(root)/
binutils-2.41/
libiberty/
getpwd.c
       1  /* getpwd.c - get the working directory */
       2  
       3  /*
       4  
       5  @deftypefn Supplemental char* getpwd (void)
       6  
       7  Returns the current working directory.  This implementation caches the
       8  result on the assumption that the process will not call @code{chdir}
       9  between calls to @code{getpwd}.
      10  
      11  @end deftypefn
      12  
      13  */
      14  
      15  #ifdef HAVE_CONFIG_H
      16  #include "config.h"
      17  #endif
      18  
      19  #include <sys/types.h>
      20  
      21  #include <errno.h>
      22  #ifndef errno
      23  extern int errno;
      24  #endif
      25  
      26  #ifdef HAVE_STDLIB_H
      27  #include <stdlib.h>
      28  #endif
      29  #ifdef HAVE_UNISTD_H
      30  #include <unistd.h>
      31  #endif
      32  #ifdef HAVE_SYS_PARAM_H
      33  #include <sys/param.h>
      34  #endif
      35  #if HAVE_SYS_STAT_H
      36  #include <sys/stat.h>
      37  #endif
      38  #if HAVE_LIMITS_H
      39  #include <limits.h>
      40  #endif
      41  
      42  #include "libiberty.h"
      43  
      44  /* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
      45     BSD systems) now provides getcwd as called for by POSIX.  Allow for
      46     the few exceptions to the general rule here.  */
      47  
      48  #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
      49  /* Prototype in case the system headers doesn't provide it. */
      50  extern char *getwd ();
      51  #define getcwd(buf,len) getwd(buf)
      52  #endif
      53  
      54  #ifdef MAXPATHLEN
      55  #define GUESSPATHLEN (MAXPATHLEN + 1)
      56  #else
      57  #define GUESSPATHLEN 100
      58  #endif
      59  
      60  #if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
      61  
      62  /* Get the working directory.  Use the PWD environment variable if it's
      63     set correctly, since this is faster and gives more uniform answers
      64     to the user.  Yield the working directory if successful; otherwise,
      65     yield 0 and set errno.  */
      66  
      67  char *
      68  getpwd (void)
      69  {
      70    static char *pwd;
      71    static int failure_errno;
      72  
      73    char *p = pwd;
      74    size_t s;
      75    struct stat dotstat, pwdstat;
      76  
      77    if (!p && !(errno = failure_errno))
      78      {
      79        if (! ((p = getenv ("PWD")) != 0
      80  	     && *p == '/'
      81  	     && stat (p, &pwdstat) == 0
      82  	     && stat (".", &dotstat) == 0
      83  	     && dotstat.st_ino == pwdstat.st_ino
      84  	     && dotstat.st_dev == pwdstat.st_dev))
      85  
      86  	/* The shortcut didn't work.  Try the slow, ``sure'' way.  */
      87  	for (s = GUESSPATHLEN;  !getcwd (p = XNEWVEC (char, s), s);  s *= 2)
      88  	  {
      89  	    int e = errno;
      90  	    free (p);
      91  #ifdef ERANGE
      92  	    if (e != ERANGE)
      93  #endif
      94  	      {
      95  		errno = failure_errno = e;
      96  		p = 0;
      97  		break;
      98  	      }
      99  	  }
     100  
     101        /* Cache the result.  This assumes that the program does
     102  	 not invoke chdir between calls to getpwd.  */
     103        pwd = p;
     104      }
     105    return p;
     106  }
     107  
     108  #else	/* VMS || _WIN32 && !__CYGWIN__ */
     109  
     110  #ifndef MAXPATHLEN
     111  #define MAXPATHLEN 255
     112  #endif
     113  
     114  char *
     115  getpwd (void)
     116  {
     117    static char *pwd = 0;
     118  
     119    if (!pwd)
     120      pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
     121  #ifdef VMS
     122  		  , 0
     123  #endif
     124  		  );
     125    return pwd;
     126  }
     127  
     128  #endif	/* VMS || _WIN32 && !__CYGWIN__ */