[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.8 and 1.20

version 1.8, 1998/02/02 02:41:23 version 1.20, 1999/07/11 18:01:46
Line 57  __RCSID("$NetBSD$");
Line 57  __RCSID("$NetBSD$");
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
   #include "extern.h"
   
 #ifdef __weak_alias  #ifdef __weak_alias
 __weak_alias(getcwd,_getcwd);  __weak_alias(getcwd,_getcwd);
   __weak_alias(realpath,_realpath);
 #endif  #endif
   
 static char *getcwd_physical __P((char *, size_t));  
   
 #define ISDOT(dp) \  #define ISDOT(dp) \
         (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \          (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
             (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))              (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
   
 char *  
 getcwd(pt, size)  
         char *pt;  
         size_t size;  
 {  
         char *pwd;  
         size_t pwdlen;  
         dev_t dev;  
         ino_t ino;  
         struct stat s;  
   
         /* Check $PWD -- if it's right, it's fast. */  #if defined(__SVR4) || defined(__svr4__)
         if ((pwd = getenv("PWD")) != NULL && pwd[0] == '/' && !stat(pwd, &s)) {  #define d_fileno d_ino
                 dev = s.st_dev;  #endif
                 ino = s.st_ino;  
                 if (!stat(".", &s) && dev == s.st_dev && ino == s.st_ino) {  
                         pwdlen = strlen(pwd);  
                         if (size != 0) {  
                                 if (pwdlen + 1 > size) {  
                                         errno = ERANGE;  
                                         return (NULL);  
                                 }  
                         } else if ((pt = malloc(pwdlen + 1)) == NULL)  
                                 return (NULL);  
                         memmove(pt, pwd, pwdlen);  
                         pt[pwdlen] = '\0';  
                         return (pt);  
                 }  
         }  
   
         return (getcwd_physical(pt, size));  
 }  
   
 /*  /*
  * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);   * char *realpath(const char *path, char resolved_path[MAXPATHLEN]);
Line 170  loop:
Line 143  loop:
          * Save the last component name and get the full pathname of           * Save the last component name and get the full pathname of
          * the current directory.           * the current directory.
          */           */
         (void)strcpy(wbuf, p);          (void)strncpy(wbuf, p, (sizeof(wbuf) - 1));
   
         /*          /*
          * Call the inernal internal version of getcwd which           * Call the inernal internal version of getcwd which
          * does a physical search rather than using the $PWD short-cut           * does a physical search rather than using the $PWD short-cut
          */           */
         if (getcwd_physical(resolved, MAXPATHLEN) == 0)          if (getcwd(resolved, MAXPATHLEN) == 0)
                 goto err1;                  goto err1;
   
         /*          /*
Line 194  loop:
Line 167  loop:
                         goto err1;                          goto err1;
                 }                  }
                 if (rootd == 0)                  if (rootd == 0)
                         (void)strcat(resolved, "/");                          (void)strcat(resolved, "/"); /* XXX: strcat is safe */
                 (void)strcat(resolved, wbuf);                  (void)strcat(resolved, wbuf);   /* XXX: strcat is safe */
         }          }
   
         /* Go back to where we came from. */          /* Go back to where we came from. */
Line 215  err2: (void)close(fd);
Line 188  err2: (void)close(fd);
         return (NULL);          return (NULL);
 }  }
   
 static char *  #ifdef OLD_GETCWD
 getcwd_physical(pt, size)  
   char *
   getcwd(pt, size)
         char *pt;          char *pt;
         size_t size;          size_t size;
 {  {
         register struct dirent *dp;          struct dirent *dp;
         register DIR *dir;          DIR *dir;
         register dev_t dev;          dev_t dev;
         register ino_t ino;          ino_t ino;
         register int first;          int first;
         register char *bpt, *bup;          char *bpt, *bup;
         struct stat s;          struct stat s;
         dev_t root_dev;          dev_t root_dev;
         ino_t root_ino;          ino_t root_ino;
         size_t ptsize, upsize;          size_t ptsize, upsize;
         int save_errno;          int save_errno;
         char *ept, *eup, *up;          char *ept, *eup, *up;
           size_t dlen;
   
         /*          /*
          * If no buffer specified by the user, allocate one as necessary.           * If no buffer specified by the user, allocate one as necessary.
Line 290  getcwd_physical(pt, size)
Line 266  getcwd_physical(pt, size)
                          * path to the beginning of the buffer, but it's always                           * path to the beginning of the buffer, but it's always
                          * been that way and stuff would probably break.                           * been that way and stuff would probably break.
                          */                           */
                         bcopy(bpt, pt, ept - bpt);                          memmove(pt, bpt,  (size_t)(ept - bpt));
                         free(up);                          free(up);
                         return (pt);                          return (pt);
                 }                  }
