100bf4279Sespie /* getpwd.c - get the working directory */
200bf4279Sespie
39588ddcfSespie /*
49588ddcfSespie
59588ddcfSespie @deftypefn Supplemental char* getpwd (void)
69588ddcfSespie
79588ddcfSespie Returns the current working directory. This implementation caches the
89588ddcfSespie result on the assumption that the process will not call @code{chdir}
99588ddcfSespie between calls to @code{getpwd}.
109588ddcfSespie
119588ddcfSespie @end deftypefn
129588ddcfSespie
139588ddcfSespie */
149588ddcfSespie
1500bf4279Sespie #ifdef HAVE_CONFIG_H
1600bf4279Sespie #include "config.h"
1700bf4279Sespie #endif
1800bf4279Sespie
1900bf4279Sespie #include <sys/types.h>
2000bf4279Sespie
2100bf4279Sespie #include <errno.h>
2200bf4279Sespie #ifndef errno
2300bf4279Sespie extern int errno;
2400bf4279Sespie #endif
2500bf4279Sespie
2600bf4279Sespie #ifdef HAVE_STDLIB_H
2700bf4279Sespie #include <stdlib.h>
2800bf4279Sespie #endif
2900bf4279Sespie #ifdef HAVE_UNISTD_H
3000bf4279Sespie #include <unistd.h>
3100bf4279Sespie #endif
3200bf4279Sespie #ifdef HAVE_SYS_PARAM_H
3300bf4279Sespie #include <sys/param.h>
3400bf4279Sespie #endif
3500bf4279Sespie #if HAVE_SYS_STAT_H
3600bf4279Sespie #include <sys/stat.h>
3700bf4279Sespie #endif
38*20fce977Smiod #if HAVE_LIMITS_H
39*20fce977Smiod #include <limits.h>
40*20fce977Smiod #endif
4100bf4279Sespie
4200bf4279Sespie #include "libiberty.h"
4300bf4279Sespie
4400bf4279Sespie /* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
4500bf4279Sespie BSD systems) now provides getcwd as called for by POSIX. Allow for
4600bf4279Sespie the few exceptions to the general rule here. */
4700bf4279Sespie
4800bf4279Sespie #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
49*20fce977Smiod /* Prototype in case the system headers doesn't provide it. */
50*20fce977Smiod extern char *getwd ();
5100bf4279Sespie #define getcwd(buf,len) getwd(buf)
5200bf4279Sespie #endif
5300bf4279Sespie
5400bf4279Sespie #ifdef MAXPATHLEN
5500bf4279Sespie #define GUESSPATHLEN (MAXPATHLEN + 1)
5600bf4279Sespie #else
5700bf4279Sespie #define GUESSPATHLEN 100
5800bf4279Sespie #endif
5900bf4279Sespie
6000bf4279Sespie #if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
6100bf4279Sespie
6200bf4279Sespie /* Get the working directory. Use the PWD environment variable if it's
6300bf4279Sespie set correctly, since this is faster and gives more uniform answers
6400bf4279Sespie to the user. Yield the working directory if successful; otherwise,
6500bf4279Sespie yield 0 and set errno. */
6600bf4279Sespie
6700bf4279Sespie char *
getpwd(void)68*20fce977Smiod getpwd (void)
6900bf4279Sespie {
7000bf4279Sespie static char *pwd;
7100bf4279Sespie static int failure_errno;
7200bf4279Sespie
7300bf4279Sespie char *p = pwd;
7400bf4279Sespie size_t s;
7500bf4279Sespie struct stat dotstat, pwdstat;
7600bf4279Sespie
7700bf4279Sespie if (!p && !(errno = failure_errno))
7800bf4279Sespie {
7900bf4279Sespie if (! ((p = getenv ("PWD")) != 0
8000bf4279Sespie && *p == '/'
8100bf4279Sespie && stat (p, &pwdstat) == 0
8200bf4279Sespie && stat (".", &dotstat) == 0
8300bf4279Sespie && dotstat.st_ino == pwdstat.st_ino
8400bf4279Sespie && dotstat.st_dev == pwdstat.st_dev))
8500bf4279Sespie
8600bf4279Sespie /* The shortcut didn't work. Try the slow, ``sure'' way. */
87*20fce977Smiod for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2)
8800bf4279Sespie {
8900bf4279Sespie int e = errno;
9000bf4279Sespie free (p);
9100bf4279Sespie #ifdef ERANGE
9200bf4279Sespie if (e != ERANGE)
9300bf4279Sespie #endif
9400bf4279Sespie {
9500bf4279Sespie errno = failure_errno = e;
9600bf4279Sespie p = 0;
9700bf4279Sespie break;
9800bf4279Sespie }
9900bf4279Sespie }
10000bf4279Sespie
10100bf4279Sespie /* Cache the result. This assumes that the program does
10200bf4279Sespie not invoke chdir between calls to getpwd. */
10300bf4279Sespie pwd = p;
10400bf4279Sespie }
10500bf4279Sespie return p;
10600bf4279Sespie }
10700bf4279Sespie
10800bf4279Sespie #else /* VMS || _WIN32 && !__CYGWIN__ */
10900bf4279Sespie
11000bf4279Sespie #ifndef MAXPATHLEN
11100bf4279Sespie #define MAXPATHLEN 255
11200bf4279Sespie #endif
11300bf4279Sespie
11400bf4279Sespie char *
getpwd(void)115*20fce977Smiod getpwd (void)
11600bf4279Sespie {
11700bf4279Sespie static char *pwd = 0;
11800bf4279Sespie
11900bf4279Sespie if (!pwd)
120*20fce977Smiod pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
12100bf4279Sespie #ifdef VMS
12200bf4279Sespie , 0
12300bf4279Sespie #endif
12400bf4279Sespie );
12500bf4279Sespie return pwd;
12600bf4279Sespie }
12700bf4279Sespie
12800bf4279Sespie #endif /* VMS || _WIN32 && !__CYGWIN__ */
129