/* @(#)getcwd.c 4.8 (Berkeley) %G% */
* getwd() returns the pathname of the current working directory. On error
* an error message is copied to pathname and null pointer is returned.
#define GETWDERR(s) strcpy(pathname, (s));
static int pathsize
; /* pathname length */
char pathbuf
[MAXPATHLEN
]; /* temporary pathname buffer */
char *pnptr
= &pathbuf
[(sizeof pathbuf
)-1]; /* pathname pointer */
char *prepend(); /* prepend dirname to pathname */
dev_t rdev
; /* root device number */
DIR *dirp
; /* directory stream */
ino_t rino
; /* root inode number */
struct direct
*dir
; /* directory entry struct */
struct stat d
,dd
; /* file status struct */
if (d
.st_ino
== rino
&& d
.st_dev
== rdev
)
break; /* reached root directory */
if ((dirp
= opendir(PARENTDIR
)) == NULL
) {
GETWDERR("getwd: can't open ..");
if (chdir(PARENTDIR
) < 0) {
GETWDERR("getwd: can't chdir to ..");
if (d
.st_dev
== dd
.st_dev
) {
if (d
.st_ino
== dd
.st_ino
) {
/* reached root directory */
if ((dir
= readdir(dirp
)) == NULL
) {
GETWDERR("getwd: read error in ..");
} while (dir
->d_ino
!= d
.st_ino
);
if((dir
= readdir(dirp
)) == NULL
) {
GETWDERR("getwd: read error in ..");
} while(dd
.st_ino
!= d
.st_ino
|| dd
.st_dev
!= d
.st_dev
);
pnptr
= prepend(PATHSEP
, prepend(dir
->d_name
, pnptr
));
if (*pnptr
== '\0') /* current dir == root dir */
strcpy(pathname
, ROOTDIR
);
GETWDERR("getwd: can't change back to .");
chdir(prepend(CURDIR
, pnptr
));
* prepend() tacks a directory name onto the front of a pathname.
prepend(dirname
, pathname
)
register int i
; /* directory name size counter */
for (i
= 0; *dirname
!= '\0'; i
++, dirname
++)
if ((pathsize
+= i
) < MAXPATHLEN
)
*--pathname
= *--dirname
;