1 /* @(#)getcwd.c 4.5 (Berkeley) 01/04/83 */ 2 3 /* 4 * Getwd 5 */ 6 #include <sys/param.h> 7 #include <sys/stat.h> 8 #include <sys/dir.h> 9 10 #define dot "." 11 #define dotdot ".." 12 13 #define prexit(s) { strcpy(esave, (s)); return (NULL); } 14 15 static char *name; 16 17 static DIR *file; 18 static int off; 19 static struct stat d, dd; 20 static struct direct *dir; 21 22 char * 23 getwd(np) 24 char *np; 25 { 26 dev_t rdev; 27 ino_t rino; 28 char *esave = np; 29 30 off = -1; 31 *np++ = '/'; 32 name = np; 33 stat("/", &d); 34 rdev = d.st_dev; 35 rino = d.st_ino; 36 for (;;) { 37 stat(dot, &d); 38 if (d.st_ino==rino && d.st_dev==rdev) 39 goto done; 40 if ((file = opendir(dotdot)) == NULL) 41 prexit("getwd: cannot open .."); 42 fstat(file->dd_fd, &dd); 43 if (chdir(dotdot) < 0) 44 prexit("getwd: cannot chdir to .."); 45 if (d.st_dev == dd.st_dev) { 46 if(d.st_ino == dd.st_ino) 47 goto done; 48 do { 49 if ((dir = readdir(file)) == NULL) 50 prexit("getwd: read error in .."); 51 } while (dir->d_ino != d.st_ino); 52 } else 53 do { 54 if ((dir = readdir(file)) == NULL) 55 prexit("getwd: read error in .."); 56 stat(dir->d_name, &dd); 57 } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); 58 closedir(file); 59 cat(); 60 } 61 done: 62 name--; 63 if (chdir(name) < 0) 64 prexit("getwd: can't change back"); 65 return (name); 66 } 67 68 cat() 69 { 70 register i, j; 71 72 i = -1; 73 while (dir->d_name[++i] != 0); 74 if ((off+i+2) > 1024-1) 75 return; 76 for(j=off+1; j>=0; --j) 77 name[j+i+1] = name[j]; 78 if (off >= 0) 79 name[i] = '/'; 80 off=i+off+1; 81 name[off] = 0; 82 for(--i; i>=0; --i) 83 name[i] = dir->d_name[i]; 84 } 85