summaryrefslogtreecommitdiff
path: root/devel/bmake/files/dirname.c
diff options
context:
space:
mode:
Diffstat (limited to 'devel/bmake/files/dirname.c')
-rw-r--r--devel/bmake/files/dirname.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/devel/bmake/files/dirname.c b/devel/bmake/files/dirname.c
index 2f4ede97a26..8652328c78c 100644
--- a/devel/bmake/files/dirname.c
+++ b/devel/bmake/files/dirname.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dirname.c,v 1.1.1.1 2011/06/18 22:17:55 bsiegert Exp $ */
+/* $NetBSD: dirname.c,v 1.1.1.2 2020/05/24 05:35:52 nia Exp $ */
/*-
* Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
@@ -35,7 +35,15 @@
#ifndef HAVE_DIRNAME
#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: dirname.c,v 1.1.1.2 2020/05/24 05:35:52 nia Exp $");
+#endif /* !LIBC_SCCS && !lint */
+#include "namespace.h"
+#include <sys/param.h>
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -45,51 +53,74 @@
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
+#ifndef MIN
+# define MIN(a, b) ((a < b) ? a : b)
+#endif
-char *
-dirname(char *path)
+
+static size_t
+xdirname_r(const char *path, char *buf, size_t buflen)
{
- static char result[PATH_MAX];
- const char *lastp;
+ const char *endp;
size_t len;
/*
* If `path' is a null pointer or points to an empty string,
* return a pointer to the string ".".
*/
- if ((path == NULL) || (*path == '\0'))
- goto singledot;
-
+ if (path == NULL || *path == '\0') {
+ path = ".";
+ len = 1;
+ goto out;
+ }
/* Strip trailing slashes, if any. */
- lastp = path + strlen(path) - 1;
- while (lastp != path && *lastp == '/')
- lastp--;
+ endp = path + strlen(path) - 1;
+ while (endp != path && *endp == '/')
+ endp--;
+
+ /* Find the start of the dir */
+ while (endp > path && *endp != '/')
+ endp--;
- /* Terminate path at the last occurence of '/'. */
- do {
- if (*lastp == '/') {
- /* Strip trailing slashes, if any. */
- while (lastp != path && *lastp == '/')
- lastp--;
+ if (endp == path) {
+ path = *endp == '/' ? "/" : ".";
+ len = 1;
+ goto out;
+ }
- /* ...and copy the result into the result buffer. */
- len = (lastp - path) + 1 /* last char */;
- if (len > (PATH_MAX - 1))
- len = PATH_MAX - 1;
+ do
+ endp--;
+ while (endp > path && *endp == '/');
- memcpy(result, path, len);
- result[len] = '\0';
+ len = endp - path + 1;
+out:
+ if (buf != NULL && buflen != 0) {
+ buflen = MIN(len, buflen - 1);
+ if (buf != path)
+ memcpy(buf, path, buflen);
+ buf[buflen] = '\0';
+ }
+ return len;
+}
- return (result);
- }
- } while (--lastp >= path);
+char *
+dirname(char *path)
+{
+ static char result[PATH_MAX];
+ (void)xdirname_r(path, result, sizeof(result));
+ return result;
+}
- /* No /'s found, return a pointer to the string ".". */
-singledot:
- result[0] = '.';
- result[1] = '\0';
+#ifdef MAIN
+#include <stdlib.h>
+#include <stdio.h>
- return (result);
+int
+main(int argc, char *argv[])
+{
+ printf("%s\n", dirname(argv[1]));
+ exit(0);
}
#endif
+#endif