xref: /csrg-svn/lib/libc/gen/getcwd.c (revision 10140)
1*10140Ssam /*	@(#)getcwd.c	4.5	(Berkeley)	01/04/83	*/
29986Ssam 
39986Ssam /*
49986Ssam  * Getwd
59986Ssam  */
610088Ssam #include <sys/param.h>
710088Ssam #include <sys/stat.h>
810088Ssam #include <sys/dir.h>
99986Ssam 
109986Ssam #define	dot	"."
119986Ssam #define	dotdot	".."
129986Ssam 
13*10140Ssam #define	prexit(s)	 { strcpy(esave, (s)); return (NULL); }
1410127Ssam 
1510088Ssam static	char *name;
169986Ssam 
1710088Ssam static	DIR *file;
1810088Ssam static	int off;
1910088Ssam static	struct stat d, dd;
2010088Ssam static	struct direct *dir;
219986Ssam 
229986Ssam char *
239986Ssam getwd(np)
2410088Ssam 	char *np;
259986Ssam {
2610088Ssam 	dev_t rdev;
2710088Ssam 	ino_t rino;
28*10140Ssam 	char *esave = np;
299986Ssam 
3010088Ssam 	off = -1;
319986Ssam 	*np++ = '/';
329986Ssam 	name = np;
339986Ssam 	stat("/", &d);
349986Ssam 	rdev = d.st_dev;
359986Ssam 	rino = d.st_ino;
369986Ssam 	for (;;) {
379986Ssam 		stat(dot, &d);
389986Ssam 		if (d.st_ino==rino && d.st_dev==rdev)
399986Ssam 			goto done;
409986Ssam 		if ((file = opendir(dotdot)) == NULL)
4110127Ssam 			prexit("getwd: cannot open ..");
429986Ssam 		fstat(file->dd_fd, &dd);
4310126Ssam 		if (chdir(dotdot) < 0)
4410127Ssam 			prexit("getwd: cannot chdir to ..");
4510126Ssam 		if (d.st_dev == dd.st_dev) {
469986Ssam 			if(d.st_ino == dd.st_ino)
479986Ssam 				goto done;
48*10140Ssam 			do {
499986Ssam 				if ((dir = readdir(file)) == NULL)
5010127Ssam 					prexit("getwd: read error in ..");
51*10140Ssam 			} while (dir->d_ino != d.st_ino);
5210126Ssam 		} else
5310126Ssam 			do {
549986Ssam 				if ((dir = readdir(file)) == NULL)
5510127Ssam 					prexit("getwd: read error in ..");
569986Ssam 				stat(dir->d_name, &dd);
579986Ssam 			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
589986Ssam 		closedir(file);
599986Ssam 		cat();
609986Ssam 	}
619986Ssam done:
629986Ssam 	name--;
639986Ssam 	if (chdir(name) < 0)
6410127Ssam 		prexit("getwd: can't change back");
659986Ssam 	return (name);
669986Ssam }
679986Ssam 
689986Ssam cat()
699986Ssam {
709986Ssam 	register i, j;
719986Ssam 
729986Ssam 	i = -1;
739986Ssam 	while (dir->d_name[++i] != 0);
749986Ssam 	if ((off+i+2) > 1024-1)
759986Ssam 		return;
769986Ssam 	for(j=off+1; j>=0; --j)
779986Ssam 		name[j+i+1] = name[j];
789986Ssam 	if (off >= 0)
799986Ssam 		name[i] = '/';
809986Ssam 	off=i+off+1;
819986Ssam 	name[off] = 0;
829986Ssam 	for(--i; i>=0; --i)
839986Ssam 		name[i] = dir->d_name[i];
849986Ssam }
85