getpwd.c revision 89857
11558Srgrimes/* getpwd.c - get the working directory */ 21558Srgrimes 31558Srgrimes/* 41558Srgrimes 51558Srgrimes@deftypefn Supplemental char* getpwd (void) 61558Srgrimes 71558SrgrimesReturns the current working directory. This implementation caches the 81558Srgrimesresult on the assumption that the process will not call @code{chdir} 91558Srgrimesbetween calls to @code{getpwd}. 101558Srgrimes 111558Srgrimes@end deftypefn 121558Srgrimes 131558Srgrimes*/ 141558Srgrimes 151558Srgrimes#ifdef HAVE_CONFIG_H 161558Srgrimes#include "config.h" 171558Srgrimes#endif 181558Srgrimes 191558Srgrimes#include <sys/types.h> 201558Srgrimes 211558Srgrimes#include <errno.h> 221558Srgrimes#ifndef errno 231558Srgrimesextern int errno; 241558Srgrimes#endif 251558Srgrimes 261558Srgrimes#ifdef HAVE_STDLIB_H 271558Srgrimes#include <stdlib.h> 281558Srgrimes#endif 291558Srgrimes#ifdef HAVE_UNISTD_H 301558Srgrimes#include <unistd.h> 311558Srgrimes#endif 321558Srgrimes#ifdef HAVE_SYS_PARAM_H 331558Srgrimes#include <sys/param.h> 341558Srgrimes#endif 3537906Scharnier#if HAVE_SYS_STAT_H 3623685Speter#include <sys/stat.h> 3737906Scharnier#endif 3837906Scharnier 3950476Speter/* Prototype these in case the system headers don't provide them. */ 401558Srgrimesextern char *getpwd (); 411558Srgrimesextern char *getwd (); 421558Srgrimes 431558Srgrimes#include "libiberty.h" 441558Srgrimes 451558Srgrimes/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe 461558Srgrimes BSD systems) now provides getcwd as called for by POSIX. Allow for 471558Srgrimes the few exceptions to the general rule here. */ 481558Srgrimes 491558Srgrimes#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) 501558Srgrimes#define getcwd(buf,len) getwd(buf) 511558Srgrimes#endif 521558Srgrimes 531558Srgrimes#ifdef MAXPATHLEN 541558Srgrimes#define GUESSPATHLEN (MAXPATHLEN + 1) 551558Srgrimes#else 561558Srgrimes#define GUESSPATHLEN 100 571558Srgrimes#endif 581558Srgrimes 591558Srgrimes#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 601558Srgrimes 611558Srgrimes/* Get the working directory. Use the PWD environment variable if it's 621558Srgrimes set correctly, since this is faster and gives more uniform answers 631558Srgrimes to the user. Yield the working directory if successful; otherwise, 641558Srgrimes yield 0 and set errno. */ 651558Srgrimes 661558Srgrimeschar * 671558Srgrimesgetpwd () 681558Srgrimes{ 691558Srgrimes static char *pwd; 701558Srgrimes static int failure_errno; 711558Srgrimes 721558Srgrimes char *p = pwd; 731558Srgrimes size_t s; 741558Srgrimes struct stat dotstat, pwdstat; 751558Srgrimes 761558Srgrimes if (!p && !(errno = failure_errno)) 771558Srgrimes { 781558Srgrimes if (! ((p = getenv ("PWD")) != 0 791558Srgrimes && *p == '/' 801558Srgrimes && stat (p, &pwdstat) == 0 811558Srgrimes && stat (".", &dotstat) == 0 821558Srgrimes && dotstat.st_ino == pwdstat.st_ino 831558Srgrimes && dotstat.st_dev == pwdstat.st_dev)) 841558Srgrimes 851558Srgrimes /* The shortcut didn't work. Try the slow, ``sure'' way. */ 861558Srgrimes for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) 8721997Simp { 881558Srgrimes int e = errno; 891558Srgrimes free (p); 9023685Speter#ifdef ERANGE 911558Srgrimes if (e != ERANGE) 921558Srgrimes#endif 931558Srgrimes { 941558Srgrimes errno = failure_errno = e; 951558Srgrimes p = 0; 961558Srgrimes break; 971558Srgrimes } 981558Srgrimes } 9992806Sobrien 1001558Srgrimes /* Cache the result. This assumes that the program does 1011558Srgrimes not invoke chdir between calls to getpwd. */ 1021558Srgrimes pwd = p; 1031558Srgrimes } 1041558Srgrimes return p; 1051558Srgrimes} 1061558Srgrimes 1071558Srgrimes#else /* VMS || _WIN32 && !__CYGWIN__ */ 1081558Srgrimes 1091558Srgrimes#ifndef MAXPATHLEN 1101558Srgrimes#define MAXPATHLEN 255 1111558Srgrimes#endif 1121558Srgrimes 1131558Srgrimeschar * 11421174Sguidogetpwd () 1151558Srgrimes{ 1161558Srgrimes static char *pwd = 0; 1171558Srgrimes 1181558Srgrimes if (!pwd) 1191558Srgrimes pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1 1201558Srgrimes#ifdef VMS 1211558Srgrimes , 0 1221558Srgrimes#endif 1231558Srgrimes ); 1241558Srgrimes return pwd; 1251558Srgrimes} 12621997Simp 1271558Srgrimes#endif /* VMS || _WIN32 && !__CYGWIN__ */ 1281558Srgrimes