1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #if defined(LIBC_SCCS) && !defined(lint)
8: static char sccsid[] = "@(#)getwd.c 5.2 (Berkeley) 3/9/86";
9: #endif LIBC_SCCS and not lint
10:
11: /*
12: * getwd() returns the pathname of the current working directory. On error
13: * an error message is copied to pathname and null pointer is returned.
14: */
15: #include <sys/param.h>
16: #include <sys/stat.h>
17: #include <sys/dir.h>
18:
19: #define GETWDERR(s) strcpy(pathname, (s));
20:
21: char *strcpy();
22: static int pathsize; /* pathname length */
23:
24: char *
25: getwd(pathname)
26: char *pathname;
27: {
28: char pathbuf[MAXPATHLEN]; /* temporary pathname buffer */
29: char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
30: char curdir[MAXPATHLEN]; /* current directory buffer */
31: char *dptr = curdir; /* directory pointer */
32: char *prepend(); /* prepend dirname to pathname */
33: dev_t cdev, rdev; /* current & root device number */
34: ino_t cino, rino; /* current & root inode number */
35: DIR *dirp; /* directory stream */
36: struct direct *dir; /* directory entry struct */
37: struct stat d, dd; /* file status struct */
38:
39: pathsize = 0;
40: *pnptr = '\0';
41: if (stat("/", &d) < 0) {
42: GETWDERR("getwd: can't stat /");
43: return (NULL);
44: }
45: rdev = d.st_dev;
46: rino = d.st_ino;
47: strcpy(dptr, "./");
48: dptr += 2;
49: if (stat(curdir, &d) < 0) {
50: GETWDERR("getwd: can't stat .");
51: return (NULL);
52: }
53: for (;;) {
54: if (d.st_ino == rino && d.st_dev == rdev)
55: break; /* reached root directory */
56: cino = d.st_ino;
57: cdev = d.st_dev;
58: strcpy(dptr, "../");
59: dptr += 3;
60: if ((dirp = opendir(curdir)) == NULL) {
61: GETWDERR("getwd: can't open ..");
62: return (NULL);
63: }
64: fstat(dirp->dd_fd, &d);
65: if (cdev == d.st_dev) {
66: if (cino == d.st_ino) {
67: /* reached root directory */
68: closedir(dirp);
69: break;
70: }
71: do {
72: if ((dir = readdir(dirp)) == NULL) {
73: closedir(dirp);
74: GETWDERR("getwd: read error in ..");
75: return (NULL);
76: }
77: } while (dir->d_ino != cino);
78: } else
79: do {
80: if ((dir = readdir(dirp)) == NULL) {
81: closedir(dirp);
82: GETWDERR("getwd: read error in ..");
83: return (NULL);
84: }
85: strcpy(dptr, dir->d_name);
86: lstat(curdir, &dd);
87: } while(dd.st_ino != cino || dd.st_dev != cdev);
88: closedir(dirp);
89: pnptr = prepend("/", prepend(dir->d_name, pnptr));
90: }
91: if (*pnptr == '\0') /* current dir == root dir */
92: strcpy(pathname, "/");
93: else
94: strcpy(pathname, pnptr);
95: return (pathname);
96: }
97:
98: /*
99: * prepend() tacks a directory name onto the front of a pathname.
100: */
101: static char *
102: prepend(dirname, pathname)
103: register char *dirname;
104: register char *pathname;
105: {
106: register int i; /* directory name size counter */
107:
108: for (i = 0; *dirname != '\0'; i++, dirname++)
109: continue;
110: if ((pathsize += i) < MAXPATHLEN)
111: while (i-- > 0)
112: *--pathname = *--dirname;
113: return (pathname);
114: }
Defined functions
getwd
defined in line
24; used 30 times
Defined variables
sccsid
defined in line
8;
never used
Defined macros