The following reply was made to PR kern/121897; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: kern/121897: commit references a PR
Date: Tue, 20 Apr 2010 10:16:58 +0000 (UTC)

 Author: kib
 Date: Tue Apr 20 10:16:44 2010
 New Revision: 206893
 URL: http://svn.freebsd.org/changeset/base/206893
 
 Log:
   Slightly modernize realpath(3).
   
   SUSv4 requires that implementation returns EINVAL if supplied path is NULL,
   and ENOENT if path is empty string [1].
   Bring prototype in conformance with SUSv4, adding restrict keywords.
   Allow the resolved path buffer pointer be NULL, in which case realpath(3)
   allocates storage with malloc().
   
   PR:  kern/121897 [1]
   MFC after:   2 weeks
 
 Modified:
   head/include/stdlib.h
   head/lib/libc/stdlib/realpath.3
   head/lib/libc/stdlib/realpath.c
 
 Modified: head/include/stdlib.h
 ==============================================================================
 --- head/include/stdlib.h      Tue Apr 20 08:51:21 2010        (r206892)
 +++ head/include/stdlib.h      Tue Apr 20 10:16:44 2010        (r206893)
 @@ -201,7 +201,7 @@ int         posix_openpt(int);
  char  *ptsname(int);
  int    putenv(char *);
  long   random(void);
 -char  *realpath(const char *, char resolved_path[]);
 +char  *realpath(const char * __restrict, char * __restrict);
  unsigned short
        *seed48(unsigned short[3]);
  #ifndef _SETKEY_DECLARED
 
 Modified: head/lib/libc/stdlib/realpath.3
 ==============================================================================
 --- head/lib/libc/stdlib/realpath.3    Tue Apr 20 08:51:21 2010        
(r206892)
 +++ head/lib/libc/stdlib/realpath.3    Tue Apr 20 10:16:44 2010        
(r206893)
 @@ -31,7 +31,7 @@
  .\"     @(#)realpath.3        8.2 (Berkeley) 2/16/94
  .\" $FreeBSD$
  .\"
 -.Dd February 16, 1994
 +.Dd April 19, 2010
  .Dt REALPATH 3
  .Os
  .Sh NAME
 @@ -43,7 +43,7 @@
  .In sys/param.h
  .In stdlib.h
  .Ft "char *"
 -.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]"
 +.Fn realpath "const char *pathname" "char *resolved_path"
  .Sh DESCRIPTION
  The
  .Fn realpath
 @@ -64,7 +64,8 @@ argument
  .Em must
  refer to a buffer capable of storing at least
  .Dv PATH_MAX
 -characters.
 +characters, or be
 +.Dv NULL .
  .Pp
  The
  .Fn realpath
 @@ -82,6 +83,13 @@ The
  function returns
  .Fa resolved_path
  on success.
 +If the function was supplied
 +.Dv NULL
 +as
 +.Fa resolved_path ,
 +and operation did not cause errors, the returned value is
 +a null-terminated string in a buffer allocated by a call to
 +.Fn malloc 3 .
  If an error occurs,
  .Fn realpath
  returns
 @@ -89,6 +97,11 @@ returns
  and
  .Fa resolved_path
  contains the pathname which caused the problem.
 +If
 +.Fa resolved_path
 +was
 +.Dv NULL ,
 +then information of the failed pathname component is lost.
  .Sh ERRORS
  The function
  .Fn realpath
 
 Modified: head/lib/libc/stdlib/realpath.c
 ==============================================================================
 --- head/lib/libc/stdlib/realpath.c    Tue Apr 20 08:51:21 2010        
(r206892)
 +++ head/lib/libc/stdlib/realpath.c    Tue Apr 20 10:16:44 2010        
