|
|
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.