Mercurial > gnulib
annotate lib/getcwd.c @ 17335:840c32a600aa
getcwd: support coreutils better
Like strtod, getcwd incorrectly referred to HAVE_RAW_DECL_GETCWD,
but this might not be correct in coreutils, which disables
the raw decl checks. Problem reported by Nagendra in
<http://bugs.gnu.org/10305#192>.
* lib/getcwd.c (__getcwd): Do not depend on HAVE_RAW_DECL_GETCWD.
* m4/getcwd-path-max.m4 (gl_FUNC_GETCWD_PATH_MAX):
Test the getcwd function, not any macro, since getcwd.c wants the
function.
* m4/getcwd.m4 (gl_FUNC_GETCWD):
Don't define HAVE_MINIMALLY_WORKING_GETCWD if the code doesn't
compile, as might happen if there's a macro but no function.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Wed, 20 Feb 2013 00:04:35 -0800 |
parents | ab5135d5ff83 |
children | 344018b6e5d7 |
rev | line source |
---|---|
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16235
diff
changeset
|
1 /* Copyright (C) 1991-1999, 2004-2013 Free Software Foundation, Inc. |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
2 This file is part of the GNU C Library. |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
3 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8474
diff
changeset
|
4 This program is free software: you can redistribute it and/or modify |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
5 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8474
diff
changeset
|
6 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8474
diff
changeset
|
7 (at your option) any later version. |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
8 |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
9 This program is distributed in the hope that it will be useful, |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
12 GNU General Public License for more details. |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
13 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8474
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8474
diff
changeset
|
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
16 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6949
diff
changeset
|
17 #if !_LIBC |
6259
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5955
diff
changeset
|
18 # include <config.h> |
8199
51d32a83a7df
Move more declarations into <unistd.h>.
Bruno Haible <bruno@clisp.org>
parents:
8075
diff
changeset
|
19 # include <unistd.h> |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
20 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
21 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
22 #include <errno.h> |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
23 #include <sys/types.h> |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
24 #include <sys/stat.h> |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
25 #include <stdbool.h> |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
26 #include <stddef.h> |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
27 |
5955
ace6ea191424
Assume HAVE_FCNTL_H (i.e., include <fcntl.h> unconditionally,
Jim Meyering <jim@meyering.net>
parents:
5907
diff
changeset
|
28 #include <fcntl.h> /* For AT_FDCWD on Solaris 9. */ |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
29 |
15661
0aac3aa8d8fd
getcwd: don't fail in a deep directory on a system without openat
Jim Meyering <meyering@redhat.com>
parents:
15522
diff
changeset
|
30 /* If this host provides the openat function or if we're using the |
17311
ab5135d5ff83
getcwd: break fdopendir + save_cwd recursive loop (Bug#13516)
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
31 gnulib replacement function with a native fdopendir, then enable |
ab5135d5ff83
getcwd: break fdopendir + save_cwd recursive loop (Bug#13516)
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
32 code below to make getcwd more efficient and robust. */ |
ab5135d5ff83
getcwd: break fdopendir + save_cwd recursive loop (Bug#13516)
Paul Eggert <eggert@cs.ucla.edu>
parents:
17249
diff
changeset
|
33 #if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR) |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
34 # define HAVE_OPENAT_SUPPORT 1 |
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
35 #else |
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
36 # define HAVE_OPENAT_SUPPORT 0 |
9534
36c5c8024476
Port to GNU/kFreeBSD - FreeBSD kernel + GNU libc,
Jim Meyering <meyering@redhat.com>
parents:
9353
diff
changeset
|
37 #endif |
36c5c8024476
Port to GNU/kFreeBSD - FreeBSD kernel + GNU libc,
Jim Meyering <meyering@redhat.com>
parents:
9353
diff
changeset
|
38 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
39 #ifndef __set_errno |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
40 # define __set_errno(val) (errno = (val)) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
41 #endif |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
42 |
6949
96af1224c6fa
* backupfile.c, dirfd.h, fts.c, getcwd.c, glob.c, glob_.h:
Paul Eggert <eggert@cs.ucla.edu>
parents:
6934
diff
changeset
|
43 #include <dirent.h> |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
44 #ifndef _D_EXACT_NAMLEN |
6934
d68ff786c180
* lib/getloadavg.c: Use __VMS, not VMS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6912
diff
changeset
|
45 # define _D_EXACT_NAMLEN(d) strlen ((d)->d_name) |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
46 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
47 #ifndef _D_ALLOC_NAMLEN |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
48 # define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
49 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
50 |
6275 | 51 #include <unistd.h> |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
52 #include <stdlib.h> |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
53 #include <string.h> |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
54 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
55 #if _LIBC |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
56 # ifndef mempcpy |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
57 # define mempcpy __mempcpy |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
58 # endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
59 #endif |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
60 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
61 #ifndef MAX |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
62 # define MAX(a, b) ((a) < (b) ? (b) : (a)) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
63 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
64 #ifndef MIN |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
65 # define MIN(a, b) ((a) < (b) ? (a) : (b)) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
66 #endif |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
67 |
15496
451ec8bd8a1c
pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
68 #include "pathmax.h" |
451ec8bd8a1c
pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
69 |
451ec8bd8a1c
pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
70 /* In this file, PATH_MAX only serves as a threshold for choosing among two |
451ec8bd8a1c
pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
71 algorithms. */ |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
72 #ifndef PATH_MAX |
15496
451ec8bd8a1c
pathmax: Leave PATH_MAX undefined on the Hurd, and a constant otherwise.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
73 # define PATH_MAX 8192 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
74 #endif |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
75 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
76 #if D_INO_IN_DIRENT |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
77 # define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino)) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
78 #else |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
79 # define MATCHING_INO(dp, ino) true |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
80 #endif |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
81 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
82 #if !_LIBC |
9353
20db465217b4
Use rpl_ prefix for functions, so as to avoid endless recursions in weird cases.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
83 # define __getcwd rpl_getcwd |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
84 # define __lstat lstat |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
85 # define __closedir closedir |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
86 # define __opendir opendir |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
87 # define __readdir readdir |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
88 #endif |
7863 | 89 |
90 /* The results of opendir() in this file are not used with dirfd and fchdir, | |
11938
7cbcde229d97
backupfile, chdir-long, fts, savedir: make safer
Eric Blake <ebb9@byu.net>
parents:
10663
diff
changeset
|
91 and we do not leak fds to any single-threaded code that could use stdio, |
7cbcde229d97
backupfile, chdir-long, fts, savedir: make safer
Eric Blake <ebb9@byu.net>
parents:
10663
diff
changeset
|
92 therefore save some unnecessary recursion in fchdir.c. |
7cbcde229d97
backupfile, chdir-long, fts, savedir: make safer
Eric Blake <ebb9@byu.net>
parents:
10663
diff
changeset
|
93 FIXME - if the kernel ever adds support for multi-thread safety for |
7cbcde229d97
backupfile, chdir-long, fts, savedir: make safer
Eric Blake <ebb9@byu.net>
parents:
10663
diff
changeset
|
94 avoiding standard fds, then we should use opendir_safer and |
7cbcde229d97
backupfile, chdir-long, fts, savedir: make safer
Eric Blake <ebb9@byu.net>
parents:
10663
diff
changeset
|
95 openat_safer. */ |
7863 | 96 #undef opendir |
97 #undef closedir | |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
98 |
5907 | 99 /* Get the name of the current working directory, and put it in SIZE |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
100 bytes of BUF. Returns NULL if the directory couldn't be determined or |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
101 SIZE was too small. If successful, returns BUF. In GNU, if BUF is |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
102 NULL, an array is allocated with 'malloc'; the array is SIZE bytes long, |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
103 unless SIZE == 0, in which case it is as big as necessary. */ |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
104 |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
105 char * |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
106 __getcwd (char *buf, size_t size) |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
107 { |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
108 /* Lengths of big file name components and entire file names, and a |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
109 deep level of file name nesting. These numbers are not upper |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
110 bounds; they are merely large values suitable for initial |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
111 allocations, designed to be large enough for most real-world |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
112 uses. */ |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
113 enum |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
114 { |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
115 BIG_FILE_NAME_COMPONENT_LENGTH = 255, |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
116 BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1), |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
117 DEEP_NESTING = 100 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
118 }; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
119 |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
120 #if HAVE_OPENAT_SUPPORT |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
121 int fd = AT_FDCWD; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
122 bool fd_needs_closing = false; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
123 #else |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
124 char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1]; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
125 char *dotlist = dots; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
126 size_t dotsize = sizeof dots; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
127 size_t dotlen = 0; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
128 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
129 DIR *dirstream = NULL; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
130 dev_t rootdev, thisdev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
131 ino_t rootino, thisino; |
5907 | 132 char *dir; |
133 register char *dirp; | |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
134 struct stat st; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
135 size_t allocated = size; |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
136 size_t used; |
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
137 |
17335
840c32a600aa
getcwd: support coreutils better
Paul Eggert <eggert@cs.ucla.edu>
parents:
17311
diff
changeset
|
138 #if HAVE_MINIMALLY_WORKING_GETCWD |
13468
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
139 /* If AT_FDCWD is not defined, the algorithm below is O(N**2) and |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
140 this is much slower than the system getcwd (at least on |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
141 GNU/Linux). So trust the system getcwd's results unless they |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
142 look suspicious. |
8217
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
143 |
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
144 Use the system getcwd even if we have openat support, since the |
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
145 system getcwd works even when a parent is unreadable, while the |
16113
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
146 openat-based approach does not. |
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
147 |
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
148 But on AIX 5.1..7.1, the system getcwd is not even minimally |
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
149 working: If the current directory name is slightly longer than |
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
150 PATH_MAX, it omits the first directory component and returns |
80ff47677300
getcwd: Work around getcwd bug on AIX 5..7.
Bruno Haible <bruno@clisp.org>
parents:
15661
diff
changeset
|
151 this wrong result with errno = 0. */ |
8217
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
152 |
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
153 # undef getcwd |
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
154 dir = getcwd (buf, size); |
15522
0c9c512b8944
getcwd: fix test failures on mingw
Eric Blake <eblake@redhat.com>
parents:
15496
diff
changeset
|
155 if (dir || (size && errno == ERANGE)) |
8217
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
156 return dir; |
13468
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
157 |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
158 /* Solaris getcwd (NULL, 0) fails with errno == EINVAL, but it has |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
159 internal magic that lets it work even if an ancestor directory is |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
160 inaccessible, which is better in many cases. So in this case try |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
161 again with a buffer that's almost always big enough. */ |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
162 if (errno == EINVAL && buf == NULL && size == 0) |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
163 { |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
164 char big_buffer[BIG_FILE_NAME_LENGTH + 1]; |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
165 dir = getcwd (big_buffer, sizeof big_buffer); |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
166 if (dir) |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
167 return strdup (dir); |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
168 } |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
169 |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
170 # if HAVE_PARTLY_WORKING_GETCWD |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
171 /* The system getcwd works, except it sometimes fails when it |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
172 shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. */ |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
173 if (errno != ERANGE && errno != ENAMETOOLONG && errno != ENOENT) |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
174 return NULL; |
df8d11635b39
getcwd: on Solaris, work better if ancestors are inaccessible
Paul R. Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
175 # endif |
8217
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
176 #endif |
f43bac5db7d2
* lib/getcwd.c (__getcwd): Undo previous change; it mishandled
Paul Eggert <eggert@cs.ucla.edu>
parents:
8216
diff
changeset
|
177 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
178 if (size == 0) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
179 { |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
180 if (buf != NULL) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
181 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
182 __set_errno (EINVAL); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
183 return NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
184 } |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
185 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
186 allocated = BIG_FILE_NAME_LENGTH + 1; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
187 } |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
188 |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
189 if (buf == NULL) |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
190 { |
5907 | 191 dir = malloc (allocated); |
192 if (dir == NULL) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
193 return NULL; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
194 } |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
195 else |
5907 | 196 dir = buf; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
197 |
5907 | 198 dirp = dir + allocated; |
199 *--dirp = '\0'; | |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
200 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
201 if (__lstat (".", &st) < 0) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
202 goto lose; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
203 thisdev = st.st_dev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
204 thisino = st.st_ino; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
205 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
206 if (__lstat ("/", &st) < 0) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
207 goto lose; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
208 rootdev = st.st_dev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
209 rootino = st.st_ino; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
210 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
211 while (!(thisdev == rootdev && thisino == rootino)) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
212 { |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
213 struct dirent *d; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
214 dev_t dotdev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
215 ino_t dotino; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
216 bool mount_point; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
217 int parent_status; |
6439
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
218 size_t dirroom; |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
219 size_t namlen; |
6912 | 220 bool use_d_ino = true; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
221 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
222 /* Look at the parent directory. */ |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
223 #if HAVE_OPENAT_SUPPORT |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
224 fd = openat (fd, "..", O_RDONLY); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
225 if (fd < 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
226 goto lose; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
227 fd_needs_closing = true; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
228 parent_status = fstat (fd, &st); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
229 #else |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
230 dotlist[dotlen++] = '.'; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
231 dotlist[dotlen++] = '.'; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
232 dotlist[dotlen] = '\0'; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
233 parent_status = __lstat (dotlist, &st); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
234 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
235 if (parent_status != 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
236 goto lose; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
237 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
238 if (dirstream && __closedir (dirstream) != 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
239 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
240 dirstream = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
241 goto lose; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
242 } |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
243 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
244 /* Figure out if this directory is a mount point. */ |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
245 dotdev = st.st_dev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
246 dotino = st.st_ino; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
247 mount_point = dotdev != thisdev; |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
248 |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
249 /* Search for the last directory. */ |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
250 #if HAVE_OPENAT_SUPPORT |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
251 dirstream = fdopendir (fd); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
252 if (dirstream == NULL) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
253 goto lose; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
254 fd_needs_closing = false; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
255 #else |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
256 dirstream = __opendir (dotlist); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
257 if (dirstream == NULL) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
258 goto lose; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
259 dotlist[dotlen++] = '/'; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
260 #endif |
6439
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
261 for (;;) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
262 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
263 /* Clear errno to distinguish EOF from error if readdir returns |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
264 NULL. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
265 __set_errno (0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
266 d = __readdir (dirstream); |
6912 | 267 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
268 /* When we've iterated through all directory entries without finding |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
269 one with a matching d_ino, rewind the stream and consider each |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
270 name again, but this time, using lstat. This is necessary in a |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
271 chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
272 .., ../.., ../../.., etc. all had the same device number, yet the |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
273 d_ino values for entries in / did not match those obtained |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
274 via lstat. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
275 if (d == NULL && errno == 0 && use_d_ino) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
276 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
277 use_d_ino = false; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
278 rewinddir (dirstream); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
279 d = __readdir (dirstream); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
280 } |
6912 | 281 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
282 if (d == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
283 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
284 if (errno == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
285 /* EOF on dirstream, which can mean e.g., that the current |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
286 directory has been removed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
287 __set_errno (ENOENT); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
288 goto lose; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
289 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
290 if (d->d_name[0] == '.' && |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
291 (d->d_name[1] == '\0' || |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
292 (d->d_name[1] == '.' && d->d_name[2] == '\0'))) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
293 continue; |
6912 | 294 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
295 if (use_d_ino) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
296 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
297 bool match = (MATCHING_INO (d, thisino) || mount_point); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
298 if (! match) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
299 continue; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
300 } |
6912 | 301 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
302 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
303 int entry_status; |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
304 #if HAVE_OPENAT_SUPPORT |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
305 entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
306 #else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
307 /* Compute size needed for this file name, or for the file |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
308 name ".." in the same directory, whichever is larger. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
309 Room for ".." might be needed the next time through |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
310 the outer loop. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
311 size_t name_alloc = _D_ALLOC_NAMLEN (d); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
312 size_t filesize = dotlen + MAX (sizeof "..", name_alloc); |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
313 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
314 if (filesize < dotlen) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
315 goto memory_exhausted; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
316 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
317 if (dotsize < filesize) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
318 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
319 /* My, what a deep directory tree you have, Grandma. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
320 size_t newsize = MAX (filesize, dotsize * 2); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
321 size_t i; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
322 if (newsize < dotsize) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
323 goto memory_exhausted; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
324 if (dotlist != dots) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
325 free (dotlist); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
326 dotlist = malloc (newsize); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
327 if (dotlist == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
328 goto lose; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
329 dotsize = newsize; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
330 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
331 i = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
332 do |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
333 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
334 dotlist[i++] = '.'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
335 dotlist[i++] = '.'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
336 dotlist[i++] = '/'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
337 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
338 while (i < dotlen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
339 } |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
340 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
341 memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
342 entry_status = __lstat (dotlist, &st); |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
343 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
344 /* We don't fail here if we cannot stat() a directory entry. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
345 This can happen when (network) file systems fail. If this |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
346 entry is in fact the one we are looking for we will find |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
347 out soon as we reach the end of the directory without |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
348 having found anything. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
349 if (entry_status == 0 && S_ISDIR (st.st_mode) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
350 && st.st_dev == thisdev && st.st_ino == thisino) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
351 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
352 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
353 } |
6439
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
354 |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
355 dirroom = dirp - dir; |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
356 namlen = _D_EXACT_NAMLEN (d); |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
357 |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
358 if (dirroom <= namlen) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
359 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
360 if (size != 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
361 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
362 __set_errno (ERANGE); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
363 goto lose; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
364 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
365 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
366 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
367 char *tmp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
368 size_t oldsize = allocated; |
6439
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
369 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
370 allocated += MAX (allocated, namlen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
371 if (allocated < oldsize |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
372 || ! (tmp = realloc (dir, allocated))) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
373 goto memory_exhausted; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
374 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
375 /* Move current contents up to the end of the buffer. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
376 This is guaranteed to be non-overlapping. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
377 dirp = memcpy (tmp + allocated - (oldsize - dirroom), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
378 tmp + dirroom, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
379 oldsize - dirroom); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
380 dir = tmp; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
381 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11970
diff
changeset
|
382 } |
6439
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
383 dirp -= namlen; |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
384 memcpy (dirp, d->d_name, namlen); |
3fd547210013
* getcwd.c (__getcwd): Don't assume that system calls after readdir
Paul Eggert <eggert@cs.ucla.edu>
parents:
6305
diff
changeset
|
385 *--dirp = '/'; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
386 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
387 thisdev = dotdev; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
388 thisino = dotino; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
389 } |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
390 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
391 if (dirstream && __closedir (dirstream) != 0) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
392 { |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
393 dirstream = NULL; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
394 goto lose; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
395 } |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
396 |
5907 | 397 if (dirp == &dir[allocated - 1]) |
398 *--dirp = '/'; | |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
399 |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
400 #if ! HAVE_OPENAT_SUPPORT |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
401 if (dotlist != dots) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
402 free (dotlist); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
403 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
404 |
5907 | 405 used = dir + allocated - dirp; |
406 memmove (dir, dirp, used); | |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
407 |
8474
11ae25a37675
* lib/getcwd.c (__getcwd): Remove redundant comparison of buf to NULL.
Paul Eggert <eggert@cs.ucla.edu>
parents:
8217
diff
changeset
|
408 if (size == 0) |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
409 /* Ensure that the buffer is only as large as necessary. */ |
5907 | 410 buf = realloc (dir, used); |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
411 |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
412 if (buf == NULL) |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
413 /* Either buf was NULL all along, or 'realloc' failed but |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
414 we still have the original string. */ |
5907 | 415 buf = dir; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
416 |
5499
41fd04e6a198
(is_ENAMETOOLONG): New macro.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5491
diff
changeset
|
417 return buf; |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
418 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
419 memory_exhausted: |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
420 __set_errno (ENOMEM); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
421 lose: |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
422 { |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
423 int save = errno; |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
424 if (dirstream) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
425 __closedir (dirstream); |
9535
fdfe023323f5
getcwd.c: Use a more readable witness: HAVE_OPENAT_SUPPORT
Petr Salinger <Petr.Salinger@seznam.cz>
parents:
9534
diff
changeset
|
426 #if HAVE_OPENAT_SUPPORT |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
427 if (fd_needs_closing) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
428 close (fd); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
429 #else |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
430 if (dotlist != dots) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
431 free (dotlist); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
432 #endif |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
433 if (buf == NULL) |
5907 | 434 free (dir); |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
435 __set_errno (save); |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
436 } |
5136
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
437 return NULL; |
3d7c80bdf362
New getcwd module, imported from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
438 } |
5491
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
439 |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
440 #ifdef weak_alias |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
441 weak_alias (__getcwd, getcwd) |
b3d5c90efc81
Merge from coreutils for getcwd and HP-UX 11.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5136
diff
changeset
|
442 #endif |