|
|
1.1 root 1: /*
2: * Return a static string containing the current
3: * working directory for this process.
4: * (Warning: this call may change the current directory
5: * of the process if for any reason it fails.)
6: */
7:
8: #include <stdio.h>
9: #include <sys/types.h>
10: #include <sys/stat.h>
11: #include <sys/dir.h>
12: #include <canon.h>
13:
14: #define MAXNAME 400 /* Longest pathname */
15:
16: extern int errno;
17: static int oerrno;
18:
19: static
20: char *
21: fail()
22: {
23: if (errno == 0)
24: errno = oerrno; /* preserve previous errno */
25: return NULL;
26: }
27:
28: char *
29: getwd()
30: {
31: struct stat d, dd;
32: struct direct dir;
33: static char fnbuf[MAXNAME];
34: register char *cp, *dp;
35: register int file;
36: register dev_t rdev;
37: register ino_t rino;
38:
39: oerrno = errno; /* save old errno */
40: errno = 0;
41: dp = fnbuf+MAXNAME-1;
42: *dp = '\0';
43: if (stat("/", &d) < 0)
44: return fail();
45: rdev = d.st_dev;
46: rino = d.st_ino;
47: while (stat(".", &d)>=0 && (d.st_ino!=rino || d.st_dev!=rdev)) {
48: if ((file = open("..", 0)) < 0)
49: return fail();
50: if (fstat(file, &dd)<0 || chdir("..")<0) {
51: close(file);
52: return fail();
53: }
54: if (d.st_dev == dd.st_dev) {
55: if (d.st_ino == dd.st_ino) {
56: close(file);
57: break;
58: }
59: do {
60: if (read(file, (char *)&dir, sizeof (dir))
61: != sizeof (dir)) {
62: close(file);
63: return fail();
64: }
65: canino(dir.d_ino);
66: } while (dir.d_ino != d.st_ino);
67: } else
68: do {
69: if (read(file, (char *)&dir, sizeof (dir))
70: != sizeof (dir)) {
71: close(file);
72: return fail();
73: }
74: canino(dir.d_ino);
75: if (dir.d_ino!=0 && stat(dir.d_name, &dd)<0) {
76: close(file);
77: return fail();
78: }
79: } while (dd.st_ino!=d.st_ino || dd.st_dev!=d.st_dev);
80: close(file);
81: if (dp-DIRSIZ <= fnbuf)
82: return fail();
83: for (cp=dir.d_name; cp!=dir.d_name+DIRSIZ && *cp!='\0'; cp++)
84: ;
85: while (cp > dir.d_name)
86: *--dp = *--cp;
87: *--dp = '/';
88: }
89: if (errno)
90: return NULL;
91: if (*dp != '/')
92: *--dp = '/';
93: if (chdir(dp) < 0)
94: return fail();
95: errno = oerrno;
96: return dp;
97: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.