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