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 <sys/param.h>
  16: #include <sys/stat.h>
  17: #include <sys/dir.h>
  18: 
  19: #define GETWDERR(s) strcpy(pathname, (s));
  20: 
  21: char *strcpy();
  22: static int pathsize;            /* pathname length */
  23: 
  24: char *
  25: getwd(pathname)
  26:     char *pathname;
  27: {
  28:     char pathbuf[MAXPATHLEN];       /* temporary pathname buffer */
  29:     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  30:     char curdir[MAXPATHLEN];    /* current directory buffer */
  31:     char *dptr = curdir;        /* directory pointer */
  32:     char *prepend();        /* prepend dirname to pathname */
  33:     dev_t cdev, rdev;       /* current & root device number */
  34:     ino_t cino, rino;       /* current & root inode number */
  35:     DIR *dirp;          /* directory stream */
  36:     struct direct *dir;     /* directory entry struct */
  37:     struct stat d, dd;      /* file status struct */
  38: 
  39:     pathsize = 0;
  40:     *pnptr = '\0';
  41:     if (stat("/", &d) < 0) {
  42:         GETWDERR("getwd: can't stat /");
  43:         return (NULL);
  44:     }
  45:     rdev = d.st_dev;
  46:     rino = d.st_ino;
  47:     strcpy(dptr, "./");
  48:     dptr += 2;
  49:     if (stat(curdir, &d) < 0) {
  50:         GETWDERR("getwd: can't stat .");
  51:         return (NULL);
  52:     }
  53:     for (;;) {
  54:         if (d.st_ino == rino && d.st_dev == rdev)
  55:             break;      /* reached root directory */
  56:         cino = d.st_ino;
  57:         cdev = d.st_dev;
  58:         strcpy(dptr, "../");
  59:         dptr += 3;
  60:         if ((dirp = opendir(curdir)) == NULL) {
  61:             GETWDERR("getwd: can't open ..");
  62:             return (NULL);
  63:         }
  64:         fstat(dirp->dd_fd, &d);
  65:         if (cdev == d.st_dev) {
  66:             if (cino == d.st_ino) {
  67:                 /* reached root directory */
  68:                 closedir(dirp);
  69:                 break;
  70:             }
  71:             do {
  72:                 if ((dir = readdir(dirp)) == NULL) {
  73:                     closedir(dirp);
  74:                     GETWDERR("getwd: read error in ..");
  75:                     return (NULL);
  76:                 }
  77:             } while (dir->d_ino != cino);
  78:         } else
  79:             do {
  80:                 if ((dir = readdir(dirp)) == NULL) {
  81:                     closedir(dirp);
  82:                     GETWDERR("getwd: read error in ..");
  83:                     return (NULL);
  84:                 }
  85:                 strcpy(dptr, dir->d_name);
  86:                 lstat(curdir, &dd);
  87:             } while(dd.st_ino != cino || dd.st_dev != cdev);
  88:         closedir(dirp);
  89:         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  90:     }
  91:     if (*pnptr == '\0')     /* current dir == root dir */
  92:         strcpy(pathname, "/");
  93:     else
  94:         strcpy(pathname, pnptr);
  95:     return (pathname);
  96: }
  97: 
  98: /*
  99:  * prepend() tacks a directory name onto the front of a pathname.
 100:  */
 101: static char *
 102: prepend(dirname, pathname)
 103:     register char *dirname;
 104:     register char *pathname;
 105: {
 106:     register int i;         /* directory name size counter */
 107: 
 108:     for (i = 0; *dirname != '\0'; i++, dirname++)
 109:         continue;
 110:     if ((pathsize += i) < MAXPATHLEN)
 111:         while (i-- > 0)
 112:             *--pathname = *--dirname;
 113:     return (pathname);
 114: }

Defined functions

prepend defined in line 101; used 3 times

Defined variables

pathsize defined in line 22; used 2 times
sccsid defined in line 8; never used

Defined macros

GETWDERR defined in line 19; used 5 times
Last modified: 1986-03-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1143
Valid CSS Valid XHTML 1.0 Strict