Page MenuHomeFreeBSD

D7355.diff
No OneTemporary

D7355.diff

Index: head/lib/libc/gen/Makefile.inc
===================================================================
--- head/lib/libc/gen/Makefile.inc
+++ head/lib/libc/gen/Makefile.inc
@@ -29,6 +29,7 @@
devname.c \
dirfd.c \
dirname.c \
+ dirname_compat.c \
disklabel.c \
dlfcn.c \
drand48.c \
Index: head/lib/libc/gen/Symbol.map
===================================================================
--- head/lib/libc/gen/Symbol.map
+++ head/lib/libc/gen/Symbol.map
@@ -82,7 +82,6 @@
daemon;
devname;
devname_r;
- dirname;
getdiskbyname;
dladdr;
dlclose;
@@ -418,6 +417,10 @@
stravis;
};
+FBSD_1.5 {
+ dirname;
+};
+
FBSDprivate_1.0 {
/* needed by thread libraries */
__thr_jtable;
Index: head/lib/libc/gen/dirname.3
===================================================================
--- head/lib/libc/gen/dirname.3
+++ head/lib/libc/gen/dirname.3
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 29, 2016
+.Dd August 12, 2016
.Dt DIRNAME 3
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Sq \&/
characters are not counted as part of the directory
name.
+.Sh RETURN VALUES
If
.Fa path
is a null pointer, the empty string, or contains no
@@ -46,40 +47,24 @@
returns a pointer to the string
.Qq \&. ,
signifying the current directory.
+Otherwise,
+it returns a pointer to the parent directory of
+.Fa path .
.Sh IMPLEMENTATION NOTES
-The
+This implementation of
.Fn dirname
-function
-returns a pointer to internal storage space allocated on the first call
-that will be overwritten
-by subsequent calls.
+uses the buffer provided by the caller to store the resulting parent
+directory.
+Other vendor implementations may return a pointer to internal storage
+space instead.
+The advantage of the former approach is that it ensures thread-safety,
+while also placing no upper limit on the supported length of the
+pathname.
.Pp
-Other vendor implementations of
-.Fn dirname
-may store their result in the input buffer,
-making it safe to use in multithreaded applications.
-Future versions of
-.Fx
-will follow this approach as well.
-.Sh RETURN VALUES
-On successful completion,
-.Fn dirname
-returns a pointer to the parent directory of
-.Fa path .
-.Pp
-If
-.Fn dirname
-fails, a null pointer is returned and the global variable
-.Va errno
-is set to indicate the error.
-.Sh ERRORS
-The following error codes may be set in
-.Va errno :
-.Bl -tag -width Er
-.It Bq Er ENAMETOOLONG
-The path component to be returned was larger than
-.Dv MAXPATHLEN .
-.El
+The algorithm used by this implementation also discards redundant
+slashes and
+.Qq \&.
+pathname components from the pathname string.
.Sh SEE ALSO
.Xr basename 1 ,
.Xr dirname 1 ,
@@ -96,5 +81,10 @@
.Ox 2.2
and
.Fx 4.2 .
+.Pp
+In
+.Fx 12.0 ,
+this function was reimplemented to store its result in the provided
+input buffer.
.Sh AUTHORS
-.An "Todd C. Miller"
+.An Nuxi, the Netherlands
Index: head/lib/libc/gen/dirname.c
===================================================================
--- head/lib/libc/gen/dirname.c
+++ head/lib/libc/gen/dirname.c
@@ -1,77 +1,90 @@
-/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */
-
-/*
- * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+/*-
+ * Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
*
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <errno.h>
#include <libgen.h>
-#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
-#include <sys/param.h>
char *
dirname(char *path)
{
- static char *dname = NULL;
- size_t len;
- const char *endp;
-
- if (dname == NULL) {
- dname = (char *)malloc(MAXPATHLEN);
- if (dname == NULL)
- return(NULL);
- }
-
- /* Empty or NULL string gets treated as "." */
- if (path == NULL || *path == '\0') {
- dname[0] = '.';
- dname[1] = '\0';
- return (dname);
+ const char *in, *prev, *begin, *end;
+ char *out;
+ size_t prevlen;
+ bool skipslash;
+
+ /*
+ * If path is a null pointer or points to an empty string,
+ * dirname() shall return a pointer to the string ".".
+ */
+ if (path == NULL || *path == '\0')
+ return ((char *)".");
+
+ /* Retain at least one leading slash character. */
+ in = out = *path == '/' ? path + 1 : path;
+
+ skipslash = true;
+ prev = ".";
+ prevlen = 1;
+ for (;;) {
+ /* Extract the next pathname component. */
+ while (*in == '/')
+ ++in;
+ begin = in;
+ while (*in != '/' && *in != '\0')
+ ++in;
+ end = in;
+ if (begin == end)
+ break;
+
+ /*
+ * Copy over the previous pathname component, except if
+ * it's dot. There is no point in retaining those.
+ */
+ if (prevlen != 1 || *prev != '.') {
+ if (!skipslash)
+ *out++ = '/';
+ skipslash = false;
+ memmove(out, prev, prevlen);
+ out += prevlen;
+ }
+
+ /* Preserve the pathname component for the next iteration. */
+ prev = begin;
+ prevlen = end - begin;
}
- /* Strip any trailing slashes */
- endp = path + strlen(path) - 1;
- while (endp > path && *endp == '/')
- endp--;
-
- /* Find the start of the dir */
- while (endp > path && *endp != '/')
- endp--;
-
- /* Either the dir is "/" or there are no slashes */
- if (endp == path) {
- dname[0] = *endp == '/' ? '/' : '.';
- dname[1] = '\0';
- return (dname);
- } else {
- /* Move forward past the separating slashes */
- do {
- endp--;
- } while (endp > path && *endp == '/');
- }
-
- len = endp - path + 1;
- if (len >= MAXPATHLEN) {
- errno = ENAMETOOLONG;
- return (NULL);
- }
- memcpy(dname, path, len);
- dname[len] = '\0';
- return (dname);
+ /*
+ * If path does not contain a '/', then dirname() shall return a
+ * pointer to the string ".".
+ */
+ if (out == path)
+ *out++ = '.';
+ *out = '\0';
+ return (path);
}
Index: head/lib/libc/gen/dirname_compat.c
===================================================================
--- head/lib/libc/gen/dirname_compat.c
+++ head/lib/libc/gen/dirname_compat.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: dirname.c,v 1.13 2005/08/08 08:05:33 espie Exp $ */
+
+/*
+ * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <errno.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+char *
+__freebsd11_dirname(char *path)
+{
+ static char *dname = NULL;
+ size_t len;
+ const char *endp;
+
+ if (dname == NULL) {
+ dname = (char *)malloc(MAXPATHLEN);
+ if (dname == NULL)
+ return(NULL);
+ }
+
+ /* Empty or NULL string gets treated as "." */
+ if (path == NULL || *path == '\0') {
+ dname[0] = '.';
+ dname[1] = '\0';
+ return (dname);
+ }
+
+ /* Strip any trailing slashes */
+ endp = path + strlen(path) - 1;
+ while (endp > path && *endp == '/')
+ endp--;
+
+ /* Find the start of the dir */
+ while (endp > path && *endp != '/')
+ endp--;
+
+ /* Either the dir is "/" or there are no slashes */
+ if (endp == path) {
+ dname[0] = *endp == '/' ? '/' : '.';
+ dname[1] = '\0';
+ return (dname);
+ } else {
+ /* Move forward past the separating slashes */
+ do {
+ endp--;
+ } while (endp > path && *endp == '/');
+ }
+
+ len = endp - path + 1;
+ if (len >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ memcpy(dname, path, len);
+ dname[len] = '\0';
+ return (dname);
+}
+
+__sym_compat(dirname, __freebsd11_dirname, FBSD_1.0);

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 15, 7:53 PM (10 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29731072
Default Alt Text
D7355.diff (9 KB)

Event Timeline