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