1 /* @(#)getcwd.c 4.3 (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 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 if (chdir(dotdot) < 0) 41 prexit("getwd: cannot chdir to ..\n"); 42 if (d.st_dev == dd.st_dev) { 43 if(d.st_ino == dd.st_ino) 44 goto done; 45 do 46 if ((dir = readdir(file)) == NULL) 47 prexit("getwd: read error in ..\n"); 48 while (dir->d_ino != d.st_ino); 49 } else 50 do { 51 if ((dir = readdir(file)) == NULL) 52 prexit("getwd: read error in ..\n"); 53 stat(dir->d_name, &dd); 54 } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); 55 closedir(file); 56 cat(); 57 } 58 done: 59 name--; 60 if (chdir(name) < 0) 61 prexit("getwd: can't change back\n"); 62 return (name); 63 } 64 65 cat() 66 { 67 register i, j; 68 69 i = -1; 70 while (dir->d_name[++i] != 0); 71 if ((off+i+2) > 1024-1) 72 return; 73 for(j=off+1; j>=0; --j) 74 name[j+i+1] = name[j]; 75 if (off >= 0) 76 name[i] = '/'; 77 off=i+off+1; 78 name[off] = 0; 79 for(--i; i>=0; --i) 80 name[i] = dir->d_name[i]; 81 } 82 83 prexit(cp) 84 char *cp; 85 { 86 write(2, cp, strlen(cp)); 87 exit(1); 88 } 89