/src/binutils-gdb/libiberty/getpwd.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | #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 | 19 | { |
70 | 19 | static char *pwd; |
71 | 19 | static int failure_errno; |
72 | | |
73 | 19 | char *p = pwd; |
74 | 19 | size_t s; |
75 | 19 | struct stat dotstat, pwdstat; |
76 | | |
77 | 19 | if (!p && !(errno = failure_errno)) |
78 | 1 | { |
79 | 1 | if (! ((p = getenv ("PWD")) != 0 |
80 | 1 | && *p == '/' |
81 | 1 | && stat (p, &pwdstat) == 0 |
82 | 1 | && stat (".", &dotstat) == 0 |
83 | 1 | && dotstat.st_ino == pwdstat.st_ino |
84 | 1 | && dotstat.st_dev == pwdstat.st_dev)) |
85 | | |
86 | | /* The shortcut didn't work. Try the slow, ``sure'' way. */ |
87 | 0 | for (s = GUESSPATHLEN; !getcwd (p = XNEWVEC (char, s), s); s *= 2) |
88 | 0 | { |
89 | 0 | int e = errno; |
90 | 0 | free (p); |
91 | 0 | #ifdef ERANGE |
92 | 0 | if (e != ERANGE) |
93 | 0 | #endif |
94 | 0 | { |
95 | 0 | errno = failure_errno = e; |
96 | 0 | p = 0; |
97 | 0 | break; |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | | /* Cache the result. This assumes that the program does |
102 | | not invoke chdir between calls to getpwd. */ |
103 | 1 | pwd = p; |
104 | 1 | } |
105 | 19 | return p; |
106 | 19 | } |
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__ */ |