|
|
1.1 ! root 1: /* getpwd.c - get the working directory */ ! 2: ! 3: #include "config.h" ! 4: ! 5: #include <errno.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: ! 9: #ifndef errno ! 10: extern int errno; ! 11: #endif ! 12: ! 13: /* Virtually every UN*X system now in common use (except for pre-4.3-tahoe ! 14: BSD systems) now provides getcwd as called for by POSIX. Allow for ! 15: the few exceptions to the general rule here. */ ! 16: ! 17: #if !(defined (POSIX) || defined (USG) || defined (VMS)) ! 18: #include <sys/param.h> ! 19: extern char *getwd (); ! 20: #define getcwd(buf,len) getwd(buf) ! 21: #define GUESSPATHLEN (MAXPATHLEN + 1) ! 22: #else /* (defined (USG) || defined (VMS)) */ ! 23: extern char *getcwd (); ! 24: /* We actually use this as a starting point, not a limit. */ ! 25: #define GUESSPATHLEN 100 ! 26: #endif /* (defined (USG) || defined (VMS)) */ ! 27: ! 28: char *getenv (); ! 29: char *xmalloc (); ! 30: ! 31: /* Get the working directory. Use the PWD environment variable if it's ! 32: set correctly, since this is faster and gives more uniform answers ! 33: to the user. Yield the working directory if successful; otherwise, ! 34: yield 0 and set errno. */ ! 35: ! 36: char * ! 37: getpwd () ! 38: { ! 39: static char *pwd; ! 40: static int failure_errno; ! 41: ! 42: char *p = pwd; ! 43: size_t s; ! 44: struct stat dotstat, pwdstat; ! 45: ! 46: if (!p && !(errno = failure_errno)) ! 47: { ! 48: if (! ((p = getenv ("PWD")) != 0 ! 49: && *p == '/' ! 50: && stat (p, &pwdstat) == 0 ! 51: && stat (".", &dotstat) == 0 ! 52: && dotstat.st_ino == pwdstat.st_ino ! 53: && dotstat.st_dev == pwdstat.st_dev)) ! 54: ! 55: /* The shortcut didn't work. Try the slow, ``sure'' way. */ ! 56: for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) ! 57: { ! 58: int e = errno; ! 59: free (p); ! 60: if (e != ERANGE) ! 61: { ! 62: errno = failure_errno = e; ! 63: p = 0; ! 64: break; ! 65: } ! 66: } ! 67: ! 68: /* Cache the result. This assumes that the program does ! 69: not invoke chdir between calls to getpwd. */ ! 70: pwd = p; ! 71: } ! 72: return p; ! 73: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.