xref: /freebsd/contrib/bmake/dirname.c (revision ef0b253881c9546ff88d3ed8480df7c791b3ddff)
1*dfd669abSSimon J. Gerraty /*	$NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $	*/
23955d011SMarcel Moolenaar 
33955d011SMarcel Moolenaar /*-
43955d011SMarcel Moolenaar  * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
53955d011SMarcel Moolenaar  * All rights reserved.
63955d011SMarcel Moolenaar  *
73955d011SMarcel Moolenaar  * This code is derived from software contributed to The NetBSD Foundation
83955d011SMarcel Moolenaar  * by Klaus Klein and Jason R. Thorpe.
93955d011SMarcel Moolenaar  *
103955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
113955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
123955d011SMarcel Moolenaar  * are met:
133955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
143955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
153955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
163955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
173955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
183955d011SMarcel Moolenaar  *
193955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
203955d011SMarcel Moolenaar  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
213955d011SMarcel Moolenaar  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223955d011SMarcel Moolenaar  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
233955d011SMarcel Moolenaar  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
243955d011SMarcel Moolenaar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
253955d011SMarcel Moolenaar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
263955d011SMarcel Moolenaar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
273955d011SMarcel Moolenaar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
283955d011SMarcel Moolenaar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
293955d011SMarcel Moolenaar  * POSSIBILITY OF SUCH DAMAGE.
303955d011SMarcel Moolenaar  */
313955d011SMarcel Moolenaar 
323955d011SMarcel Moolenaar #ifdef HAVE_CONFIG_H
333955d011SMarcel Moolenaar # include <config.h>
343955d011SMarcel Moolenaar #endif
353955d011SMarcel Moolenaar #ifndef HAVE_DIRNAME
363955d011SMarcel Moolenaar 
373955d011SMarcel Moolenaar #include <sys/cdefs.h>
38*dfd669abSSimon J. Gerraty #if defined(LIBC_SCCS) && !defined(lint)
39*dfd669abSSimon J. Gerraty __RCSID("$NetBSD: dirname.c,v 1.14 2018/09/27 00:45:34 kre Exp $");
40*dfd669abSSimon J. Gerraty #endif /* !LIBC_SCCS && !lint */
41*dfd669abSSimon J. Gerraty 
42be19d90bSSimon J. Gerraty #include <sys/param.h>
43be19d90bSSimon J. Gerraty #ifdef HAVE_LIBGEN_H
44be19d90bSSimon J. Gerraty #include <libgen.h>
45be19d90bSSimon J. Gerraty #endif
463955d011SMarcel Moolenaar #ifdef HAVE_LIMITS_H
473955d011SMarcel Moolenaar #include <limits.h>
483955d011SMarcel Moolenaar #endif
493955d011SMarcel Moolenaar #ifdef HAVE_STRING_H
503955d011SMarcel Moolenaar #include <string.h>
513955d011SMarcel Moolenaar #endif
523955d011SMarcel Moolenaar #ifndef PATH_MAX
533955d011SMarcel Moolenaar # define PATH_MAX 1024
543955d011SMarcel Moolenaar #endif
55be19d90bSSimon J. Gerraty #ifndef MIN
56be19d90bSSimon J. Gerraty # define MIN(a, b) ((a < b) ? a : b)
57be19d90bSSimon J. Gerraty #endif
583955d011SMarcel Moolenaar 
59be19d90bSSimon J. Gerraty 
60be19d90bSSimon J. Gerraty static size_t
xdirname_r(const char * path,char * buf,size_t buflen)61be19d90bSSimon J. Gerraty xdirname_r(const char *path, char *buf, size_t buflen)
623955d011SMarcel Moolenaar {
63be19d90bSSimon J. Gerraty 	const char *endp;
643955d011SMarcel Moolenaar 	size_t len;
653955d011SMarcel Moolenaar 
663955d011SMarcel Moolenaar 	/*
673955d011SMarcel Moolenaar 	 * If `path' is a null pointer or points to an empty string,
683955d011SMarcel Moolenaar 	 * return a pointer to the string ".".
693955d011SMarcel Moolenaar 	 */
70be19d90bSSimon J. Gerraty 	if (path == NULL || *path == '\0') {
71be19d90bSSimon J. Gerraty 		path = ".";
72be19d90bSSimon J. Gerraty 		len = 1;
73be19d90bSSimon J. Gerraty 		goto out;
74be19d90bSSimon J. Gerraty 	}
753955d011SMarcel Moolenaar 
763955d011SMarcel Moolenaar 	/* Strip trailing slashes, if any. */
77be19d90bSSimon J. Gerraty 	endp = path + strlen(path) - 1;
78be19d90bSSimon J. Gerraty 	while (endp != path && *endp == '/')
79be19d90bSSimon J. Gerraty 		endp--;
803955d011SMarcel Moolenaar 
81be19d90bSSimon J. Gerraty 	/* Find the start of the dir */
82be19d90bSSimon J. Gerraty 	while (endp > path && *endp != '/')
83be19d90bSSimon J. Gerraty 		endp--;
843955d011SMarcel Moolenaar 
85be19d90bSSimon J. Gerraty 	if (endp == path) {
86be19d90bSSimon J. Gerraty 		path = *endp == '/' ? "/" : ".";
87be19d90bSSimon J. Gerraty 		len = 1;
88be19d90bSSimon J. Gerraty 		goto out;
893955d011SMarcel Moolenaar 	}
903955d011SMarcel Moolenaar 
91be19d90bSSimon J. Gerraty 	do
92be19d90bSSimon J. Gerraty 		endp--;
93be19d90bSSimon J. Gerraty 	while (endp > path && *endp == '/');
943955d011SMarcel Moolenaar 
95be19d90bSSimon J. Gerraty 	len = endp - path + 1;
96be19d90bSSimon J. Gerraty out:
97be19d90bSSimon J. Gerraty 	if (buf != NULL && buflen != 0) {
98be19d90bSSimon J. Gerraty 		buflen = MIN(len, buflen - 1);
99*dfd669abSSimon J. Gerraty 		if (buf != path)
100be19d90bSSimon J. Gerraty 			memcpy(buf, path, buflen);
101be19d90bSSimon J. Gerraty 		buf[buflen] = '\0';
1023955d011SMarcel Moolenaar 	}
103be19d90bSSimon J. Gerraty 	return len;
104be19d90bSSimon J. Gerraty }
105be19d90bSSimon J. Gerraty 
106be19d90bSSimon J. Gerraty char *
dirname(char * path)107be19d90bSSimon J. Gerraty dirname(char *path)
108be19d90bSSimon J. Gerraty {
109be19d90bSSimon J. Gerraty 	static char result[PATH_MAX];
110be19d90bSSimon J. Gerraty 	(void)xdirname_r(path, result, sizeof(result));
111be19d90bSSimon J. Gerraty 	return result;
112be19d90bSSimon J. Gerraty }
113be19d90bSSimon J. Gerraty 
114be19d90bSSimon J. Gerraty #ifdef MAIN
115be19d90bSSimon J. Gerraty #include <stdlib.h>
116be19d90bSSimon J. Gerraty #include <stdio.h>
117be19d90bSSimon J. Gerraty 
118be19d90bSSimon J. Gerraty int
main(int argc,char * argv[])119be19d90bSSimon J. Gerraty main(int argc, char *argv[])
120be19d90bSSimon J. Gerraty {
121be19d90bSSimon J. Gerraty 	printf("%s\n", dirname(argv[1]));
122be19d90bSSimon J. Gerraty 	exit(0);
123be19d90bSSimon J. Gerraty }
124be19d90bSSimon J. Gerraty #endif
1253955d011SMarcel Moolenaar #endif
126