Update copyright notices with scripts/update-copyrights
[jlayton/glibc.git] / sysdeps / posix / getcwd.c
1 /* Copyright (C) 1991-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library 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 GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 /* Wants:
19    AC_STDC_HEADERS
20    AC_DIR_HEADER
21    AC_UNISTD_H
22    AC_MEMORY_H
23    AC_CONST
24    AC_ALLOCA
25  */
26
27 /* AIX requires this to be the first thing in the file.  */
28 #if defined _AIX && !defined __GNUC__
29  #pragma alloca
30 #endif
31
32 #ifdef  HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40
41 #ifdef  STDC_HEADERS
42 # include <stddef.h>
43 #endif
44
45 #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
46 extern int errno;
47 #endif
48 #ifndef __set_errno
49 # define __set_errno(val) errno = (val)
50 #endif
51
52 #ifndef NULL
53 # define NULL   0
54 #endif
55
56 #if defined USGr3 && !defined DIRENT
57 # define DIRENT
58 #endif /* USGr3 */
59 #if defined Xenix && !defined SYSNDIR
60 # define SYSNDIR
61 #endif /* Xenix */
62
63 #if defined POSIX || defined DIRENT || defined __GNU_LIBRARY__
64 # include <dirent.h>
65 # ifndef __GNU_LIBRARY__
66 #  define D_NAMLEN(d) strlen((d)->d_name)
67 # else
68 #  define HAVE_D_NAMLEN
69 #  define D_NAMLEN(d) ((d)->d_namlen)
70 # endif
71 #else /* not POSIX or DIRENT */
72 # define dirent         direct
73 # define D_NAMLEN(d)    ((d)->d_namlen)
74 # define HAVE_D_NAMLEN
75 # if defined USG && !defined sgi
76 #  if defined SYSNDIR
77 #   include <sys/ndir.h>
78 #  else /* Not SYSNDIR */
79 #   include "ndir.h"
80 #  endif /* SYSNDIR */
81 # else /* not USG */
82 #  include <sys/dir.h>
83 # endif /* USG */
84 #endif /* POSIX or DIRENT or __GNU_LIBRARY__ */
85
86 #if defined HAVE_UNISTD_H || defined __GNU_LIBRARY__
87 # include <unistd.h>
88 #endif
89
90 #if defined STDC_HEADERS || defined __GNU_LIBRARY__ || defined POSIX
91 # include <stdlib.h>
92 # include <string.h>
93 # define ANSI_STRING
94 #else   /* No standard headers.  */
95
96 # ifdef USG
97
98 #  include <string.h>
99 #  ifdef NEED_MEMORY_H
100 #   include <memory.h>
101 #  endif
102 #  define       ANSI_STRING
103
104 # else  /* Not USG.  */
105
106 #  ifdef NeXT
107
108 #   include <string.h>
109
110 #  else /* Not NeXT.  */
111
112 #   include <strings.h>
113
114 #   ifndef bcmp
115 extern int bcmp ();
116 #   endif
117 #   ifndef bzero
118 extern void bzero ();
119 #   endif
120 #   ifndef bcopy
121 extern void bcopy ();
122 #   endif
123
124 #  endif /* NeXT. */
125
126 # endif /* USG.  */
127
128 extern char *malloc (), *realloc ();
129 extern void free ();
130
131 #endif /* Standard headers.  */
132
133 #ifndef ANSI_STRING
134 # define memcpy(d, s, n)        bcopy((s), (d), (n))
135 # define memmove memcpy
136 #endif  /* Not ANSI_STRING.  */
137
138 #ifndef MAX
139 # define MAX(a, b) ((a) < (b) ? (b) : (a))
140 #endif
141
142 #ifdef _LIBC
143 # ifndef mempcpy
144 #  define mempcpy __mempcpy
145 # endif
146 # define HAVE_MEMPCPY   1
147 #endif
148
149 #if !defined __alloca && !defined __GNU_LIBRARY__
150
151 # ifdef __GNUC__
152 #  undef alloca
153 #  define alloca(n)     __builtin_alloca (n)
154 # else  /* Not GCC.  */
155 #  if   defined sparc || defined HAVE_ALLOCA_H
156 #   include <alloca.h>
157 #  else /* Not sparc or HAVE_ALLOCA_H.  */
158 #   ifndef _AIX
159 extern char *alloca ();
160 #   endif /* Not _AIX.  */
161 #  endif /* sparc or HAVE_ALLOCA_H.  */
162 # endif /* GCC.  */
163
164 # define __alloca       alloca
165
166 #endif
167
168 #if defined HAVE_LIMITS_H || defined STDC_HEADERS || defined __GNU_LIBRARY__
169 # include <limits.h>
170 #else
171 # include <sys/param.h>
172 #endif
173
174 #if defined _LIBC
175 # include <not-cancel.h>
176 # include <kernel-features.h>
177 #else
178 # define openat64_not_cancel_3(dfd, name, mode) openat64 (dfd, name, mode)
179 # define close_not_cancel_no_status(fd) close (fd)
180 #endif
181
182 #ifndef PATH_MAX
183 # ifdef MAXPATHLEN
184 #  define PATH_MAX MAXPATHLEN
185 # else
186 #  define PATH_MAX 1024
187 # endif
188 #endif
189
190 #if !defined STDC_HEADERS && !defined __GNU_LIBRARY__
191 # undef size_t
192 # define size_t unsigned int
193 #endif
194
195 #ifndef __GNU_LIBRARY__
196 # define __lstat64      stat64
197 #endif
198 \f
199 #ifndef _LIBC
200 # define __getcwd getcwd
201 #endif
202
203 #ifndef GETCWD_RETURN_TYPE
204 # define GETCWD_RETURN_TYPE char *
205 #endif
206
207 #ifdef __ASSUME_ATFCTS
208 # define __have_atfcts 1
209 #elif defined NOT_IN_libc && defined IS_IN_rtld
210 static int __rtld_have_atfcts;
211 # define __have_atfcts __rtld_have_atfcts
212 #endif
213
214 /* Get the pathname of the current working directory, and put it in SIZE
215    bytes of BUF.  Returns NULL if the directory couldn't be determined or
216    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
217    NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
218    unless SIZE == 0, in which case it is as big as necessary.  */
219
220 GETCWD_RETURN_TYPE
221 __getcwd (buf, size)
222      char *buf;
223      size_t size;
224 {
225 #ifndef __ASSUME_ATFCTS
226   static const char dots[]
227     = "../../../../../../../../../../../../../../../../../../../../../../../\
228 ../../../../../../../../../../../../../../../../../../../../../../../../../../\
229 ../../../../../../../../../../../../../../../../../../../../../../../../../..";
230   const char *dotp = &dots[sizeof (dots)];
231   const char *dotlist = dots;
232   size_t dotsize = sizeof (dots) - 1;
233 #endif
234   int prev_errno = errno;
235   DIR *dirstream = NULL;
236   bool fd_needs_closing = false;
237   int fd = AT_FDCWD;
238
239   char *path;
240 #ifndef NO_ALLOCATION
241   size_t allocated = size;
242   if (size == 0)
243     {
244       if (buf != NULL)
245         {
246           __set_errno (EINVAL);
247           return NULL;
248         }
249
250       allocated = PATH_MAX + 1;
251     }
252
253   if (buf == NULL)
254     {
255       path = malloc (allocated);
256       if (path == NULL)
257         return NULL;
258     }
259   else
260 #else
261 # define allocated size
262 #endif
263     path = buf;
264
265   char *pathp = path + allocated;
266   *--pathp = '\0';
267
268   struct stat64 st;
269   if (__lstat64 (".", &st) < 0)
270     goto lose;
271   dev_t thisdev = st.st_dev;
272   ino_t thisino = st.st_ino;
273
274   if (__lstat64 ("/", &st) < 0)
275     goto lose;
276   dev_t rootdev = st.st_dev;
277   ino_t rootino = st.st_ino;
278
279   while (!(thisdev == rootdev && thisino == rootino))
280     {
281       if (__have_atfcts >= 0)
282         {
283           int mode = O_RDONLY;
284 #ifdef O_CLOEXEC
285           mode |= O_CLOEXEC;
286 #endif
287           fd = openat64_not_cancel_3 (fd, "..", mode);
288         }
289       else
290         fd = -1;
291       if (fd >= 0)
292         {
293           fd_needs_closing = true;
294           if (__fstat64 (fd, &st) < 0)
295             goto lose;
296         }
297 #ifndef __ASSUME_ATFCTS
298       else if (errno == ENOSYS)
299         {
300           __have_atfcts = -1;
301
302           /* Look at the parent directory.  */
303           if (dotp == dotlist)
304             {
305 # ifdef NO_ALLOCATION
306               __set_errno (ENOMEM);
307               goto lose;
308 # else
309               /* My, what a deep directory tree you have, Grandma.  */
310               char *new;
311               if (dotlist == dots)
312                 {
313                   new = malloc (dotsize * 2 + 1);
314                   if (new == NULL)
315                     goto lose;
316 #  ifdef HAVE_MEMPCPY
317                   dotp = mempcpy (new, dots, dotsize);
318 #  else
319                   memcpy (new, dots, dotsize);
320                   dotp = &new[dotsize];
321 #  endif
322                 }
323               else
324                 {
325                   new = realloc ((__ptr_t) dotlist, dotsize * 2 + 1);
326                   if (new == NULL)
327                     goto lose;
328                   dotp = &new[dotsize];
329                 }
330 #  ifdef HAVE_MEMPCPY
331               *((char *) mempcpy ((char *) dotp, new, dotsize)) = '\0';
332               dotsize *= 2;
333 #  else
334               memcpy ((char *) dotp, new, dotsize);
335               dotsize *= 2;
336               new[dotsize] = '\0';
337 #  endif
338               dotlist = new;
339 # endif
340             }
341
342           dotp -= 3;
343
344           /* Figure out if this directory is a mount point.  */
345           if (__lstat64 (dotp, &st) < 0)
346             goto lose;
347         }
348 #endif
349       else
350         goto lose;
351
352       if (dirstream && __closedir (dirstream) != 0)
353         {
354           dirstream = NULL;
355           goto lose;
356        }
357
358       dev_t dotdev = st.st_dev;
359       ino_t dotino = st.st_ino;
360       bool mount_point = dotdev != thisdev;
361
362       /* Search for the last directory.  */
363       if (__have_atfcts >= 0)
364         dirstream = __fdopendir (fd);
365 #ifndef __ASSUME_ATFCTS
366       else
367         dirstream = __opendir (dotp);
368 #endif
369       if (dirstream == NULL)
370         goto lose;
371       fd_needs_closing = false;
372
373       struct dirent *d;
374       bool use_d_ino = true;
375       while (1)
376         {
377           /* Clear errno to distinguish EOF from error if readdir returns
378              NULL.  */
379           __set_errno (0);
380           d = __readdir (dirstream);
381           if (d == NULL)
382             {
383               if (errno == 0)
384                 {
385                   /* When we've iterated through all directory entries
386                      without finding one with a matching d_ino, rewind the
387                      stream and consider each name again, but this time, using
388                      lstat64.  This is necessary in a chroot on at least one
389                      system.  */
390                   if (use_d_ino)
391                     {
392                       use_d_ino = false;
393                       rewinddir (dirstream);
394                       continue;
395                     }
396
397                   /* EOF on dirstream, which means that the current directory
398                      has been removed.  */
399                   __set_errno (ENOENT);
400                 }
401               goto lose;
402             }
403
404 #ifdef _DIRENT_HAVE_D_TYPE
405           if (d->d_type != DT_DIR && d->d_type != DT_UNKNOWN)
406             continue;
407 #endif
408           if (d->d_name[0] == '.'
409               && (d->d_name[1] == '\0'
410                   || (d->d_name[1] == '.' && d->d_name[2] == '\0')))
411             continue;
412           if (use_d_ino && !mount_point && (ino_t) d->d_ino != thisino)
413             continue;
414
415           if (__have_atfcts >= 0)
416             {
417               /* We don't fail here if we cannot stat64() a directory entry.
418                  This can happen when (network) filesystems fail.  If this
419                  entry is in fact the one we are looking for we will find
420                  out soon as we reach the end of the directory without
421                  having found anything.  */
422               if (__fstatat64 (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
423                 continue;
424             }
425 #ifndef __ASSUME_ATFCTS
426           else
427             {
428               char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN (d)];
429 # ifdef HAVE_MEMPCPY
430               char *tmp = mempcpy (name, dotp, dotlist + dotsize - dotp);
431               *tmp++ = '/';
432               strcpy (tmp, d->d_name);
433 # else
434               memcpy (name, dotp, dotlist + dotsize - dotp);
435               name[dotlist + dotsize - dotp] = '/';
436               strcpy (&name[dotlist + dotsize - dotp + 1], d->d_name);
437 # endif
438               /* We don't fail here if we cannot stat64() a directory entry.
439                  This can happen when (network) filesystems fail.  If this
440                  entry is in fact the one we are looking for we will find
441                  out soon as we reach the end of the directory without
442                  having found anything.  */
443               if (__lstat64 (name, &st) < 0)
444                 continue;
445             }
446 #endif
447           if (S_ISDIR (st.st_mode)
448               && st.st_dev == thisdev && st.st_ino == thisino)
449             break;
450         }
451
452       size_t namlen = _D_EXACT_NAMLEN (d);
453
454       if ((size_t) (pathp - path) <= namlen)
455         {
456 #ifndef NO_ALLOCATION
457           if (size == 0)
458             {
459               size_t oldsize = allocated;
460
461               allocated = 2 * MAX (allocated, namlen);
462               char *tmp = realloc (path, allocated);
463               if (tmp == NULL)
464                 goto lose;
465
466               /* Move current contents up to the end of the buffer.
467                  This is guaranteed to be non-overlapping.  */
468               pathp = memcpy (tmp + allocated - (path + oldsize - pathp),
469                               tmp + (pathp - path),
470                               path + oldsize - pathp);
471               path = tmp;
472             }
473           else
474 #endif
475             {
476               __set_errno (ERANGE);
477               goto lose;
478             }
479         }
480       pathp -= namlen;
481       (void) memcpy (pathp, d->d_name, namlen);
482       *--pathp = '/';
483
484       thisdev = dotdev;
485       thisino = dotino;
486     }
487
488   if (dirstream != NULL && __closedir (dirstream) != 0)
489     {
490       dirstream = NULL;
491       goto lose;
492     }
493
494   if (pathp == &path[allocated - 1])
495     *--pathp = '/';
496
497 #ifndef __ASSUME_ATFCTS
498   if (dotlist != dots)
499     free ((__ptr_t) dotlist);
500 #endif
501
502   size_t used = path + allocated - pathp;
503   memmove (path, pathp, used);
504
505   if (size == 0)
506     /* Ensure that the buffer is only as large as necessary.  */
507     buf = realloc (path, used);
508
509   if (buf == NULL)
510     /* Either buf was NULL all along, or `realloc' failed but
511        we still have the original string.  */
512     buf = path;
513
514   /* Restore errno on successful return.  */
515   __set_errno (prev_errno);
516
517   return buf;
518
519  lose:;
520   int save_errno = errno;
521 #ifndef __ASSUME_ATFCTS
522   if (dotlist != dots)
523     free ((__ptr_t) dotlist);
524 #endif
525   if (dirstream != NULL)
526     __closedir (dirstream);
527   if (fd_needs_closing)
528     close_not_cancel_no_status (fd);
529 #ifndef NO_ALLOCATION
530   if (buf == NULL)
531     free (path);
532 #endif
533   __set_errno (save_errno);
534   return NULL;
535 }
536
537 #if defined _LIBC && !defined __getcwd
538 weak_alias (__getcwd, getcwd)
539 #endif