1169695Skan/* getpwd.c - get the working directory */ 2169695Skan 3169695Skan/* 4169695Skan 5169695Skan@deftypefn Supplemental char* getpwd (void) 6169695Skan 7169695SkanReturns the current working directory. This implementation caches the 8169695Skanresult on the assumption that the process will not call @code{chdir} 9169695Skanbetween calls to @code{getpwd}. 10169695Skan 11169695Skan@end deftypefn 12169695Skan 13169695Skan*/ 14169695Skan 15169695Skan#ifdef HAVE_CONFIG_H 16169695Skan#include "config.h" 17169695Skan#endif 18169695Skan 19169695Skan#include <sys/types.h> 20169695Skan 21169695Skan#include <errno.h> 22169695Skan#ifndef errno 23169695Skanextern int errno; 24169695Skan#endif 25169695Skan 26169695Skan#ifdef HAVE_STDLIB_H 27169695Skan#include <stdlib.h> 28169695Skan#endif 29169695Skan#ifdef HAVE_UNISTD_H 30169695Skan#include <unistd.h> 31169695Skan#endif 32169695Skan#ifdef HAVE_SYS_PARAM_H 33169695Skan#include <sys/param.h> 34169695Skan#endif 35169695Skan#if HAVE_SYS_STAT_H 36169695Skan#include <sys/stat.h> 37169695Skan#endif 38169695Skan#if HAVE_LIMITS_H 39169695Skan#include <limits.h> 40169695Skan#endif 41169695Skan 42169695Skan#include "libiberty.h" 43169695Skan 44169695Skan/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe 45169695Skan BSD systems) now provides getcwd as called for by POSIX. Allow for 46169695Skan the few exceptions to the general rule here. */ 47169695Skan 48169695Skan#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) 49169695Skan/* Prototype in case the system headers doesn't provide it. */ 50169695Skanextern char *getwd (); 51169695Skan#define getcwd(buf,len) getwd(buf) 52169695Skan#endif 53169695Skan 54169695Skan#ifdef MAXPATHLEN 55169695Skan#define GUESSPATHLEN (MAXPATHLEN + 1) 56169695Skan#else 57169695Skan#define GUESSPATHLEN 100 58169695Skan#endif 59169695Skan 60169695Skan#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 61169695Skan 62169695Skan/* Get the working directory. Use the PWD environment variable if it's 63169695Skan set correctly, since this is faster and gives more uniform answers 64169695Skan to the user. Yield the working directory if successful; otherwise, 65169695Skan yield 0 and set errno. */ 66169695Skan 67169695Skanchar * 68169695Skangetpwd (void) 69169695Skan{ 70169695Skan static char *pwd; 71169695Skan static int failure_errno; 72169695Skan 73169695Skan char *p = pwd; 74169695Skan size_t s; 75169695Skan struct stat dotstat, pwdstat; 76169695Skan 77169695Skan if (!p && !(errno = failure_errno)) 78169695Skan { 79169695Skan if (! ((p = getenv ("PWD")) != 0 80169695Skan && *p == '/' 81169695Skan && stat (p, &pwdstat) == 0 82169695Skan && stat (".", &dotstat) == 0 83169695Skan && dotstat.st_ino == pwdstat.st_ino 84169695Skan && dotstat.st_dev == pwdstat.st_dev)) 85169695Skan 86169695Skan /* The shortcut didn't work. Try the slow, ``sure'' way. */ 87169695Skan for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) 88169695Skan { 89169695Skan int e = errno; 90169695Skan free (p); 91169695Skan#ifdef ERANGE 92169695Skan if (e != ERANGE) 93169695Skan#endif 94169695Skan { 95169695Skan errno = failure_errno = e; 96169695Skan p = 0; 97169695Skan break; 98169695Skan } 99169695Skan } 100169695Skan 101169695Skan /* Cache the result. This assumes that the program does 102169695Skan not invoke chdir between calls to getpwd. */ 103169695Skan pwd = p; 104169695Skan } 105169695Skan return p; 106169695Skan} 107169695Skan 108169695Skan#else /* VMS || _WIN32 && !__CYGWIN__ */ 109169695Skan 110169695Skan#ifndef MAXPATHLEN 111169695Skan#define MAXPATHLEN 255 112169695Skan#endif 113169695Skan 114169695Skanchar * 115169695Skangetpwd (void) 116169695Skan{ 117169695Skan static char *pwd = 0; 118169695Skan 119169695Skan if (!pwd) 120169695Skan pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1 121169695Skan#ifdef VMS 122169695Skan , 0 123169695Skan#endif 124169695Skan ); 125169695Skan return pwd; 126169695Skan} 127169695Skan 128169695Skan#endif /* VMS || _WIN32 && !__CYGWIN__ */ 129