home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdmalloc / getwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  3.0 KB  |  119 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #if defined(LIBC_SCCS) && !defined(lint)
  8. static char sccsid[] = "@(#)getwd.c    5.2 (Berkeley) 3/9/86";
  9. #endif /* LIBC_SCCS and not lint */
  10.  
  11. /*
  12.  * getwd() returns the pathname of the current working directory. On error
  13.  * an error message is copied to pathname and null pointer is returned.
  14.  */
  15. #include <limits.h>
  16. #include <sys/types.h>
  17. #include <dirent.h>
  18. #include <sys/param.h>
  19. #include <sys/stat.h>
  20.  
  21. #define GETWDERR(s)    strcpy(pathname, (s));
  22.  
  23. char *strcpy(char *, char *);
  24. static int pathsize;            /* pathname length */
  25.  
  26. static char *prepend(char *, char *);
  27.  
  28. char *
  29. getwd(pathname)
  30.     char *pathname;
  31. {
  32.     char pathbuf[PATH_MAX];        /* temporary pathname buffer */
  33.     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  34.     char curdir[PATH_MAX];    /* current directory buffer */
  35.     char *dptr = curdir;        /* directory pointer */
  36.     dev_t cdev, rdev;        /* current & root device number */
  37.     ino_t cino, rino;        /* current & root inode number */
  38.     DIR *dirp;            /* directory stream */
  39.     struct dirent *dir;        /* directory entry struct */
  40.     struct stat d, dd;        /* file status struct */
  41.  
  42.     pathsize = 0;
  43.     *pnptr = '\0';
  44.     if (stat("/", &d) < 0) {
  45.         GETWDERR("getwd: can't stat /");
  46.         return (NULL);
  47.     }
  48.     rdev = d.st_dev;
  49.     rino = d.st_ino;
  50.     strcpy(dptr, "./");
  51.     dptr += 2;
  52.     if (stat(curdir, &d) < 0) {
  53.         GETWDERR("getwd: can't stat .");
  54.         return (NULL);
  55.     }
  56.     for (;;) {
  57.         if (d.st_ino == rino && d.st_dev == rdev)
  58.             break;        /* reached root directory */
  59.         cino = d.st_ino;
  60.         cdev = d.st_dev;
  61.         strcpy(dptr, "../");
  62.         dptr += 3;
  63.         if ((dirp = opendir(curdir)) == NULL) {
  64.             GETWDERR("getwd: can't open ..");
  65.             return (NULL);
  66.         }
  67.         fstat(dirp->dd_fd, &d);
  68.         if (cdev == d.st_dev) {
  69.             if (cino == d.st_ino) {
  70.                 /* reached root directory */
  71.                 closedir(dirp);
  72.                 break;
  73.             }
  74.             do {
  75.                 if ((dir = readdir(dirp)) == NULL) {
  76.                     closedir(dirp);
  77.                     GETWDERR("getwd: read error in ..");
  78.                     return (NULL);
  79.                 }
  80.             } while (dir->d_ino != cino);
  81.         } else
  82.             do {
  83.                 if ((dir = readdir(dirp)) == NULL) {
  84.                     closedir(dirp);
  85.                     GETWDERR("getwd: read error in ..");
  86.                     return (NULL);
  87.                 }
  88.                 strcpy(dptr, dir->d_name);
  89.                 lstat(curdir, &dd);
  90.             } while(dd.st_ino != cino || dd.st_dev != cdev);
  91.         /* BUG FIX: the following two lines were interchanged */
  92.         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  93.         closedir(dirp);
  94.     }
  95.     if (*pnptr == '\0')        /* current dir == root dir */
  96.         strcpy(pathname, "/");
  97.     else
  98.         strcpy(pathname, pnptr);
  99.     return (pathname);
  100. }
  101.  
  102. /*
  103.  * prepend() tacks a directory name onto the front of a pathname.
  104.  */
  105. static char *
  106. prepend(dirname, pathname)
  107.     register char *dirname;
  108.     register char *pathname;
  109. {
  110.     register int i;            /* directory name size counter */
  111.  
  112.     for (i = 0; *dirname != '\0'; i++, dirname++)
  113.         continue;
  114.     if ((pathsize += i) < PATH_MAX)
  115.         while (i-- > 0)
  116.             *--pathname = *--dirname;
  117.     return (pathname);
  118. }
  119.