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