109e1178ed/*	$OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $	*/
209e1178ed
309e1178ed/*
409e1178ed * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
509e1178ed *
609e1178ed * Permission to use, copy, modify, and distribute this software for any
709e1178ed * purpose with or without fee is hereby granted, provided that the above
809e1178ed * copyright notice and this permission notice appear in all copies.
909e1178ed *
1009e1178ed * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1109e1178ed * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1209e1178ed * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1309e1178ed * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1409e1178ed * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1509e1178ed * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1609e1178ed * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1709e1178ed */
1809e1178ed
1909e1178ed#include <sys/cdefs.h>
2009e1178ed__FBSDID("$FreeBSD$");
2109e1178ed
2209e1178ed#include <errno.h>
2309e1178ed#include <libgen.h>
2409e1178ed#include <stdlib.h>
2509e1178ed#include <string.h>
2609e1178ed#include <sys/param.h>
2709e1178ed
2809e1178edchar *
2909e1178ed__freebsd11_dirname(char *path)
3009e1178ed{
3109e1178ed	static char *dname = NULL;
3209e1178ed	size_t len;
3309e1178ed	const char *endp;
3409e1178ed
3509e1178ed	if (dname == NULL) {
3609e1178ed		dname = (char *)malloc(MAXPATHLEN);
3709e1178ed		if (dname == NULL)
3809e1178ed			return(NULL);
3909e1178ed	}
4009e1178ed
4109e1178ed	/* Empty or NULL string gets treated as "." */
4209e1178ed	if (path == NULL || *path == '\0') {
4309e1178ed		dname[0] = '.';
4409e1178ed		dname[1] = '\0';
4509e1178ed		return (dname);
4609e1178ed	}
4709e1178ed
4809e1178ed	/* Strip any trailing slashes */
4909e1178ed	endp = path + strlen(path) - 1;
5009e1178ed	while (endp > path && *endp == '/')
5109e1178ed		endp--;
5209e1178ed
5309e1178ed	/* Find the start of the dir */
5409e1178ed	while (endp > path && *endp != '/')
5509e1178ed		endp--;
5609e1178ed
5709e1178ed	/* Either the dir is "/" or there are no slashes */
5809e1178ed	if (endp == path) {
5909e1178ed		dname[0] = *endp == '/' ? '/' : '.';
6009e1178ed		dname[1] = '\0';
6109e1178ed		return (dname);
6209e1178ed	} else {
6309e1178ed		/* Move forward past the separating slashes */
6409e1178ed		do {
6509e1178ed			endp--;
6609e1178ed		} while (endp > path && *endp == '/');
6709e1178ed	}
6809e1178ed
6909e1178ed	len = endp - path + 1;
7009e1178ed	if (len >= MAXPATHLEN) {
7109e1178ed		errno = ENAMETOOLONG;
7209e1178ed		return (NULL);
7309e1178ed	}
7409e1178ed	memcpy(dname, path, len);
7509e1178ed	dname[len] = '\0';
7609e1178ed	return (dname);
7709e1178ed}
7809e1178ed
7909e1178ed__sym_compat(dirname, __freebsd11_dirname, FBSD_1.0);
80