getpwd.c revision 60484
16562Sphk/* getpwd.c - get the working directory */ 237421Scharnier 36562Sphk#ifdef HAVE_CONFIG_H 46562Sphk#include "config.h" 53995Spst#endif 63995Spst 76562Sphk#include <sys/types.h> 86562Sphk 96562Sphk#include <errno.h> 106562Sphk#ifndef errno 116562Sphkextern int errno; 126562Sphk#endif 136562Sphk 146562Sphk#ifdef HAVE_STDLIB_H 156562Sphk#include <stdlib.h> 166562Sphk#endif 176562Sphk#ifdef HAVE_UNISTD_H 183995Spst#include <unistd.h> 193995Spst#endif 2037421Scharnier#ifdef HAVE_SYS_PARAM_H 2137421Scharnier#include <sys/param.h> 2237421Scharnier#endif 2337421Scharnier#if HAVE_SYS_STAT_H 2437421Scharnier#include <sys/stat.h> 2519168Sbde#endif 2637421Scharnier 2719168Sbde/* Prototype these in case the system headers don't provide them. */ 283995Spstextern char *getpwd (); 293995Spstextern char *getwd (); 3032074Ssteve 3119168Sbde#include "libiberty.h" 323995Spst 333995Spst/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe 346562Sphk BSD systems) now provides getcwd as called for by POSIX. Allow for 356562Sphk the few exceptions to the general rule here. */ 363995Spst 373995Spst#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) 383995Spst#define getcwd(buf,len) getwd(buf) 393995Spst#endif 406562Sphk 416562Sphk#ifdef MAXPATHLEN 426562Sphk#define GUESSPATHLEN (MAXPATHLEN + 1) 436725Sphk#else 4432074Ssteve#define GUESSPATHLEN 100 453995Spst#endif 463995Spst 473995Spst#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 483995Spst 493995Spst/* Get the working directory. Use the PWD environment variable if it's 503995Spst set correctly, since this is faster and gives more uniform answers 513995Spst to the user. Yield the working directory if successful; otherwise, 523995Spst yield 0 and set errno. */ 533995Spst 543995Spstchar * 556562Sphkgetpwd () 566562Sphk{ 576562Sphk static char *pwd; 586562Sphk static int failure_errno; 593995Spst 6032086Ssteve char *p = pwd; 616562Sphk size_t s; 629489Sphk struct stat dotstat, pwdstat; 633995Spst 6432074Ssteve if (!p && !(errno = failure_errno)) 6532086Ssteve { 6632086Ssteve if (! ((p = getenv ("PWD")) != 0 6732074Ssteve && *p == '/' 6832074Ssteve && stat (p, &pwdstat) == 0 6932074Ssteve && stat (".", &dotstat) == 0 7032074Ssteve && dotstat.st_ino == pwdstat.st_ino 7132074Ssteve && dotstat.st_dev == pwdstat.st_dev)) 7232074Ssteve 7332074Ssteve /* The shortcut didn't work. Try the slow, ``sure'' way. */ 746562Sphk for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) 7532074Ssteve { 7632074Ssteve int e = errno; 776562Sphk free (p); 7832074Ssteve#ifdef ERANGE 7932074Ssteve if (e != ERANGE) 8032074Ssteve#endif 816562Sphk { 8232074Ssteve errno = failure_errno = e; 8332074Ssteve p = 0; 8432074Ssteve break; 8532074Ssteve } 8637421Scharnier } 8732074Ssteve 8832074Ssteve /* Cache the result. This assumes that the program does 8932074Ssteve not invoke chdir between calls to getpwd. */ 9032074Ssteve pwd = p; 9132074Ssteve } 926725Sphk return p; 933995Spst} 946562Sphk 953995Spst#else /* VMS || _WIN32 && !__CYGWIN__ */ 966562Sphk 976562Sphk#ifndef MAXPATHLEN 983995Spst#define MAXPATHLEN 255 996562Sphk#endif 1006562Sphk 1016562Sphkchar * 1023995Spstgetpwd () 1036562Sphk{ 1049489Sphk static char *pwd = 0; 1053995Spst 1069489Sphk if (!pwd) 1073995Spst pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1 1086562Sphk#ifdef VMS 1096562Sphk , 0 1103995Spst#endif 1116562Sphk ); 1126562Sphk return pwd; 1133995Spst} 1146562Sphk 1156562Sphk#endif /* VMS || _WIN32 && !__CYGWIN__ */ 1166725Sphk