Mercurial > hg > octave-kai > gnulib-hg
annotate lib/fdopendir.c @ 17342:c75939cb6254
merge with default branch
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Thu, 21 Feb 2013 14:57:31 +0000 |
parents | e542fd46ad6f |
children |
rev | line source |
---|---|
11934 | 1 /* provide a replacement fdopendir function |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16201
diff
changeset
|
2 Copyright (C) 2004-2013 Free Software Foundation, Inc. |
11934 | 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 <http://www.gnu.org/licenses/>. */ | |
16 | |
17 /* written by Jim Meyering */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <dirent.h> | |
22 | |
23 #include <stdlib.h> | |
24 #include <unistd.h> | |
25 | |
12127 | 26 #if !HAVE_FDOPENDIR |
11934 | 27 |
12127 | 28 # include "openat.h" |
29 # include "openat-priv.h" | |
30 # include "save-cwd.h" | |
31 | |
32 # if GNULIB_DIRENT_SAFER | |
33 # include "dirent--.h" | |
34 # endif | |
11936 | 35 |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
36 # ifndef REPLACE_FCHDIR |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
37 # define REPLACE_FCHDIR 0 |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
38 # endif |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
39 |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
40 static DIR *fdopendir_with_dup (int, int, struct saved_cwd const *); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
41 static DIR *fd_clone_opendir (int, struct saved_cwd const *); |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
42 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
43 /* Replacement for POSIX fdopendir. |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
44 |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
45 First, try to simulate it via opendir ("/proc/self/fd/..."). Failing |
11935 | 46 that, simulate it by using fchdir metadata, or by doing |
47 save_cwd/fchdir/opendir(".")/restore_cwd. | |
11934 | 48 If either the save_cwd or the restore_cwd fails (relatively unlikely), |
49 then give a diagnostic and exit nonzero. | |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
50 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
51 If successful, the resulting stream is based on FD in |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
52 implementations where streams are based on file descriptors and in |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
53 applications where no other thread or signal handler allocates or |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
54 frees file descriptors. In other cases, consult dirfd on the result |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
55 to find out whether FD is still being used. |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
56 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
57 Otherwise, this function works just like POSIX fdopendir. |
11934 | 58 |
59 W A R N I N G: | |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
60 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
61 Unlike other fd-related functions, this one places constraints on FD. |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
62 If this function returns successfully, FD is under control of the |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
63 dirent.h system, and the caller should not close or modify the state of |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
64 FD other than by the dirent.h functions. */ |
11934 | 65 DIR * |
66 fdopendir (int fd) | |
67 { | |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
68 DIR *dir = fdopendir_with_dup (fd, -1, NULL); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
69 |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
70 if (! REPLACE_FCHDIR && ! dir) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
71 { |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
72 int saved_errno = errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
73 if (EXPECTED_ERRNO (saved_errno)) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
74 { |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
75 struct saved_cwd cwd; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
76 if (save_cwd (&cwd) != 0) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
77 openat_save_fail (errno); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
78 dir = fdopendir_with_dup (fd, -1, &cwd); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
79 saved_errno = errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
80 free_cwd (&cwd); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
81 errno = saved_errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
82 } |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
83 } |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
84 |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
85 return dir; |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
86 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
87 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
88 /* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
89 to be a dup of FD which is less than FD - 1 and which will be |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
90 closed by the caller and not otherwise used by the caller. This |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
91 function makes sure that FD is closed and all file descriptors less |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
92 than FD are open, and then calls fd_clone_opendir on a dup of FD. |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
93 That way, barring race conditions, fd_clone_opendir returns a |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
94 stream whose file descriptor is FD. |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
95 |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
96 If REPLACE_CHDIR or CWD is null, use opendir ("/proc/self/fd/...", |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
97 falling back on fchdir metadata. Otherwise, CWD is a saved version |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
98 of the working directory; use fchdir/opendir(".")/restore_cwd(CWD). */ |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
99 static DIR * |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
100 fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd) |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
101 { |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
102 int dupfd = dup (fd); |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
103 if (dupfd < 0 && errno == EMFILE) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
104 dupfd = older_dupfd; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
105 if (dupfd < 0) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
106 return NULL; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
107 else |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
108 { |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
109 DIR *dir; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
110 int saved_errno; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
111 if (dupfd < fd - 1 && dupfd != older_dupfd) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
112 { |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
113 dir = fdopendir_with_dup (fd, dupfd, cwd); |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
114 saved_errno = errno; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
115 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
116 else |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
117 { |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
118 close (fd); |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
119 dir = fd_clone_opendir (dupfd, cwd); |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
120 saved_errno = errno; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
121 if (! dir) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
122 { |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
123 int fd1 = dup (dupfd); |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
124 if (fd1 != fd) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
125 openat_save_fail (fd1 < 0 ? errno : EBADF); |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
126 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
127 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
128 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
129 if (dupfd != older_dupfd) |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
130 close (dupfd); |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
131 errno = saved_errno; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
132 return dir; |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
133 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
134 } |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
135 |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
136 /* Like fdopendir, except the result controls a clone of FD. It is |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
137 the caller's responsibility both to close FD and (if the result is |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
138 not null) to closedir the result. */ |
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
139 static DIR * |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
140 fd_clone_opendir (int fd, struct saved_cwd const *cwd) |
13673
8a0919c1c14c
fdopendir: preserve argument fd before returning
Paul Eggert <eggert@cs.ucla.edu>
parents:
12559
diff
changeset
|
141 { |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
142 if (REPLACE_FCHDIR || ! cwd) |
11934 | 143 { |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
144 DIR *dir = NULL; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
145 int saved_errno = EOPNOTSUPP; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
146 char buf[OPENAT_BUFFER_SIZE]; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
147 char *proc_file = openat_proc_name (buf, fd, "."); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
148 if (proc_file) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
149 { |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
150 dir = opendir (proc_file); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
151 saved_errno = errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
152 if (proc_file != buf) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
153 free (proc_file); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
154 } |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
155 # if REPLACE_FCHDIR |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
156 if (! dir && EXPECTED_ERRNO (saved_errno)) |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
157 { |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
158 char const *name = _gl_directory_name (fd); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
159 return (name ? opendir (name) : NULL); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
160 } |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
161 # endif |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
162 errno = saved_errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
163 return dir; |
11934 | 164 } |
165 else | |
166 { | |
167 if (fchdir (fd) != 0) | |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
168 return NULL; |
11934 | 169 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12127
diff
changeset
|
170 { |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
171 DIR *dir = opendir ("."); |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
172 int saved_errno = errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
173 if (restore_cwd (cwd) != 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12127
diff
changeset
|
174 openat_restore_fail (errno); |
13842
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
175 errno = saved_errno; |
eee91e173fad
fdopendir: fix bug on MacOS X when low on file descriptors
Paul Eggert <eggert@cs.ucla.edu>
parents:
13825
diff
changeset
|
176 return dir; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12127
diff
changeset
|
177 } |
11934 | 178 } |
179 } | |
12127 | 180 |
181 #else /* HAVE_FDOPENDIR */ | |
182 | |
183 # include <errno.h> | |
184 # include <sys/stat.h> | |
185 | |
186 # undef fdopendir | |
187 | |
188 /* Like fdopendir, but work around GNU/Hurd bug by validating FD. */ | |
189 | |
190 DIR * | |
191 rpl_fdopendir (int fd) | |
192 { | |
193 struct stat st; | |
194 if (fstat (fd, &st)) | |
195 return NULL; | |
196 if (!S_ISDIR (st.st_mode)) | |
197 { | |
198 errno = ENOTDIR; | |
199 return NULL; | |
200 } | |
201 return fdopendir (fd); | |
202 } | |
203 | |
204 #endif /* HAVE_FDOPENDIR */ |