Back to index

cell-binutils  2.17cvs20070401
getpwd.c
Go to the documentation of this file.
00001 /* getpwd.c - get the working directory */
00002 
00003 /*
00004 
00005 @deftypefn Supplemental char* getpwd (void)
00006 
00007 Returns the current working directory.  This implementation caches the
00008 result on the assumption that the process will not call @code{chdir}
00009 between calls to @code{getpwd}.
00010 
00011 @end deftypefn
00012 
00013 */
00014 
00015 #ifdef HAVE_CONFIG_H
00016 #include "config.h"
00017 #endif
00018 
00019 #include <sys/types.h>
00020 
00021 #include <errno.h>
00022 #ifndef errno
00023 extern int errno;
00024 #endif
00025 
00026 #ifdef HAVE_STDLIB_H
00027 #include <stdlib.h>
00028 #endif
00029 #ifdef HAVE_UNISTD_H
00030 #include <unistd.h>
00031 #endif
00032 #ifdef HAVE_SYS_PARAM_H
00033 #include <sys/param.h>
00034 #endif
00035 #if HAVE_SYS_STAT_H
00036 #include <sys/stat.h>
00037 #endif
00038 #if HAVE_LIMITS_H
00039 #include <limits.h>
00040 #endif
00041 
00042 #include "libiberty.h"
00043 
00044 /* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
00045    BSD systems) now provides getcwd as called for by POSIX.  Allow for
00046    the few exceptions to the general rule here.  */
00047 
00048 #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
00049 /* Prototype in case the system headers doesn't provide it. */
00050 extern char *getwd ();
00051 #define getcwd(buf,len) getwd(buf)
00052 #endif
00053 
00054 #ifdef MAXPATHLEN
00055 #define GUESSPATHLEN (MAXPATHLEN + 1)
00056 #else
00057 #define GUESSPATHLEN 100
00058 #endif
00059 
00060 #if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
00061 
00062 /* Get the working directory.  Use the PWD environment variable if it's
00063    set correctly, since this is faster and gives more uniform answers
00064    to the user.  Yield the working directory if successful; otherwise,
00065    yield 0 and set errno.  */
00066 
00067 char *
00068 getpwd (void)
00069 {
00070   static char *pwd;
00071   static int failure_errno;
00072 
00073   char *p = pwd;
00074   size_t s;
00075   struct stat dotstat, pwdstat;
00076 
00077   if (!p && !(errno = failure_errno))
00078     {
00079       if (! ((p = getenv ("PWD")) != 0
00080             && *p == '/'
00081             && stat (p, &pwdstat) == 0
00082             && stat (".", &dotstat) == 0
00083             && dotstat.st_ino == pwdstat.st_ino
00084             && dotstat.st_dev == pwdstat.st_dev))
00085 
00086        /* The shortcut didn't work.  Try the slow, ``sure'' way.  */
00087        for (s = GUESSPATHLEN;  !getcwd (p = XNEWVEC (char, s), s);  s *= 2)
00088          {
00089            int e = errno;
00090            free (p);
00091 #ifdef ERANGE
00092            if (e != ERANGE)
00093 #endif
00094              {
00095               errno = failure_errno = e;
00096               p = 0;
00097               break;
00098              }
00099          }
00100 
00101       /* Cache the result.  This assumes that the program does
00102         not invoke chdir between calls to getpwd.  */
00103       pwd = p;
00104     }
00105   return p;
00106 }
00107 
00108 #else  /* VMS || _WIN32 && !__CYGWIN__ */
00109 
00110 #ifndef MAXPATHLEN
00111 #define MAXPATHLEN 255
00112 #endif
00113 
00114 char *
00115 getpwd (void)
00116 {
00117   static char *pwd = 0;
00118 
00119   if (!pwd)
00120     pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
00121 #ifdef VMS
00122                 , 0
00123 #endif
00124                 );
00125   return pwd;
00126 }
00127 
00128 #endif /* VMS || _WIN32 && !__CYGWIN__ */