Module Name:    src
Committed By:   christos
Date:           Mon Jul 14 20:44:45 UTC 2014

Modified Files:
        src/lib/libc/gen: basename.c dirname.c

Log Message:
Factor out the basename and dirname code into basename_r and dirname_r
which are static for now. Inspired by similar changes to android(bionic).


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/lib/libc/gen/basename.c
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/gen/dirname.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/basename.c
diff -u src/lib/libc/gen/basename.c:1.9 src/lib/libc/gen/basename.c:1.10
--- src/lib/libc/gen/basename.c:1.9	Tue Nov 24 08:34:20 2009
+++ src/lib/libc/gen/basename.c	Mon Jul 14 16:44:45 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: basename.c,v 1.9 2009/11/24 13:34:20 tnozaki Exp $	*/
+/*	$NetBSD: basename.c,v 1.10 2014/07/14 20:44:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
@@ -31,11 +31,13 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: basename.c,v 1.9 2009/11/24 13:34:20 tnozaki Exp $");
+__RCSID("$NetBSD: basename.c,v 1.10 2014/07/14 20:44:45 christos Exp $");
 #endif /* !LIBC_SCCS && !lint */
 
 #include "namespace.h"
+#include <sys/param.h>
 #include <libgen.h>
+#include <string.h>
 #include <limits.h>
 #include <string.h>
 
@@ -43,43 +45,57 @@ __RCSID("$NetBSD: basename.c,v 1.9 2009/
 __weak_alias(basename,_basename)
 #endif
 
-#if !HAVE_BASENAME
-char *
-basename(char *path)
+static size_t
+basename_r(const char *path, char *buf, size_t buflen)
 {
-	static char result[PATH_MAX];
-	const char *p, *lastp;
+	const char *startp, *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')) {
-		result[0] = '.';
-		result[1] = '\0';
-
-		return (result);
+	if (path == NULL || *path == '\0') {
+		startp = ".";
+		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--;
+
+	/* Only slashes -> "/" */
+	if (endp == path && *endp == '/') {
+		startp = "/";
+		len = 1;
+		goto out;
+	}
 
 	/* Now find the beginning of this (final) component. */
-	p = lastp;
-	while (p != path && *(p - 1) != '/')
-		p--;
+	for (startp = endp; startp > path && *(startp - 1) != '/'; startp--)
+		continue;
 
 	/* ...and copy the result into the result buffer. */
-	len = (lastp - p) + 1 /* last char */;
-	if (len > (PATH_MAX - 1))
-		len = PATH_MAX - 1;
+	len = (endp - startp) + 1 /* last char */;
+out:
+	if (buf != NULL && buflen != 0) {
+		buflen = MIN(len, buflen - 1);
+		memcpy(buf, startp, buflen);
+		buf[buflen] = '\0';
+	}
+	return len;
+}
+
+#if !HAVE_BASENAME
 
-	memcpy(result, p, len);
-	result[len] = '\0';
+char *
+basename(char *path) {
+	static char result[PATH_MAX];
 
-	return (result);
+	(void)basename_r(path, result, sizeof(result));
+	return result;
 }
+
 #endif

Index: src/lib/libc/gen/dirname.c
diff -u src/lib/libc/gen/dirname.c:1.11 src/lib/libc/gen/dirname.c:1.12
--- src/lib/libc/gen/dirname.c:1.11	Tue Nov 24 08:34:20 2009
+++ src/lib/libc/gen/dirname.c	Mon Jul 14 16:44:45 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $	*/
+/*	$NetBSD: dirname.c,v 1.12 2014/07/14 20:44:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
@@ -31,10 +31,11 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $");
+__RCSID("$NetBSD: dirname.c,v 1.12 2014/07/14 20:44:45 christos Exp $");
 #endif /* !LIBC_SCCS && !lint */
 
 #include "namespace.h"
+#include <sys/param.h>
 #include <libgen.h>
 #include <limits.h>
 #include <string.h>
@@ -43,51 +44,57 @@ __RCSID("$NetBSD: dirname.c,v 1.11 2009/
 __weak_alias(dirname,_dirname)
 #endif
 
-#if !HAVE_DIRNAME
-char *
-dirname(char *path)
+static size_t
+dirname_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--;
-
-	/* Terminate path at the last occurence of '/'. */
-	do {
-		if (*lastp == '/') {
-			/* Strip trailing slashes, if any. */
-			while (lastp != path && *lastp == '/')
-				lastp--;
-
-			/* ...and copy the result into the result buffer. */
-			len = (lastp - path) + 1 /* last char */;
-			if (len > (PATH_MAX - 1))
-				len = PATH_MAX - 1;
-
-			memcpy(result, path, len);
-			result[len] = '\0';
-
-			return (result);
-		}
-	} while (--lastp >= path);
-
-	/* No /'s found, return a pointer to the string ".". */
-singledot:
-	result[0] = '.';
-	result[1] = '\0';
+	endp = path + strlen(path) - 1;
+	while (endp != path && *endp == '/')
+		endp--;
+
+	/* Find the start of the dir */
+	while (endp > path && *endp != '/')
+		endp--;
+
+	if (endp == path) {
+		path = *endp == '/' ? "/" : ".";
+		len = 1;
+		goto out;
+	}
+
+	do
+		endp--;
+	while (endp > path && *endp == '/');
+
+	len = endp - path + 1;
+out:
+	if (buf != NULL && buflen != 0) {
+		buflen = MIN(len, buflen - 1);
+		memcpy(buf, path, buflen);
+		buf[buflen] = '\0';
+	}
+	return len;
+}
 
-	return (result);
+#if !HAVE_DIRNAME
+char *
+dirname(char *path)
+{
+	static char result[PATH_MAX];
+	(void)dirname_r(path, result, sizeof(result));
+	return result;
 }
 #endif

Reply via email to