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