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