diff options
author | Ian Lance Taylor <ian@airs.com> | 2000-02-22 15:59:20 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2000-02-22 15:59:20 +0000 |
commit | e2eaf477991014a67bc122c3225f6a3fe6d1a8e6 (patch) | |
tree | 5937dcfd1baa6d55a635fde513e946dc33a05ca3 /libiberty/getpwd.c | |
parent | 252b5132c753830d5fd56823373aed85f2a0db63 (diff) | |
download | fsf-binutils-gdb-e2eaf477991014a67bc122c3225f6a3fe6d1a8e6.zip fsf-binutils-gdb-e2eaf477991014a67bc122c3225f6a3fe6d1a8e6.tar.gz fsf-binutils-gdb-e2eaf477991014a67bc122c3225f6a3fe6d1a8e6.tar.bz2 |
import libiberty from egcs
Diffstat (limited to 'libiberty/getpwd.c')
-rw-r--r-- | libiberty/getpwd.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/libiberty/getpwd.c b/libiberty/getpwd.c new file mode 100644 index 0000000..de6e039 --- /dev/null +++ b/libiberty/getpwd.c @@ -0,0 +1,115 @@ +/* getpwd.c - get the working directory */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> + +#include <errno.h> +#ifndef errno +extern int errno; +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#if HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +/* Prototype these in case the system headers don't provide them. */ +extern char *getpwd (); +extern char *getwd (); + +#include "libiberty.h" + +/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe + BSD systems) now provides getcwd as called for by POSIX. Allow for + the few exceptions to the general rule here. */ + +#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD) +#define getcwd(buf,len) getwd(buf) +#endif + +#ifdef MAXPATHLEN +#define GUESSPATHLEN (MAXPATHLEN + 1) +#else +#define GUESSPATHLEN 100 +#endif + +#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) + +/* Get the working directory. Use the PWD environment variable if it's + set correctly, since this is faster and gives more uniform answers + to the user. Yield the working directory if successful; otherwise, + yield 0 and set errno. */ + +char * +getpwd () +{ + static char *pwd; + static int failure_errno; + + char *p = pwd; + size_t s; + struct stat dotstat, pwdstat; + + if (!p && !(errno = failure_errno)) + { + if (! ((p = getenv ("PWD")) != 0 + && *p == '/' + && stat (p, &pwdstat) == 0 + && stat (".", &dotstat) == 0 + && dotstat.st_ino == pwdstat.st_ino + && dotstat.st_dev == pwdstat.st_dev)) + + /* The shortcut didn't work. Try the slow, ``sure'' way. */ + for (s = GUESSPATHLEN; ! getcwd (p = xmalloc (s), s); s *= 2) + { + int e = errno; + free (p); +#ifdef ERANGE + if (e != ERANGE) +#endif + { + errno = failure_errno = e; + p = 0; + break; + } + } + + /* Cache the result. This assumes that the program does + not invoke chdir between calls to getpwd. */ + pwd = p; + } + return p; +} + +#else /* VMS || _WIN32 && !__CYGWIN__ */ + +#ifndef MAXPATHLEN +#define MAXPATHLEN 255 +#endif + +char * +getpwd () +{ + static char *pwd = 0; + + if (!pwd) + pwd = getcwd (xmalloc (MAXPATHLEN + 1), MAXPATHLEN + 1 +#ifdef VMS + , 0 +#endif + ); + return pwd; +} + +#endif /* VMS || _WIN32 && !__CYGWIN__ */ |