1 /* @(#)getcwd.c 4.4 (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(np, 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 29 off = -1; 30 *np++ = '/'; 31 name = np; 32 stat("/", &d); 33 rdev = d.st_dev; 34 rino = d.st_ino; 35 for (;;) { 36 stat(dot, &d); 37 if (d.st_ino==rino && d.st_dev==rdev) 38 goto done; 39 if ((file = opendir(dotdot)) == NULL) 40 prexit("getwd: cannot open .."); 41 fstat(file->dd_fd, &dd); 42 if (chdir(dotdot) < 0) 43 prexit("getwd: cannot chdir to .."); 44 if (d.st_dev == dd.st_dev) { 45 if(d.st_ino == dd.st_ino) 46 goto done; 47 do 48 if ((dir = readdir(file)) == NULL) 49 prexit("getwd: read error in .."); 50 while (dir->d_ino != d.st_ino); 51 } else 52 do { 53 if ((dir = readdir(file)) == NULL) 54 prexit("getwd: read error in .."); 55 stat(dir->d_name, &dd); 56 } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); 57 closedir(file); 58 cat(); 59 } 60 done: 61 name--; 62 if (chdir(name) < 0) 63 prexit("getwd: can't change back"); 64 return (name); 65 } 66 67 cat() 68 { 69 register i, j; 70 71 i = -1; 72 while (dir->d_name[++i] != 0); 73 if ((off+i+2) > 1024-1) 74 return; 75 for(j=off+1; j>=0; --j) 76 name[j+i+1] = name[j]; 77 if (off >= 0) 78 name[i] = '/'; 79 off=i+off+1; 80 name[off] = 0; 81 for(--i; i>=0; --i) 82 name[i] = dir->d_name[i]; 83 } 84