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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11934
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
3
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
7 (at your option) any later version.
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
8
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
12 GNU General Public License for more details.
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
13
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
16
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
17 /* written by Jim Meyering */
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
18
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
19 #include <config.h>
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
20
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
21 #include <dirent.h>
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
22
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
23 #include <stdlib.h>
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
24 #include <unistd.h>
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
25
12127
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
26 #if !HAVE_FDOPENDIR
11934
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
27
12127
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
28 # include "openat.h"
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
29 # include "openat-priv.h"
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
30 # include "save-cwd.h"
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
31
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
32 # if GNULIB_DIRENT_SAFER
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
33 # include "dirent--.h"
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
34 # endif
11936
a126d5b22410 dirent-safer: new module
Eric Blake <ebb9@byu.net>
parents: 11935
diff changeset
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
d233b3d8efbf fdopendir: optimize on mingw
Eric Blake <ebb9@byu.net>
parents: 11934
diff changeset
46 that, simulate it by using fchdir metadata, or by doing
d233b3d8efbf fdopendir: optimize on mingw
Eric Blake <ebb9@byu.net>
parents: 11934
diff changeset
47 save_cwd/fchdir/opendir(".")/restore_cwd.
11934
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
48 If either the save_cwd or the restore_cwd fails (relatively unlikely),
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
58
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
65 DIR *
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
66 fdopendir (int fd)
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
164 }
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
165 else
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
166 {
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
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
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
178 }
80567a8f98f8 fdopendir: split into its own module
Eric Blake <ebb9@byu.net>
parents:
diff changeset
179 }
12127
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
180
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
181 #else /* HAVE_FDOPENDIR */
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
182
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
183 # include <errno.h>
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
184 # include <sys/stat.h>
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
185
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
186 # undef fdopendir
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
187
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
188 /* Like fdopendir, but work around GNU/Hurd bug by validating FD. */
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
189
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
190 DIR *
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
191 rpl_fdopendir (int fd)
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
192 {
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
193 struct stat st;
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
194 if (fstat (fd, &st))
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
195 return NULL;
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
196 if (!S_ISDIR (st.st_mode))
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
197 {
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
198 errno = ENOTDIR;
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
199 return NULL;
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
200 }
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
201 return fdopendir (fd);
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
202 }
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
203
bda9467a9d66 fdopendir: fix GNU/Hurd bug
Eric Blake <ebb9@byu.net>
parents: 11936
diff changeset
204 #endif /* HAVE_FDOPENDIR */