xref: /csrg-svn/lib/libc/gen/getcwd.c (revision 10140)
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