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