Update gnulib to current upstream master
[external/binutils.git] / gdb / gnulib / import / getcwd.c
1 /* Copyright (C) 1991-1999, 2004-2018 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16
17 #if !_LIBC
18 # include <config.h>
19 # include <unistd.h>
20 #endif
21
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <stdbool.h>
26 #include <stddef.h>
27
28 #include <fcntl.h> /* For AT_FDCWD on Solaris 9.  */
29
30 /* If this host provides the openat function or if we're using the
31    gnulib replacement function with a native fdopendir, then enable
32    code below to make getcwd more efficient and robust.  */
33 #if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR)
34 # define HAVE_OPENAT_SUPPORT 1
35 #else
36 # define HAVE_OPENAT_SUPPORT 0
37 #endif
38
39 #ifndef __set_errno
40 # define __set_errno(val) (errno = (val))
41 #endif
42
43 #include <dirent.h>
44 #ifndef _D_EXACT_NAMLEN
45 # define _D_EXACT_NAMLEN(d) strlen ((d)->d_name)
46 #endif
47 #ifndef _D_ALLOC_NAMLEN
48 # define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
49 #endif
50
51 #include <unistd.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #if _LIBC
56 # ifndef mempcpy
57 #  define mempcpy __mempcpy
58 # endif
59 #endif
60
61 #ifndef MAX
62 # define MAX(a, b) ((a) < (b) ? (b) : (a))
63 #endif
64 #ifndef MIN
65 # define MIN(a, b) ((a) < (b) ? (a) : (b))
66 #endif
67
68 #include "pathmax.h"
69
70 /* In this file, PATH_MAX only serves as a threshold for choosing among two
71    algorithms.  */
72 #ifndef PATH_MAX
73 # define PATH_MAX 8192
74 #endif
75
76 #if D_INO_IN_DIRENT
77 # define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino))
78 #else
79 # define MATCHING_INO(dp, ino) true
80 #endif
81
82 #if !_LIBC
83 # define __getcwd rpl_getcwd
84 # define __lstat lstat
85 # define __closedir closedir
86 # define __opendir opendir
87 # define __readdir readdir
88 #endif
89
90 /* The results of opendir() in this file are not used with dirfd and fchdir,
91    and we do not leak fds to any single-threaded code that could use stdio,
92    therefore save some unnecessary recursion in fchdir.c.
93    FIXME - if the kernel ever adds support for multi-thread safety for
94    avoiding standard fds, then we should use opendir_safer and
95    openat_safer.  */
96 #ifdef GNULIB_defined_opendir
97 # undef opendir
98 #endif
99 #ifdef GNULIB_defined_closedir
100 # undef closedir
101 #endif
102 \f
103 /* Get the name of the current working directory, and put it in SIZE
104    bytes of BUF.  Returns NULL if the directory couldn't be determined or
105    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
106    NULL, an array is allocated with 'malloc'; the array is SIZE bytes long,
107    unless SIZE == 0, in which case it is as big as necessary.  */
108
109 char *
110 __getcwd (char *buf, size_t size)
111 {
112   /* Lengths of big file name components and entire file names, and a
113      deep level of file name nesting.  These numbers are not upper
114      bounds; they are merely large values suitable for initial
115      allocations, designed to be large enough for most real-world
116      uses.  */
117   enum
118     {
119       BIG_FILE_NAME_COMPONENT_LENGTH = 255,
120       BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1),
121       DEEP_NESTING = 100
122     };
123
124 #if HAVE_OPENAT_SUPPORT
125   int fd = AT_FDCWD;
126   bool fd_needs_closing = false;
127 #else
128   char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1];
129   char *dotlist = dots;
130   size_t dotsize = sizeof dots;
131   size_t dotlen = 0;
132 #endif
133   DIR *dirstream = NULL;
134   dev_t rootdev, thisdev;
135   ino_t rootino, thisino;
136   char *dir;
137   register char *dirp;
138   struct stat st;
139   size_t allocated = size;
140   size_t used;
141
142 #if HAVE_MINIMALLY_WORKING_GETCWD
143   /* If AT_FDCWD is not defined, the algorithm below is O(N**2) and
144      this is much slower than the system getcwd (at least on
145      GNU/Linux).  So trust the system getcwd's results unless they
146      look suspicious.
147
148      Use the system getcwd even if we have openat support, since the
149      system getcwd works even when a parent is unreadable, while the
150      openat-based approach does not.
151
152      But on AIX 5.1..7.1, the system getcwd is not even minimally
153      working: If the current directory name is slightly longer than
154      PATH_MAX, it omits the first directory component and returns
155      this wrong result with errno = 0.  */
156
157 # undef getcwd
158   dir = getcwd (buf, size);
159   if (dir || (size && errno == ERANGE))
160     return dir;
161
162   /* Solaris getcwd (NULL, 0) fails with errno == EINVAL, but it has
163      internal magic that lets it work even if an ancestor directory is
164      inaccessible, which is better in many cases.  So in this case try
165      again with a buffer that's almost always big enough.  */
166   if (errno == EINVAL && buf == NULL && size == 0)
167     {
168       char big_buffer[BIG_FILE_NAME_LENGTH + 1];
169       dir = getcwd (big_buffer, sizeof big_buffer);
170       if (dir)
171         return strdup (dir);
172     }
173
174 # if HAVE_PARTLY_WORKING_GETCWD
175   /* The system getcwd works, except it sometimes fails when it
176      shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT.    */
177   if (errno != ERANGE && errno != ENAMETOOLONG && errno != ENOENT)
178     return NULL;
179 # endif
180 #endif
181
182   if (size == 0)
183     {
184       if (buf != NULL)
185         {
186           __set_errno (EINVAL);
187           return NULL;
188         }
189
190       allocated = BIG_FILE_NAME_LENGTH + 1;
191     }
192
193   if (buf == NULL)
194     {
195       dir = malloc (allocated);
196       if (dir == NULL)
197         return NULL;
198     }
199   else
200     dir = buf;
201
202   dirp = dir + allocated;
203   *--dirp = '\0';
204
205   if (__lstat (".", &st) < 0)
206     goto lose;
207   thisdev = st.st_dev;
208   thisino = st.st_ino;
209
210   if (__lstat ("/", &st) < 0)
211     goto lose;
212   rootdev = st.st_dev;
213   rootino = st.st_ino;
214
215   while (!(thisdev == rootdev && thisino == rootino))
216     {
217       struct dirent *d;
218       dev_t dotdev;
219       ino_t dotino;
220       bool mount_point;
221       int parent_status;
222       size_t dirroom;
223       size_t namlen;
224       bool use_d_ino = true;
225
226       /* Look at the parent directory.  */
227 #if HAVE_OPENAT_SUPPORT
228       fd = openat (fd, "..", O_RDONLY);
229       if (fd < 0)
230         goto lose;
231       fd_needs_closing = true;
232       parent_status = fstat (fd, &st);
233 #else
234       dotlist[dotlen++] = '.';
235       dotlist[dotlen++] = '.';
236       dotlist[dotlen] = '\0';
237       parent_status = __lstat (dotlist, &st);
238 #endif
239       if (parent_status != 0)
240         goto lose;
241
242       if (dirstream && __closedir (dirstream) != 0)
243         {
244           dirstream = NULL;
245           goto lose;
246         }
247
248       /* Figure out if this directory is a mount point.  */
249       dotdev = st.st_dev;
250       dotino = st.st_ino;
251       mount_point = dotdev != thisdev;
252
253       /* Search for the last directory.  */
254 #if HAVE_OPENAT_SUPPORT
255       dirstream = fdopendir (fd);
256       if (dirstream == NULL)
257         goto lose;
258       fd_needs_closing = false;
259 #else
260       dirstream = __opendir (dotlist);
261       if (dirstream == NULL)
262         goto lose;
263       dotlist[dotlen++] = '/';
264 #endif
265       for (;;)
266         {
267           /* Clear errno to distinguish EOF from error if readdir returns
268              NULL.  */
269           __set_errno (0);
270           d = __readdir (dirstream);
271
272           /* When we've iterated through all directory entries without finding
273              one with a matching d_ino, rewind the stream and consider each
274              name again, but this time, using lstat.  This is necessary in a
275              chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where
276              .., ../.., ../../.., etc. all had the same device number, yet the
277              d_ino values for entries in / did not match those obtained
278              via lstat.  */
279           if (d == NULL && errno == 0 && use_d_ino)
280             {
281               use_d_ino = false;
282               rewinddir (dirstream);
283               d = __readdir (dirstream);
284             }
285
286           if (d == NULL)
287             {
288               if (errno == 0)
289                 /* EOF on dirstream, which can mean e.g., that the current
290                    directory has been removed.  */
291                 __set_errno (ENOENT);
292               goto lose;
293             }
294           if (d->d_name[0] == '.' &&
295               (d->d_name[1] == '\0' ||
296                (d->d_name[1] == '.' && d->d_name[2] == '\0')))
297             continue;
298
299           if (use_d_ino)
300             {
301               bool match = (MATCHING_INO (d, thisino) || mount_point);
302               if (! match)
303                 continue;
304             }
305
306           {
307             int entry_status;
308 #if HAVE_OPENAT_SUPPORT
309             entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW);
310 #else
311             /* Compute size needed for this file name, or for the file
312                name ".." in the same directory, whichever is larger.
313                Room for ".." might be needed the next time through
314                the outer loop.  */
315             size_t name_alloc = _D_ALLOC_NAMLEN (d);
316             size_t filesize = dotlen + MAX (sizeof "..", name_alloc);
317
318             if (filesize < dotlen)
319               goto memory_exhausted;
320
321             if (dotsize < filesize)
322               {
323                 /* My, what a deep directory tree you have, Grandma.  */
324                 size_t newsize = MAX (filesize, dotsize * 2);
325                 size_t i;
326                 if (newsize < dotsize)
327                   goto memory_exhausted;
328                 if (dotlist != dots)
329                   free (dotlist);
330                 dotlist = malloc (newsize);
331                 if (dotlist == NULL)
332                   goto lose;
333                 dotsize = newsize;
334
335                 i = 0;
336                 do
337                   {
338                     dotlist[i++] = '.';
339                     dotlist[i++] = '.';
340                     dotlist[i++] = '/';
341                   }
342                 while (i < dotlen);
343               }
344
345             memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d));
346             entry_status = __lstat (dotlist, &st);
347 #endif
348             /* We don't fail here if we cannot stat() a directory entry.
349                This can happen when (network) file systems fail.  If this
350                entry is in fact the one we are looking for we will find
351                out soon as we reach the end of the directory without
352                having found anything.  */
353             if (entry_status == 0 && S_ISDIR (st.st_mode)
354                 && st.st_dev == thisdev && st.st_ino == thisino)
355               break;
356           }
357         }
358
359       dirroom = dirp - dir;
360       namlen = _D_EXACT_NAMLEN (d);
361
362       if (dirroom <= namlen)
363         {
364           if (size != 0)
365             {
366               __set_errno (ERANGE);
367               goto lose;
368             }
369           else
370             {
371               char *tmp;
372               size_t oldsize = allocated;
373
374               allocated += MAX (allocated, namlen);
375               if (allocated < oldsize
376                   || ! (tmp = realloc (dir, allocated)))
377                 goto memory_exhausted;
378
379               /* Move current contents up to the end of the buffer.
380                  This is guaranteed to be non-overlapping.  */
381               dirp = memcpy (tmp + allocated - (oldsize - dirroom),
382                              tmp + dirroom,
383                              oldsize - dirroom);
384               dir = tmp;
385             }
386         }
387       dirp -= namlen;
388       memcpy (dirp, d->d_name, namlen);
389       *--dirp = '/';
390
391       thisdev = dotdev;
392       thisino = dotino;
393     }
394
395   if (dirstream && __closedir (dirstream) != 0)
396     {
397       dirstream = NULL;
398       goto lose;
399     }
400
401   if (dirp == &dir[allocated - 1])
402     *--dirp = '/';
403
404 #if ! HAVE_OPENAT_SUPPORT
405   if (dotlist != dots)
406     free (dotlist);
407 #endif
408
409   used = dir + allocated - dirp;
410   memmove (dir, dirp, used);
411
412   if (size == 0)
413     /* Ensure that the buffer is only as large as necessary.  */
414     buf = realloc (dir, used);
415
416   if (buf == NULL)
417     /* Either buf was NULL all along, or 'realloc' failed but
418        we still have the original string.  */
419     buf = dir;
420
421   return buf;
422
423  memory_exhausted:
424   __set_errno (ENOMEM);
425  lose:
426   {
427     int save = errno;
428     if (dirstream)
429       __closedir (dirstream);
430 #if HAVE_OPENAT_SUPPORT
431     if (fd_needs_closing)
432       close (fd);
433 #else
434     if (dotlist != dots)
435       free (dotlist);
436 #endif
437     if (buf == NULL)
438       free (dir);
439     __set_errno (save);
440   }
441   return NULL;
442 }
443
444 #ifdef weak_alias
445 weak_alias (__getcwd, getcwd)
446 #endif