121345Sdist /* 221345Sdist * Copyright (c) 1980 Regents of the University of California. 321345Sdist * All rights reserved. The Berkeley software License Agreement 421345Sdist * specifies the terms and conditions for redistribution. 521345Sdist */ 69986Ssam 7*26565Sdonn #if defined(LIBC_SCCS) && !defined(lint) 8*26565Sdonn static char sccsid[] = "@(#)getcwd.c 5.2 (Berkeley) 03/09/86"; 9*26565Sdonn #endif LIBC_SCCS and not lint 1021345Sdist 119986Ssam /* 1210155Ssam * getwd() returns the pathname of the current working directory. On error 1310155Ssam * an error message is copied to pathname and null pointer is returned. 149986Ssam */ 1510088Ssam #include <sys/param.h> 1610088Ssam #include <sys/stat.h> 1710088Ssam #include <sys/dir.h> 189986Ssam 1910155Ssam #define GETWDERR(s) strcpy(pathname, (s)); 209986Ssam 2111370Snicklin char *strcpy(); 2210155Ssam static int pathsize; /* pathname length */ 2310127Ssam 249986Ssam char * 2510155Ssam getwd(pathname) 2610155Ssam char *pathname; 279986Ssam { 2810156Ssam char pathbuf[MAXPATHLEN]; /* temporary pathname buffer */ 2910155Ssam char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */ 3017867Sralph char curdir[MAXPATHLEN]; /* current directory buffer */ 3117867Sralph char *dptr = curdir; /* directory pointer */ 3210155Ssam char *prepend(); /* prepend dirname to pathname */ 3317867Sralph dev_t cdev, rdev; /* current & root device number */ 3417867Sralph ino_t cino, rino; /* current & root inode number */ 3510155Ssam DIR *dirp; /* directory stream */ 3610155Ssam struct direct *dir; /* directory entry struct */ 3717867Sralph struct stat d, dd; /* file status struct */ 389986Ssam 3910155Ssam pathsize = 0; 4010155Ssam *pnptr = '\0'; 4117867Sralph if (stat("/", &d) < 0) { 4217867Sralph GETWDERR("getwd: can't stat /"); 4317867Sralph return (NULL); 4417867Sralph } 459986Ssam rdev = d.st_dev; 469986Ssam rino = d.st_ino; 4717867Sralph strcpy(dptr, "./"); 4817867Sralph dptr += 2; 4917867Sralph if (stat(curdir, &d) < 0) { 5017867Sralph GETWDERR("getwd: can't stat ."); 5117867Sralph return (NULL); 5217867Sralph } 539986Ssam for (;;) { 5410155Ssam if (d.st_ino == rino && d.st_dev == rdev) 5510155Ssam break; /* reached root directory */ 5617867Sralph cino = d.st_ino; 5717867Sralph cdev = d.st_dev; 5817867Sralph strcpy(dptr, "../"); 5917867Sralph dptr += 3; 6017867Sralph if ((dirp = opendir(curdir)) == NULL) { 6110155Ssam GETWDERR("getwd: can't open .."); 6217867Sralph return (NULL); 6310155Ssam } 6417867Sralph fstat(dirp->dd_fd, &d); 6517867Sralph if (cdev == d.st_dev) { 6617867Sralph if (cino == d.st_ino) { 6710155Ssam /* reached root directory */ 6810155Ssam closedir(dirp); 6910155Ssam break; 7010155Ssam } 7110140Ssam do { 7210155Ssam if ((dir = readdir(dirp)) == NULL) { 7310155Ssam closedir(dirp); 7410155Ssam GETWDERR("getwd: read error in .."); 7517867Sralph return (NULL); 7610155Ssam } 7717867Sralph } while (dir->d_ino != cino); 7810126Ssam } else 7910126Ssam do { 8017867Sralph if ((dir = readdir(dirp)) == NULL) { 8110155Ssam closedir(dirp); 8210155Ssam GETWDERR("getwd: read error in .."); 8317867Sralph return (NULL); 8410155Ssam } 8517867Sralph strcpy(dptr, dir->d_name); 8617867Sralph lstat(curdir, &dd); 8717867Sralph } while(dd.st_ino != cino || dd.st_dev != cdev); 8810155Ssam closedir(dirp); 8917867Sralph pnptr = prepend("/", prepend(dir->d_name, pnptr)); 909986Ssam } 9110155Ssam if (*pnptr == '\0') /* current dir == root dir */ 9217867Sralph strcpy(pathname, "/"); 9317867Sralph else 9410155Ssam strcpy(pathname, pnptr); 9510155Ssam return (pathname); 969986Ssam } 979986Ssam 9810155Ssam /* 9910155Ssam * prepend() tacks a directory name onto the front of a pathname. 10010155Ssam */ 10110155Ssam static char * 10210155Ssam prepend(dirname, pathname) 10310155Ssam register char *dirname; 10410155Ssam register char *pathname; 1059986Ssam { 10610155Ssam register int i; /* directory name size counter */ 1079986Ssam 10810155Ssam for (i = 0; *dirname != '\0'; i++, dirname++) 10910155Ssam continue; 11010156Ssam if ((pathsize += i) < MAXPATHLEN) 11110155Ssam while (i-- > 0) 11210155Ssam *--pathname = *--dirname; 11310155Ssam return (pathname); 1149986Ssam } 115