xref: /csrg-svn/lib/libc/gen/getcwd.c (revision 10088)
1*10088Ssam /*	@(#)getcwd.c	4.2	(Berkeley)	01/02/83	*/
29986Ssam 
39986Ssam /*
49986Ssam  * Getwd
59986Ssam  */
6*10088Ssam #include <sys/param.h>
7*10088Ssam #include <sys/stat.h>
8*10088Ssam #include <sys/dir.h>
99986Ssam 
109986Ssam #define	dot	"."
119986Ssam #define	dotdot	".."
129986Ssam 
13*10088Ssam static	char *name;
149986Ssam 
15*10088Ssam static	DIR *file;
16*10088Ssam static	int off;
17*10088Ssam static	struct stat d, dd;
18*10088Ssam static	struct direct *dir;
199986Ssam 
209986Ssam char *
219986Ssam getwd(np)
22*10088Ssam 	char *np;
239986Ssam {
24*10088Ssam 	dev_t rdev;
25*10088Ssam 	ino_t rino;
269986Ssam 
27*10088Ssam 	off = -1;
289986Ssam 	*np++ = '/';
299986Ssam 	name = np;
309986Ssam 	stat("/", &d);
319986Ssam 	rdev = d.st_dev;
329986Ssam 	rino = d.st_ino;
339986Ssam 	for (;;) {
349986Ssam 		stat(dot, &d);
359986Ssam 		if (d.st_ino==rino && d.st_dev==rdev)
369986Ssam 			goto done;
379986Ssam 		if ((file = opendir(dotdot)) == NULL)
389986Ssam 			prexit("getwd: cannot open ..\n");
399986Ssam 		fstat(file->dd_fd, &dd);
409986Ssam 		chdir(dotdot);
419986Ssam 		if(d.st_dev == dd.st_dev) {
429986Ssam 			if(d.st_ino == dd.st_ino)
439986Ssam 				goto done;
449986Ssam 			do
459986Ssam 				if ((dir = readdir(file)) == NULL)
469986Ssam 					prexit("getwd: read error in ..\n");
479986Ssam 			while (dir->d_ino != d.st_ino);
489986Ssam 		}
499986Ssam 		else do {
509986Ssam 				if ((dir = readdir(file)) == NULL)
519986Ssam 					prexit("getwd: read error in ..\n");
529986Ssam 				stat(dir->d_name, &dd);
539986Ssam 			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
549986Ssam 		closedir(file);
559986Ssam 		cat();
569986Ssam 	}
579986Ssam done:
589986Ssam 	name--;
599986Ssam 	if (chdir(name) < 0)
609986Ssam 		prexit("getwd: can't change back\n");
619986Ssam 	return (name);
629986Ssam }
639986Ssam 
649986Ssam cat()
659986Ssam {
669986Ssam 	register i, j;
679986Ssam 
689986Ssam 	i = -1;
699986Ssam 	while (dir->d_name[++i] != 0);
709986Ssam 	if ((off+i+2) > 1024-1)
719986Ssam 		return;
729986Ssam 	for(j=off+1; j>=0; --j)
739986Ssam 		name[j+i+1] = name[j];
749986Ssam 	if (off >= 0)
759986Ssam 		name[i] = '/';
769986Ssam 	off=i+off+1;
779986Ssam 	name[off] = 0;
789986Ssam 	for(--i; i>=0; --i)
799986Ssam 		name[i] = dir->d_name[i];
809986Ssam }
819986Ssam 
829986Ssam prexit(cp)
839986Ssam char *cp;
849986Ssam {
859986Ssam 	write(2, cp, strlen(cp));
869986Ssam 	exit(1);
879986Ssam }
88