Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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__ */
  129.