|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.