[BACK]Return to getcwd.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/gen/getcwd.c between version 1.50.4.2 and 1.51

version 1.50.4.2, 2012/10/30 18:58:46 version 1.51, 2012/03/13 21:13:35
Line 61  __weak_alias(realpath,_realpath)
Line 61  __weak_alias(realpath,_realpath)
 #endif  #endif
   
 /*  /*
  * char *realpath(const char *path, char *resolved);   * char *realpath(const char *path, char resolved[MAXPATHLEN]);
  *   *
  * Find the real name of path, by removing all ".", ".." and symlink   * Find the real name of path, by removing all ".", ".." and symlink
  * components.  Returns (resolved) on success, or (NULL) on failure,   * components.  Returns (resolved) on success, or (NULL) on failure,
  * in which case the path which caused trouble is left in (resolved).   * in which case the path which caused trouble is left in (resolved).
  */   */
 char *  char *
 realpath(const char * __restrict path, char * __restrict resolved)  realpath(const char *path, char *resolved)
 {  {
         struct stat sb;          struct stat sb;
         int idx = 0, nlnk = 0;          int idx = 0, nlnk = 0;
         const char *q;          const char *q;
         char *p, wbuf[2][MAXPATHLEN], *fres;          char *p, wbuf[2][MAXPATHLEN];
         size_t len;          size_t len;
         ssize_t n;          ssize_t n;
   
           _DIAGASSERT(resolved != NULL);
   
         /* POSIX sez we must test for this */          /* POSIX sez we must test for this */
         if (path == NULL) {          if (path == NULL) {
                 errno = EINVAL;                  errno = EINVAL;
                 return NULL;                  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 .,           * Build real path one by one with paying an attention to .,
          * .. and symbolic link.           * .. and symbolic link.
Line 102  realpath(const char * __restrict path, c
Line 96  realpath(const char * __restrict path, c
          */           */
         p = resolved;          p = resolved;
   
         if (*path == '\0') {          if (*path == 0) {
                 *p = '\0';                  *p = 0;
                 errno = ENOENT;                  errno = ENOENT;
                 goto out;                  return (NULL);
         }          }
   
         /* If relative path, start from current working directory. */          /* If relative path, start from current working directory. */
Line 113  realpath(const char * __restrict path, c
Line 107  realpath(const char * __restrict path, c
                 /* check for resolved pointer to appease coverity */                  /* check for resolved pointer to appease coverity */
                 if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) {                  if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) {
                         p[0] = '.';                          p[0] = '.';
                         p[1] = '\0';                          p[1] = 0;
                         goto out;                          return (NULL);
                 }                  }
                 len = strlen(resolved);                  len = strlen(resolved);
                 if (len > 1)                  if (len > 1)
Line 126  loop:
Line 120  loop:
         while (*path == '/')          while (*path == '/')
                 path++;                  path++;
   
         if (*path == '\0') {          if (*path == 0) {
                 if (p == resolved)                  if (p == resolved)
                         *p++ = '/';                          *p++ = '/';
                 *p = '\0';                  *p = 0;
                 return resolved;                  return (resolved);
         }          }
   
         /* Find the end of this component. */          /* Find the end of this component. */
         q = path;          q = path;
         do          do
                 q++;                  q++;
         while (*q != '/' && *q != '\0');          while (*q != '/' && *q != 0);
   
         /* Test . or .. */          /* Test . or .. */
         if (path[0] == '.') {          if (path[0] == '.') {
Line 149  loop:
Line 143  loop:
                         /* Trim the last component. */                          /* Trim the last component. */
                         if (p != resolved)                          if (p != resolved)
                                 while (*--p != '/')                                  while (*--p != '/')
                                         continue;                                          ;
                         path = q;                          path = q;
                         goto loop;                          goto loop;
                 }                  }
Line 160  loop:
Line 154  loop:
                 errno = ENAMETOOLONG;                  errno = ENAMETOOLONG;
                 if (p == resolved)                  if (p == resolved)
                         *p++ = '/';                          *p++ = '/';
                 *p = '\0';                  *p = 0;
                 goto out;                  return (NULL);
         }          }
         p[0] = '/';          p[0] = '/';
         memcpy(&p[1], path,          memcpy(&p[1], path,
             /* LINTED We know q > path. */              /* LINTED We know q > path. */
             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           * If this component is a symlink, toss it and prepend link
          * target to unresolved path.           * target to unresolved path.
          */           */
         if (lstat(resolved, &sb) == -1)          if (lstat(resolved, &sb) == -1) {
                 goto out;                  return (NULL);
           }
         if (S_ISLNK(sb.st_mode)) {          if (S_ISLNK(sb.st_mode)) {
                 if (nlnk++ >= MAXSYMLINKS) {                  if (nlnk++ >= MAXSYMLINKS) {
                         errno = ELOOP;                          errno = ELOOP;
                         goto out;                          return (NULL);
                 }                  }
                 n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1);                  n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1);
                 if (n < 0)                  if (n < 0)
                         goto out;                          return (NULL);
                 if (n == 0) {                  if (n == 0) {
                         errno = ENOENT;                          errno = ENOENT;
                         goto out;                          return (NULL);
                 }                  }
   
                 /* Append unresolved path to link target and switch to it. */                  /* Append unresolved path to link target and switch to it. */
                 if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) {                  if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) {
                         errno = ENAMETOOLONG;                          errno = ENAMETOOLONG;
                         goto out;                          return (NULL);
                 }                  }
                 memcpy(&wbuf[idx][n], q, len + 1);                  memcpy(&wbuf[idx][n], q, len + 1);
                 path = wbuf[idx];                  path = wbuf[idx];
Line 205  loop:
Line 199  loop:
         }          }
         if (*q == '/' && !S_ISDIR(sb.st_mode)) {          if (*q == '/' && !S_ISDIR(sb.st_mode)) {
                 errno = ENOTDIR;                  errno = ENOTDIR;
                 goto out;                  return (NULL);
         }          }
   
         /* Advance both resolved and unresolved path. */          /* Advance both resolved and unresolved path. */
         p += 1 + q - path;          p += 1 + q - path;
         path = q;          path = q;
         goto loop;          goto loop;
 out:  
         free(fres);  
         return NULL;  
 }  }
   
 char *  char *

Legend:
Removed from v.1.50.4.2  
changed lines
  Added in v.1.51

CVSweb <webmaster@jp.NetBSD.org>