/* @(#)getcwd.c 4.10 (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 curdir
[MAXPATHLEN
]; /* current directory buffer */
char *dptr
= curdir
; /* directory pointer */
char *prepend(); /* prepend dirname to pathname */
dev_t cdev
, rdev
; /* current & root device number */
ino_t cino
, rino
; /* current & root inode number */
DIR *dirp
; /* directory stream */
struct direct
*dir
; /* directory entry struct */
struct stat d
, dd
; /* file status struct */
GETWDERR("getwd: can't stat /");
if (stat(curdir
, &d
) < 0) {
GETWDERR("getwd: can't stat .");
if (d
.st_ino
== rino
&& d
.st_dev
== rdev
)
break; /* reached root directory */
if ((dirp
= opendir(curdir
)) == NULL
) {
GETWDERR("getwd: can't open ..");
/* reached root directory */
if ((dir
= readdir(dirp
)) == NULL
) {
GETWDERR("getwd: read error in ..");
} while (dir
->d_ino
!= cino
);
if ((dir
= readdir(dirp
)) == NULL
) {
GETWDERR("getwd: read error in ..");
strcpy(dptr
, dir
->d_name
);
} while(dd
.st_ino
!= cino
|| dd
.st_dev
!= cdev
);
pnptr
= prepend("/", prepend(dir
->d_name
, pnptr
));
if (*pnptr
== '\0') /* current dir == root dir */
* 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
;