Line 327  getcwd_physical(pt, size)
Line 303  getcwd_physical(pt, size)
                         for (;;) {                          for (;;) {
                                 if (!(dp = readdir(dir)))                                  if (!(dp = readdir(dir)))
                                         goto notfound;                                          goto notfound;
                                 if (dp->d_fileno == ino)                                  if (dp->d_fileno == ino) {
   #if defined(__SVR4) || defined(__svr4__) || defined(__linux__)
                                           dlen = strlen(dp->d_name);
   #else
                                           dlen = dp->d_namlen;
   #endif
                                         break;                                          break;
                                   }
                         }                          }
                 } else                  } else
                         for (;;) {                          for (;;) {
Line 336  getcwd_physical(pt, size)
Line 318  getcwd_physical(pt, size)
                                         goto notfound;                                          goto notfound;
                                 if (ISDOT(dp))                                  if (ISDOT(dp))
                                         continue;                                          continue;
                                 bcopy(dp->d_name, bup, dp->d_namlen + 1);  #if defined(__SVR4) || defined(__svr4__) || defined(__linux__)
                                   dlen = strlen(dp->d_name);
   #else
                                   dlen = dp->d_namlen;
   #endif
                                   memmove(bup, dp->d_name, dlen + 1);
   
                                 /* Save the first error for later. */                                  /* Save the first error for later. */
                                 if (lstat(up, &s)) {                                  if (lstat(up, &s)) {
Line 353  getcwd_physical(pt, size)
Line 340  getcwd_physical(pt, size)
                  * Check for length of the current name, preceding slash,                   * Check for length of the current name, preceding slash,
                  * leading slash.                   * leading slash.
                  */                   */
                 if (bpt - pt <= dp->d_namlen + (first ? 1 : 2)) {                  if (bpt - pt <= dlen + (first ? 1 : 2)) {
                         size_t len, off;                          size_t len, off;
   
                         if (!ptsize) {                          if (!ptsize) {
Line 366  getcwd_physical(pt, size)
Line 353  getcwd_physical(pt, size)
                                 goto err;                                  goto err;
                         bpt = pt + off;                          bpt = pt + off;
                         ept = pt + ptsize;                          ept = pt + ptsize;
                         bcopy(bpt, ept - len, len);                          memmove(ept - len, bpt, len);
                         bpt = ept - len;                          bpt = ept - len;
                 }                  }
                 if (!first)                  if (!first)
                         *--bpt = '/';                          *--bpt = '/';
                 bpt -= dp->d_namlen;                  bpt -= dlen;
                 bcopy(dp->d_name, bpt, dp->d_namlen);                  memmove(bpt, dp->d_name, dlen);
                 (void)closedir(dir);                  (void)closedir(dir);
   
                 /* Truncate any file name. */                  /* Truncate any file name. */
Line 394  err:
Line 381  err:
         free(up);          free(up);
         return (NULL);          return (NULL);
 }  }
   
   #else /* New getcwd */
   
   char *
   getcwd(pt, size)
           char *pt;
           size_t size;
   {
           size_t ptsize, bufsize;
           int len;
   
           /*
            * If no buffer specified by the user, allocate one as necessary.
            * If a buffer is specified, the size has to be non-zero.  The path
            * is built from the end of the buffer backwards.
            */
           if (pt) {
                   ptsize = 0;
                   if (!size) {
                           errno = EINVAL;
                           return (NULL);
                   }
                   bufsize = size;
           } else {
                   if ((pt = malloc(ptsize = 1024 - 4)) == NULL)
                           return (NULL);
                   bufsize = ptsize;
           }
           for (;;) {
                   len = __getcwd(pt, bufsize);
                   if ((len < 0) && (size == 0) && (errno == ERANGE)) {
                           if (ptsize > (MAXPATHLEN*4))
                                   return NULL;
                           if ((pt = realloc(pt, ptsize *= 2)) == NULL)
                                   return NULL;
                           bufsize = ptsize;
                           continue;
                   }
                   break;
           }
           if (len < 0)
                   return NULL;
           else
                   return pt;
   }
   
   #endif

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.20

CVSweb <webmaster@jp.NetBSD.org>