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