xref: /freebsd/lib/libc/gen/dirname_compat.c (revision d14f60e9ba9357499d3743222ec845df2e25a008)
1e2f68161SEd Schouten /*	$OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $	*/
2e2f68161SEd Schouten 
3e2f68161SEd Schouten /*
4e2f68161SEd Schouten  * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
5e2f68161SEd Schouten  *
6e2f68161SEd Schouten  * Permission to use, copy, modify, and distribute this software for any
7e2f68161SEd Schouten  * purpose with or without fee is hereby granted, provided that the above
8e2f68161SEd Schouten  * copyright notice and this permission notice appear in all copies.
9e2f68161SEd Schouten  *
10e2f68161SEd Schouten  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11e2f68161SEd Schouten  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12e2f68161SEd Schouten  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13e2f68161SEd Schouten  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14e2f68161SEd Schouten  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15e2f68161SEd Schouten  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16e2f68161SEd Schouten  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17e2f68161SEd Schouten  */
18e2f68161SEd Schouten 
19e2f68161SEd Schouten #include <sys/cdefs.h>
20e2f68161SEd Schouten __FBSDID("$FreeBSD$");
21e2f68161SEd Schouten 
22e2f68161SEd Schouten #include <errno.h>
23e2f68161SEd Schouten #include <libgen.h>
24e2f68161SEd Schouten #include <stdlib.h>
25e2f68161SEd Schouten #include <string.h>
26e2f68161SEd Schouten #include <sys/param.h>
27e2f68161SEd Schouten 
28*d14f60e9SAlan Somers char * __freebsd11_dirname(char *path);
29*d14f60e9SAlan Somers 
30e2f68161SEd Schouten char *
31e2f68161SEd Schouten __freebsd11_dirname(char *path)
32e2f68161SEd Schouten {
33e2f68161SEd Schouten 	static char *dname = NULL;
34e2f68161SEd Schouten 	size_t len;
35e2f68161SEd Schouten 	const char *endp;
36e2f68161SEd Schouten 
37e2f68161SEd Schouten 	if (dname == NULL) {
38e2f68161SEd Schouten 		dname = (char *)malloc(MAXPATHLEN);
39e2f68161SEd Schouten 		if (dname == NULL)
40e2f68161SEd Schouten 			return(NULL);
41e2f68161SEd Schouten 	}
42e2f68161SEd Schouten 
43e2f68161SEd Schouten 	/* Empty or NULL string gets treated as "." */
44e2f68161SEd Schouten 	if (path == NULL || *path == '\0') {
45e2f68161SEd Schouten 		dname[0] = '.';
46e2f68161SEd Schouten 		dname[1] = '\0';
47e2f68161SEd Schouten 		return (dname);
48e2f68161SEd Schouten 	}
49e2f68161SEd Schouten 
50e2f68161SEd Schouten 	/* Strip any trailing slashes */
51e2f68161SEd Schouten 	endp = path + strlen(path) - 1;
52e2f68161SEd Schouten 	while (endp > path && *endp == '/')
53e2f68161SEd Schouten 		endp--;
54e2f68161SEd Schouten 
55e2f68161SEd Schouten 	/* Find the start of the dir */
56e2f68161SEd Schouten 	while (endp > path && *endp != '/')
57e2f68161SEd Schouten 		endp--;
58e2f68161SEd Schouten 
59e2f68161SEd Schouten 	/* Either the dir is "/" or there are no slashes */
60e2f68161SEd Schouten 	if (endp == path) {
61e2f68161SEd Schouten 		dname[0] = *endp == '/' ? '/' : '.';
62e2f68161SEd Schouten 		dname[1] = '\0';
63e2f68161SEd Schouten 		return (dname);
64e2f68161SEd Schouten 	} else {
65e2f68161SEd Schouten 		/* Move forward past the separating slashes */
66e2f68161SEd Schouten 		do {
67e2f68161SEd Schouten 			endp--;
68e2f68161SEd Schouten 		} while (endp > path && *endp == '/');
69e2f68161SEd Schouten 	}
70e2f68161SEd Schouten 
71e2f68161SEd Schouten 	len = endp - path + 1;
72e2f68161SEd Schouten 	if (len >= MAXPATHLEN) {
73e2f68161SEd Schouten 		errno = ENAMETOOLONG;
74e2f68161SEd Schouten 		return (NULL);
75e2f68161SEd Schouten 	}
76e2f68161SEd Schouten 	memcpy(dname, path, len);
77e2f68161SEd Schouten 	dname[len] = '\0';
78e2f68161SEd Schouten 	return (dname);
79e2f68161SEd Schouten }
80e2f68161SEd Schouten 
81e2f68161SEd Schouten __sym_compat(dirname, __freebsd11_dirname, FBSD_1.0);
82