Module Name:    src
Committed By:   bouyer
Date:           Sat Apr 20 10:11:02 UTC 2013

Modified Files:
        src/lib/libc/gen [netbsd-6]: getcwd.c realpath.3

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.50.6.1 src/lib/libc/gen/getcwd.c
cvs rdiff -u -r1.12 -r1.12.46.1 src/lib/libc/gen/realpath.3

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/getcwd.c
diff -u src/lib/libc/gen/getcwd.c:1.50 src/lib/libc/gen/getcwd.c:1.50.6.1
--- src/lib/libc/gen/getcwd.c:1.50	Mon Feb 21 00:40:07 2011
+++ src/lib/libc/gen/getcwd.c	Sat Apr 20 10:11:01 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: getcwd.c,v 1.50 2011/02/21 00:40:07 joerg Exp $	*/
+/*	$NetBSD: getcwd.c,v 1.50.6.1 2013/04/20 10:11:01 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.6.1 2013/04/20 10:11:01 bouyer Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -61,29 +61,35 @@ __weak_alias(realpath,_realpath)
 #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 @@ realpath(const char *path, char *resolve
 	 */
 	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 @@ realpath(const char *path, char *resolve
 		/* 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 @@ loop:
 	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 @@ loop:
 			/* Trim the last component. */
 			if (p != resolved)
 				while (*--p != '/')
-					;
+					continue;
 			path = q;
 			goto loop;
 		}
@@ -153,39 +159,39 @@ loop:
 		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 @@ loop:
 	}
 	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 *

Index: src/lib/libc/gen/realpath.3
diff -u src/lib/libc/gen/realpath.3:1.12 src/lib/libc/gen/realpath.3:1.12.46.1
--- src/lib/libc/gen/realpath.3:1.12	Sat Aug 13 19:53:53 2005
+++ src/lib/libc/gen/realpath.3	Sat Apr 20 10:11:01 2013
@@ -1,4 +1,4 @@
-.\"	$NetBSD: realpath.3,v 1.12 2005/08/13 19:53:53 elad Exp $
+.\"	$NetBSD: realpath.3,v 1.12.46.1 2013/04/20 10:11:01 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 @@ function will resolve both absolute and 
 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 @@ returns
 .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 @@ for any of the errors specified for the 
 .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

Reply via email to