xref: /original-bsd/usr.bin/f77/libU77/getcwd_.c (revision 1f3a482a)
1 /** F77 NOTE: the getcwd() routine should be in libc.a ! **/
2 /*
3  * return name of working (current) directory
4  */
5 #include	<stdio.h>
6 #include	<sys/param.h>
7 #include	<sys/stat.h>
8 #include	<sys/dir.h>
9 
10 static char	slash[]	= "/";
11 static char	dot[]	= ".";
12 static char	dotdot[] = "..";
13 static char	name[128];
14 
15 char *
16 getcwd()
17 {
18 	int	rdev, rino;
19 	int	fd;
20 	struct	stat	d, dd;
21 	struct	direct	dir;
22 	char	*prepend();
23 	char	*namep = &name[(sizeof name)-1];
24 
25 	*namep = '\0';
26 	stat(slash, &d);
27 	rdev = d.st_dev;
28 	rino = d.st_ino;
29 	for (;;)
30 	{
31 		stat(dot, &d);
32 		if (d.st_ino == rino && d.st_dev == rdev)
33 		{
34 			if (*namep == '\0')	/* rootdir is a special case */
35 				namep = prepend(namep, slash);
36 			chdir(namep);
37 			return(namep);
38 		}
39 		if ((fd = open(dotdot,0)) < 0)
40 		{
41 			chdir(prepend(namep, dot));
42 			return((char *)0);
43 		}
44 		chdir(dotdot);
45 		fstat(fd, &dd);
46 		if(d.st_dev == dd.st_dev)
47 		{
48 			if(d.st_ino == dd.st_ino)
49 			{
50 				close(fd);
51 				if (*namep == '\0') /* root is a special case */
52 					namep = prepend(namep, slash);
53 				chdir(namep);
54 				return(namep);
55 			}
56 			do
57 			{
58 				if (read(fd, (char *)&dir, sizeof(dir)) < sizeof(dir))
59 				{
60 					close(fd);
61 					chdir(prepend(namep, dot));
62 					return((char *)0);
63 				}
64 			} while (dir.d_ino != d.st_ino);
65 		}
66 		else do
67 		{
68 				if(read(fd, (char *)&dir, sizeof(dir)) < sizeof(dir))
69 				{
70 					close(fd);
71 					chdir(prepend(namep, dot));
72 					return((char *)0);
73 				}
74 				stat(dir.d_name, &dd);
75 			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
76 		close(fd);
77 		namep = prepend(prepend(namep, dir.d_name), slash);
78 	}
79 }
80 
81 char *
82 prepend(p, n)
83 char *p;
84 char *n;
85 {
86 	int i = 0;
87 
88 	while (i < DIRSIZ && *n)
89 	{
90 		n++; i++;
91 	}
92 	while (i--)
93 		*--p = *--n;
94 	return(p);
95 }
96 
97 /*
98 char id_getcwd[] = "@(#)getcwd_.c	1.3";
99  * Get pathname of current working directory.
100  *
101  * calling sequence:
102  *	character*128 path
103  *	ierr = getcwd(path)
104  * where:
105  *	path will receive the pathname of the current working directory.
106  *	ierr will be 0 if successful, a system error code otherwise.
107  */
108 
109 extern int errno;
110 
111 long
112 getcwd_(path, len)
113 char *path;
114 long len;
115 {
116 	char *p;
117 
118 	p = getcwd();
119 	if (p)
120 	{
121 		b_char(p, path, len);
122 		return(0L);
123 	}
124 	return((long)errno);
125 }
126