Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6-0]: src/lib/libc/gen Pull up following revision(s) (requested b...



details:   https://anonhg.NetBSD.org/src/rev/90c410c53802
branches:  netbsd-6-0
changeset: 774793:90c410c53802
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Apr 20 10:11:43 2013 +0000

description:
Pull up following revision(s) (requested by christos in ticket #874):
        lib/libc/gen/realpath.3: revision 1.13
        lib/libc/gen/getcwd.c: revision 1.52
PR/46618: Onno van der Linden: realpath(3) isn't SUSv4 compliant (and causes
flactag 2.0.4 to dump core). Fix to accept a NULL argument for resolvedpath.

diffstat:

 lib/libc/gen/getcwd.c   |  63 ++++++++++++++++++++++++++++---------------------
 lib/libc/gen/realpath.3 |  30 ++++++++++++++++++++---
 2 files changed, 62 insertions(+), 31 deletions(-)

diffs (266 lines):

diff -r 51faed5f14a9 -r 90c410c53802 lib/libc/gen/getcwd.c
--- a/lib/libc/gen/getcwd.c     Sat Apr 20 10:05:44 2013 +0000
+++ b/lib/libc/gen/getcwd.c     Sat Apr 20 10:11:43 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: getcwd.c,v 1.50 2011/02/21 00:40:07 joerg Exp $        */
+/*     $NetBSD: getcwd.c,v 1.50.10.1 2013/04/20 10:11:43 bouyer Exp $  */
 
 /*
  * Copyright (c) 1989, 1991, 1993, 1995
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)getcwd.c   8.5 (Berkeley) 2/7/95";
 #else
-__RCSID("$NetBSD: getcwd.c,v 1.50 2011/02/21 00:40:07 joerg Exp $");
+__RCSID("$NetBSD: getcwd.c,v 1.50.10.1 2013/04/20 10:11:43 bouyer Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -61,29 +61,35 @@
 #endif
 
 /*
- * char *realpath(const char *path, char resolved[MAXPATHLEN]);
+ * char *realpath(const char *path, char *resolved);
  *
  * Find the real name of path, by removing all ".", ".." and symlink
  * components.  Returns (resolved) on success, or (NULL) on failure,
  * in which case the path which caused trouble is left in (resolved).
  */
 char *
-realpath(const char *path, char *resolved)
+realpath(const char * __restrict path, char * __restrict resolved)
 {
        struct stat sb;
        int idx = 0, n, nlnk = 0;
        const char *q;
-       char *p, wbuf[2][MAXPATHLEN];
+       char *p, wbuf[2][MAXPATHLEN], *fres;
        size_t len;
 
-       _DIAGASSERT(resolved != NULL);
-
        /* POSIX sez we must test for this */
        if (path == NULL) {
                errno = EINVAL;
                return NULL;
        }
 
+       if (resolved == NULL) {
+               fres = resolved = malloc(MAXPATHLEN);
+               if (resolved == NULL)
+                       return NULL;
+       } else
+               fres = NULL;
+
+
        /*
         * Build real path one by one with paying an attention to .,
         * .. and symbolic link.
@@ -95,10 +101,10 @@
         */
        p = resolved;
 
-       if (*path == 0) {
-               *p = 0;
+       if (*path == '\0') {
+               *p = '\0';
                errno = ENOENT;
-               return (NULL);
+               goto out;
        }
 
        /* If relative path, start from current working directory. */
@@ -106,8 +112,8 @@
                /* check for resolved pointer to appease coverity */
                if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) {
                        p[0] = '.';
-                       p[1] = 0;
-                       return (NULL);
+                       p[1] = '\0';
+                       goto out;
                }
                len = strlen(resolved);
                if (len > 1)
@@ -119,18 +125,18 @@
        while (*path == '/')
                path++;
 
-       if (*path == 0) {
+       if (*path == '\0') {
                if (p == resolved)
                        *p++ = '/';
-               *p = 0;
-               return (resolved);
+               *p = '\0';
+               return resolved;
        }
 
        /* Find the end of this component. */
        q = path;
        do
                q++;
-       while (*q != '/' && *q != 0);
+       while (*q != '/' && *q != '\0');
 
        /* Test . or .. */
        if (path[0] == '.') {
@@ -142,7 +148,7 @@
                        /* Trim the last component. */
                        if (p != resolved)
                                while (*--p != '/')
-                                       ;
+                                       continue;
                        path = q;
                        goto loop;
                }
@@ -153,39 +159,39 @@
                errno = ENAMETOOLONG;
                if (p == resolved)
                        *p++ = '/';
-               *p = 0;
-               return (NULL);
+               *p = '\0';
+               goto out;
        }
        p[0] = '/';
        memcpy(&p[1], path,
            /* LINTED We know q > path. */
            q - path);
-       p[1 + q - path] = 0;
+       p[1 + q - path] = '\0';
 
        /*
         * If this component is a symlink, toss it and prepend link
         * target to unresolved path.
         */
-       if (lstat(resolved, &sb) == -1) {
-               return (NULL);
-       }
+       if (lstat(resolved, &sb) == -1)
+               goto out;
+
        if (S_ISLNK(sb.st_mode)) {
                if (nlnk++ >= MAXSYMLINKS) {
                        errno = ELOOP;
-                       return (NULL);
+                       goto out;
                }
                n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1);
                if (n < 0)
                        return (NULL);
                if (n == 0) {
                        errno = ENOENT;
-                       return (NULL);
+                       goto out;
                }
 
                /* Append unresolved path to link target and switch to it. */
                if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) {
                        errno = ENAMETOOLONG;
-                       return (NULL);
+                       goto out;
                }
                memcpy(&wbuf[idx][n], q, len + 1);
                path = wbuf[idx];
@@ -198,13 +204,16 @@
        }
        if (*q == '/' && !S_ISDIR(sb.st_mode)) {
                errno = ENOTDIR;
-               return (NULL);
+               goto out;
        }
 
        /* Advance both resolved and unresolved path. */
        p += 1 + q - path;
        path = q;
        goto loop;
