160484Sobrien/* getpwd.c - get the working directory */ 260484Sobrien 389857Sobrien/* 489857Sobrien 589857Sobrien@deftypefn Supplemental char* getpwd (void) 689857Sobrien 789857SobrienReturns the current working directory. This implementation caches the 889857Sobrienresult on the assumption that the process will not call @code{chdir} 989857Sobrienbetween calls to @code{getpwd}. 1089857Sobrien 1189857Sobrien@end deftypefn 1289857Sobrien 1389857Sobrien*/ 1489857Sobrien 1560484Sobrien#ifdef HAVE_CONFIG_H 1660484Sobrien#include "config.h" 1760484Sobrien#endif 1860484Sobrien 1960484Sobrien#include <sys/types.h> 2060484Sobrien 2160484Sobrien#include <errno.h> 2260484Sobrien#ifndef errno 2360484Sobrienextern int errno; 2460484Sobrien#endif 2560484Sobrien 2660484Sobrien#ifdef HAVE_STDLIB_H 2760484Sobrien#include <stdlib.h> 2860484Sobrien#endif 2960484Sobrien#ifdef HAVE_UNISTD_H 3060484Sobrien#include <unistd.h> 3160484Sobrien#endif 3260484Sobrien#ifdef HAVE_SYS_PARAM_H 3360484Sobrien#include <sys/param.h> 3460484Sobrien#endif 3560484Sobrien#if HAVE_SYS_STAT_H 3660484Sobrien#include <sys/stat.h> 3760484Sobrien#endif 38130561Sobrien#if HAVE_LIMITS_H 39130561Sobrien#include <limits.h> 40130561Sobrien#endif 4160484Sobrien 4260484Sobrien#include "libiberty.h" 4360484Sobrien 4460484Sobrien/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe 4560484Sobrien BSD systems) now provides getcwd as called for by POSIX. Allow for 4660484Sobrien the few exceptions to the general rule here. */ 4760484Sobrien 4860484Sobrien#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) 49218822Sdim/* Prototype in case the system headers doesn't provide it. */ 50218822Sdimextern char *getwd (); 5160484Sobrien#define getcwd(buf,len) getwd(buf) 5260484Sobrien#endif 5360484Sobrien 5460484Sobrien#ifdef MAXPATHLEN 5560484Sobrien#define GUESSPATHLEN (MAXPATHLEN + 1) 5660484Sobrien#else 5760484Sobrien#define GUESSPATHLEN 100 5860484Sobrien#endif 5960484Sobrien 6060484Sobrien#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 6160484Sobrien 6260484Sobrien/* Get the working directory. Use the PWD environment variable if it's 6360484Sobrien set correctly, since this is faster and gives more uniform answers 6460484Sobrien to the user. Yield the working directory if successful; otherwise, 6560484Sobrien yield 0 and set errno. */ 6660484Sobrien 6760484Sobrienchar * 68218822Sdimgetpwd (void) 6960484Sobrien{ 7060484Sobrien static char *pwd; 7160484Sobrien static int failure_errno; 7260484Sobrien 7360484Sobrien char *p = pwd; 7460484Sobrien size_t s; 7560484Sobrien struct stat dotstat, pwdstat; 7660484Sobrien 7760484Sobrien if (!p && !(errno = failure_errno)) 7860484Sobrien { 7960484Sobrien if (! ((p = getenv ("PWD")) != 0 8060484Sobrien && *p == '/' 8160484Sobrien && stat (p, &pwdstat) == 0 8260484Sobrien && stat (".", &dotstat) == 0 8360484Sobrien && dotstat.st_ino == pwdstat.st_ino 8460484Sobrien && dotstat.st_dev == pwdstat.st_dev)) 8560484Sobrien 8660484Sobrien /* The shortcut didn't work. Try the slow, ``sure'' way. */ 87218822Sdim for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) 8860484Sobrien { 8960484Sobrien int e = errno; 9060484Sobrien free (p); 9160484Sobrien#ifdef ERANGE 9260484Sobrien if (e != ERANGE) 9360484Sobrien#endif 9460484Sobrien { 9560484Sobrien errno = failure_errno = e; 9660484Sobrien p = 0; 9760484Sobrien break; 9860484Sobrien } 9960484Sobrien } 10060484Sobrien 10160484Sobrien /* Cache the result. This assumes that the program does 10260484Sobrien not invoke chdir between calls to getpwd. */ 10360484Sobrien pwd = p; 10460484Sobrien } 10560484Sobrien return p; 10660484Sobrien} 10760484Sobrien 10860484Sobrien#else /* VMS || _WIN32 && !__CYGWIN__ */ 10960484Sobrien 11060484Sobrien#ifndef MAXPATHLEN 11160484Sobrien#define MAXPATHLEN 255 11260484Sobrien#endif 11360484Sobrien 11460484Sobrienchar * 115218822Sdimgetpwd (void) 11660484Sobrien{ 11760484Sobrien static char *pwd = 0; 11860484Sobrien 11960484Sobrien if (!pwd) 120218822Sdim pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1 12160484Sobrien#ifdef VMS 12260484Sobrien , 0 12360484Sobrien#endif 12460484Sobrien ); 12560484Sobrien return pwd; 12660484Sobrien} 12760484Sobrien 12860484Sobrien#endif /* VMS || _WIN32 && !__CYGWIN__ */ 129