1169695Skan/* getpwd.c - get the working directory */
2169695Skan
3169695Skan/*
4169695Skan
5169695Skan@deftypefn Supplemental char* getpwd (void)
6169695Skan
7169695SkanReturns the current working directory.  This implementation caches the
8169695Skanresult on the assumption that the process will not call @code{chdir}
9169695Skanbetween calls to @code{getpwd}.
10169695Skan
11169695Skan@end deftypefn
12169695Skan
13169695Skan*/
14169695Skan
15169695Skan#ifdef HAVE_CONFIG_H
16169695Skan#include "config.h"
17169695Skan#endif
18169695Skan
19169695Skan#include <sys/types.h>
20169695Skan
21169695Skan#include <errno.h>
22169695Skan#ifndef errno
23169695Skanextern int errno;
24169695Skan#endif
25169695Skan
26169695Skan#ifdef HAVE_STDLIB_H
27169695Skan#include <stdlib.h>
28169695Skan#endif
29169695Skan#ifdef HAVE_UNISTD_H
30169695Skan#include <unistd.h>
31169695Skan#endif
32169695Skan#ifdef HAVE_SYS_PARAM_H
33169695Skan#include <sys/param.h>
34169695Skan#endif
35169695Skan#if HAVE_SYS_STAT_H
36169695Skan#include <sys/stat.h>
37169695Skan#endif
38169695Skan#if HAVE_LIMITS_H
39169695Skan#include <limits.h>
40169695Skan#endif
41169695Skan
42169695Skan#include "libiberty.h"
43169695Skan
44169695Skan/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
45169695Skan   BSD systems) now provides getcwd as called for by POSIX.  Allow for
46169695Skan   the few exceptions to the general rule here.  */
47169695Skan
48169695Skan#if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
49169695Skan/* Prototype in case the system headers doesn't provide it. */
50169695Skanextern char *getwd ();
51169695Skan#define getcwd(buf,len) getwd(buf)
52169695Skan#endif
53169695Skan
54169695Skan#ifdef MAXPATHLEN
55169695Skan#define GUESSPATHLEN (MAXPATHLEN + 1)
56169695Skan#else
57169695Skan#define GUESSPATHLEN 100
58169695Skan#endif
59169695Skan
60169695Skan#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
61169695Skan
62169695Skan/* Get the working directory.  Use the PWD environment variable if it's
63169695Skan   set correctly, since this is faster and gives more uniform answers
64169695Skan   to the user.  Yield the working directory if successful; otherwise,
65169695Skan   yield 0 and set errno.  */
66169695Skan
67169695Skanchar *
68169695Skangetpwd (void)
69169695Skan{
70169695Skan  static char *pwd;
71169695Skan  static int failure_errno;
72169695Skan
73169695Skan  char *p = pwd;
74169695Skan  size_t s;
75169695Skan  struct stat dotstat, pwdstat;
76169695Skan
77169695Skan  if (!p && !(errno = failure_errno))
78169695Skan    {
79169695Skan      if (! ((p = getenv ("PWD")) != 0
80169695Skan	     && *p == '/'
81169695Skan	     && stat (p, &pwdstat) == 0
82169695Skan	     && stat (".", &dotstat) == 0
83169695Skan	     && dotstat.st_ino == pwdstat.st_ino
84169695Skan	     && dotstat.st_dev == pwdstat.st_dev))
85169695Skan
86169695Skan	/* The shortcut didn't work.  Try the slow, ``sure'' way.  */
87169695Skan	for (s = GUESSPATHLEN;  !getcwd (p = XNEWVEC (char, s), s);  s *= 2)
88169695Skan	  {
89169695Skan	    int e = errno;
90169695Skan	    free (p);
91169695Skan#ifdef ERANGE
92169695Skan	    if (e != ERANGE)
93169695Skan#endif
94169695Skan	      {
95169695Skan		errno = failure_errno = e;
96169695Skan		p = 0;
97169695Skan		break;
98169695Skan	      }
99169695Skan	  }
100169695Skan
101169695Skan      /* Cache the result.  This assumes that the program does
102169695Skan	 not invoke chdir between calls to getpwd.  */
103169695Skan      pwd = p;
104169695Skan    }
105169695Skan  return p;
106169695Skan}
107169695Skan
108169695Skan#else	/* VMS || _WIN32 && !__CYGWIN__ */
109169695Skan
110169695Skan#ifndef MAXPATHLEN
111169695Skan#define MAXPATHLEN 255
112169695Skan#endif
113169695Skan
114169695Skanchar *
115169695Skangetpwd (void)
116169695Skan{
117169695Skan  static char *pwd = 0;
118169695Skan
119169695Skan  if (!pwd)
120169695Skan    pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
121169695Skan#ifdef VMS
122169695Skan		  , 0
123169695Skan#endif
124169695Skan		  );
125169695Skan  return pwd;
126169695Skan}
127169695Skan
128169695Skan#endif	/* VMS || _WIN32 && !__CYGWIN__ */
129