(r206893)
 @@ -43,23 +43,37 @@ __FBSDID("$FreeBSD$");
  #include "un-namespace.h"
  
  /*
 - * char *realpath(const char *path, char resolved[PATH_MAX]);
 - *
   * 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[PATH_MAX])
 +realpath(const char * __restrict path, char * __restrict resolved)
  {
        struct stat sb;
        char *p, *q, *s;
        size_t left_len, resolved_len;
        unsigned symlinks;
 -      int serrno, slen;
 +      int serrno, slen, m;
        char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
  
 +      if (path == NULL) {
 +              errno = EINVAL;
 +              return (NULL);
 +      }
 +      if (path[0] == '\0') {
 +              errno = ENOENT;
 +              return (NULL);
 +      }
        serrno = errno;
 +      if (resolved == NULL) {
 +              resolved = malloc(PATH_MAX);
 +              if (resolved == NULL)
 +                      return (NULL);
 +              m = 1;
 +      } else
 +              m = 0;
 +
        symlinks = 0;
        if (path[0] == '/') {
                resolved[0] = '/';
 @@ -71,12 +85,19 @@ realpath(const char *path, char resolved
        } else {
                if (getcwd(resolved, PATH_MAX) == NULL) {
                        strlcpy(resolved, ".", PATH_MAX);
 +                      if (m) {
 +                              serrno = errno;
 +                              free(resolved);
 +                              errno = serrno;
 +                      }
                        return (NULL);
                }
                resolved_len = strlen(resolved);
                left_len = strlcpy(left, path, sizeof(left));
        }
        if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
 +              if (m)
 +                      free(resolved);
                errno = ENAMETOOLONG;
                return (NULL);
        }
 @@ -92,6 +113,8 @@ realpath(const char *path, char resolved
                p = strchr(left, '/');
                s = p ? p : left + left_len;
                if (s - left >= sizeof(next_token)) {
 +                      if (m)
 +                              free(resolved);
                        errno = ENAMETOOLONG;
                        return (NULL);
                }
 @@ -102,6 +125,8 @@ realpath(const char *path, char resolved
                        memmove(left, s + 1, left_len + 1);
                if (resolved[resolved_len - 1] != '/') {
                        if (resolved_len + 1 >= PATH_MAX) {
 +                              if (m)
 +                                      free(resolved);
                                errno = ENAMETOOLONG;
                                return (NULL);
                        }
 @@ -133,6 +158,8 @@ realpath(const char *path, char resolved
                 */
                resolved_len = strlcat(resolved, next_token, PATH_MAX);
                if (resolved_len >= PATH_MAX) {
 +                      if (m)
 +                              free(resolved);
                        errno = ENAMETOOLONG;
                        return (NULL);
                }
 @@ -141,16 +168,29 @@ realpath(const char *path, char resolved
                                errno = serrno;
                                return (resolved);
                        }
 +                      if (m) {
 +                              serrno = errno;
 +                              free(resolved);
 +                              errno = serrno;
 +                      }
                        return (NULL);
                }
                if (S_ISLNK(sb.st_mode)) {
                        if (symlinks++ > MAXSYMLINKS) {
 +                              if (m)
 +                                      free(resolved);
                                errno = ELOOP;
                                return (NULL);
                        }
                        slen = readlink(resolved, symlink, sizeof(symlink) - 1);
 -                      if (slen < 0)
 +                      if (slen < 0) {
 +                              if (m) {
 +                                      serrno = errno;
 +                                      free(resolved);
 +                                      errno = serrno;
 +                              }
                                return (NULL);
 +                      }
                        symlink[slen] = '\0';
                        if (symlink[0] == '/') {
                                resolved[1] = 0;
 @@ -171,6 +211,8 @@ realpath(const char *path, char resolved
                        if (p != NULL) {
                                if (symlink[slen - 1] != '/') {
                                        if (slen + 1 >= sizeof(symlink)) {
 +                                              if (m)
 +                                                      free(resolved);
                                                errno = ENAMETOOLONG;
                                                return (NULL);
                                        }
 @@ -179,6 +221,8 @@ realpath(const char *path, char resolved
                                }
                                left_len = strlcat(symlink, left, sizeof(left));
                                if (left_len >= sizeof(left)) {
 +                                      if (m)
 +                                              free(resolved);
                                        errno = ENAMETOOLONG;
                                        return (NULL);
                                }
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to