|
|
1.1 ! root 1: /* @(#)getwd.c 4.8 (Berkeley) 3/2/83 */ ! 2: ! 3: /* ! 4: * getwd() returns the pathname of the current working directory. On error ! 5: * an error message is copied to pathname and null pointer is returned. ! 6: */ ! 7: #include <sys/param.h> ! 8: #include <sys/stat.h> ! 9: #include <sys/dir.h> ! 10: ! 11: #define CURDIR "." ! 12: #define GETWDERR(s) strcpy(pathname, (s)); ! 13: #define PARENTDIR ".." ! 14: #define PATHSEP "/" ! 15: #define ROOTDIR "/" ! 16: ! 17: char *strcpy(); ! 18: static int pathsize; /* pathname length */ ! 19: ! 20: char * ! 21: getwd(pathname) ! 22: char *pathname; ! 23: { ! 24: char pathbuf[MAXPATHLEN]; /* temporary pathname buffer */ ! 25: char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */ ! 26: char *prepend(); /* prepend dirname to pathname */ ! 27: dev_t rdev; /* root device number */ ! 28: DIR *dirp; /* directory stream */ ! 29: ino_t rino; /* root inode number */ ! 30: struct direct *dir; /* directory entry struct */ ! 31: struct stat d ,dd; /* file status struct */ ! 32: ! 33: pathsize = 0; ! 34: *pnptr = '\0'; ! 35: stat(ROOTDIR, &d); ! 36: rdev = d.st_dev; ! 37: rino = d.st_ino; ! 38: for (;;) { ! 39: stat(CURDIR, &d); ! 40: if (d.st_ino == rino && d.st_dev == rdev) ! 41: break; /* reached root directory */ ! 42: if ((dirp = opendir(PARENTDIR)) == NULL) { ! 43: GETWDERR("getwd: can't open .."); ! 44: goto fail; ! 45: } ! 46: if (chdir(PARENTDIR) < 0) { ! 47: GETWDERR("getwd: can't chdir to .."); ! 48: goto fail; ! 49: } ! 50: fstat(dirp->dd_fd, &dd); ! 51: if (d.st_dev == dd.st_dev) { ! 52: if (d.st_ino == dd.st_ino) { ! 53: /* reached root directory */ ! 54: closedir(dirp); ! 55: break; ! 56: } ! 57: do { ! 58: if ((dir = readdir(dirp)) == NULL) { ! 59: closedir(dirp); ! 60: GETWDERR("getwd: read error in .."); ! 61: goto fail; ! 62: } ! 63: } while (dir->d_ino != d.st_ino); ! 64: } else ! 65: do { ! 66: if((dir = readdir(dirp)) == NULL) { ! 67: closedir(dirp); ! 68: GETWDERR("getwd: read error in .."); ! 69: goto fail; ! 70: } ! 71: stat(dir->d_name, &dd); ! 72: } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); ! 73: closedir(dirp); ! 74: pnptr = prepend(PATHSEP, prepend(dir->d_name, pnptr)); ! 75: } ! 76: if (*pnptr == '\0') /* current dir == root dir */ ! 77: strcpy(pathname, ROOTDIR); ! 78: else { ! 79: strcpy(pathname, pnptr); ! 80: if (chdir(pnptr) < 0) { ! 81: GETWDERR("getwd: can't change back to ."); ! 82: return (NULL); ! 83: } ! 84: } ! 85: return (pathname); ! 86: ! 87: fail: ! 88: chdir(prepend(CURDIR, pnptr)); ! 89: return (NULL); ! 90: } ! 91: ! 92: /* ! 93: * prepend() tacks a directory name onto the front of a pathname. ! 94: */ ! 95: static char * ! 96: prepend(dirname, pathname) ! 97: register char *dirname; ! 98: register char *pathname; ! 99: { ! 100: register int i; /* directory name size counter */ ! 101: ! 102: for (i = 0; *dirname != '\0'; i++, dirname++) ! 103: continue; ! 104: if ((pathsize += i) < MAXPATHLEN) ! 105: while (i-- > 0) ! 106: *--pathname = *--dirname; ! 107: return (pathname); ! 108: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.