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