152419Sjulian/* getpwd.c - get the working directory */ 252419Sjulian 352419Sjulian/* 452419Sjulian 552419Sjulian@deftypefn Supplemental char* getpwd (void) 652419Sjulian 752419SjulianReturns the current working directory. This implementation caches the 852419Sjulianresult on the assumption that the process will not call @code{chdir} 952419Sjulianbetween calls to @code{getpwd}. 1052419Sjulian 1152419Sjulian@end deftypefn 1252419Sjulian 1352419Sjulian*/ 1452419Sjulian 1552419Sjulian#ifdef HAVE_CONFIG_H 1652419Sjulian#include "config.h" 1752419Sjulian#endif 1852419Sjulian 1952419Sjulian#include <sys/types.h> 2052419Sjulian 2152419Sjulian#include <errno.h> 2252419Sjulian#ifndef errno 2352419Sjulianextern int errno; 2452419Sjulian#endif 2552419Sjulian 2652419Sjulian#ifdef HAVE_STDLIB_H 2752419Sjulian#include <stdlib.h> 2852419Sjulian#endif 2952419Sjulian#ifdef HAVE_UNISTD_H 3052419Sjulian#include <unistd.h> 3152419Sjulian#endif 3252419Sjulian#ifdef HAVE_SYS_PARAM_H 3352419Sjulian#include <sys/param.h> 3452419Sjulian#endif 3552419Sjulian#if HAVE_SYS_STAT_H 3652419Sjulian#include <sys/stat.h> 3752419Sjulian#endif 3852419Sjulian#if HAVE_LIMITS_H 3952419Sjulian#include <limits.h> 4052419Sjulian#endif 4152419Sjulian 4252419Sjulian#include "libiberty.h" 4352419Sjulian 4452419Sjulian/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe 4552419Sjulian BSD systems) now provides getcwd as called for by POSIX. Allow for 4652419Sjulian the few exceptions to the general rule here. */ 4752419Sjulian 4852419Sjulian#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) 4952419Sjulian/* Prototype in case the system headers doesn't provide it. */ 5052419Sjulianextern char *getwd (); 5152419Sjulian#define getcwd(buf,len) getwd(buf) 5252419Sjulian#endif 5352419Sjulian 5452419Sjulian#ifdef MAXPATHLEN 5552419Sjulian#define GUESSPATHLEN (MAXPATHLEN + 1) 5652419Sjulian#else 5752419Sjulian#define GUESSPATHLEN 100 5852419Sjulian#endif 5952419Sjulian 6052419Sjulian#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 6152419Sjulian 6252419Sjulian/* Get the working directory. Use the PWD environment variable if it's 6352419Sjulian set correctly, since this is faster and gives more uniform answers 6452419Sjulian to the user. Yield the working directory if successful; otherwise, 6552419Sjulian yield 0 and set errno. */ 6652419Sjulian 6752419Sjulianchar * 6852419Sjuliangetpwd (void) 6952419Sjulian{ 7052419Sjulian static char *pwd; 7152419Sjulian static int failure_errno; 7252419Sjulian 7352419Sjulian char *p = pwd; 7452419Sjulian size_t s; 7552419Sjulian struct stat dotstat, pwdstat; 7652419Sjulian 7752419Sjulian if (!p && !(errno = failure_errno)) 7852419Sjulian { 7952419Sjulian if (! ((p = getenv ("PWD")) != 0 8052419Sjulian && *p == '/' 8152419Sjulian && stat (p, &pwdstat) == 0 8252419Sjulian && stat (".", &dotstat) == 0 8352419Sjulian && dotstat.st_ino == pwdstat.st_ino 8452419Sjulian && dotstat.st_dev == pwdstat.st_dev)) 8552419Sjulian 8652419Sjulian /* The shortcut didn't work. Try the slow, ``sure'' way. */ 8752419Sjulian for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) 8852419Sjulian { 8952419Sjulian int e = errno; 9052419Sjulian free (p); 9152419Sjulian#ifdef ERANGE 9252419Sjulian if (e != ERANGE) 9352419Sjulian#endif 9452419Sjulian { 9552419Sjulian errno = failure_errno = e; 9652419Sjulian p = 0; 9752419Sjulian break; 9852419Sjulian } 9952419Sjulian } 10052539Sjulian 10152419Sjulian /* Cache the result. This assumes that the program does 10252419Sjulian not invoke chdir between calls to getpwd. */ 10352419Sjulian pwd = p; 10452419Sjulian } 10552419Sjulian return p; 10652419Sjulian} 10752419Sjulian 10852419Sjulian#else /* VMS || _WIN32 && !__CYGWIN__ */ 10952419Sjulian 11052419Sjulian#ifndef MAXPATHLEN 11152419Sjulian#define MAXPATHLEN 255 11252419Sjulian#endif 11352419Sjulian 11452419Sjulianchar * 11552419Sjuliangetpwd (void) 11652419Sjulian{ 11752419Sjulian static char *pwd = 0; 11852419Sjulian 11952419Sjulian if (!pwd) 12052419Sjulian pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1 12152419Sjulian#ifdef VMS 12252419Sjulian , 0 12352419Sjulian#endif 12452419Sjulian ); 12552419Sjulian return pwd; 12652419Sjulian} 12752419Sjulian 12852419Sjulian#endif /* VMS || _WIN32 && !__CYGWIN__ */ 12952419Sjulian