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