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