+out:
+       free(fres);
+       return NULL;
 }
 
 char *
diff -r 51faed5f14a9 -r 90c410c53802 lib/libc/gen/realpath.3
--- a/lib/libc/gen/realpath.3   Sat Apr 20 10:05:44 2013 +0000
+++ b/lib/libc/gen/realpath.3   Sat Apr 20 10:11:43 2013 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: realpath.3,v 1.12 2005/08/13 19:53:53 elad Exp $
+.\"    $NetBSD: realpath.3,v 1.12.50.1 2013/04/20 10:11:43 bouyer Exp $
 .\"
 .\" Copyright (c) 1994
 .\"    The Regents of the University of California.  All rights reserved.
@@ -32,7 +32,7 @@
 .\"
 .\"     from: @(#)realpath.3   8.2 (Berkeley) 2/16/94
 .\"
-.Dd August 13, 2005
+.Dd June 21, 2012
 .Dt REALPATH 3
 .Os
 .Sh NAME
@@ -44,7 +44,7 @@
 .In sys/param.h
 .In stdlib.h
 .Ft "char *"
-.Fn realpath "const char *pathname" "char resolvedname[MAXPATHLEN]"
+.Fn realpath "const char * restrict pathname" "char * restrict resolvedname"
 .Sh DESCRIPTION
 The
 .Fn realpath
@@ -73,6 +73,12 @@
 and return the absolute pathname corresponding to
 .Fa pathname .
 .Sh RETURN VALUES
+If
+.Fa resolvednamed
+is
+.Dv NULL ,
+it will be allocated and the returned pointer can be deallocated using
+.Xr free 3 .
 The
 .Fn realpath
 function returns
@@ -84,7 +90,9 @@
 .Dv NULL ,
 and
 .Fa resolvedname
-contains the pathname which caused the problem.
+was not allocated by
+.Xr realpath ,
+it will contain the pathname which caused the problem.
 .Sh ERRORS
 The function
 .Fn realpath
@@ -95,17 +103,31 @@
 .Xr close 2 ,
 .Xr fchdir 2 ,
 .Xr lstat 2 ,
+.Xr malloc 3 ,
 .Xr open 2 ,
 .Xr readlink 2
 and
 .Xr getcwd 3 .
 .Sh SEE ALSO
 .Xr getcwd 3
+.Sh STANDARDS
+.Fn realpath
+first appeared in
+.St -xpg4.2 
+and is part of
+.St -p1003.1-2001 .
 .Sh HISTORY
 The
 .Fn realpath
 function call first appeared in
 .Bx 4.4 .
+In
+.Nx 7.0
+the function was updated to accept a
+.Dv NULL
+pointer for the
+.Fa resolvedname
+argument.
 .Sh BUGS
 This implementation of
 .Fn realpath



Home | Main Index | Thread Index | Old Index