Mercurial > hg > octave-lojdl > gnulib-hg
annotate lib/openat.c @ 7017:005fe24b840a
Update javaexec module from GNU gettext 0.15.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sat, 22 Jul 2006 15:17:55 +0000 |
parents | d65bd1fc3298 |
children | 43e3888c56c4 |
rev | line source |
---|---|
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
1 /* provide a replacement openat function |
6847 | 2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
3 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
4 This program is free software; you can redistribute it and/or modify |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
5 it under the terms of the GNU General Public License as published by |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
6 the Free Software Foundation; either version 2, or (at your option) |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
7 any later version. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
8 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
9 This program is distributed in the hope that it will be useful, |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
12 GNU General Public License for more details. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
13 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
15 along with this program; if not, write to the Free Software Foundation, |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
5609
diff
changeset
|
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
17 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
18 /* written by Jim Meyering */ |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
19 |
6259
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5907
diff
changeset
|
20 #ifdef HAVE_CONFIG_H |
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5907
diff
changeset
|
21 # include <config.h> |
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5907
diff
changeset
|
22 #endif |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
23 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
24 #include "openat.h" |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
25 |
6527 | 26 #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ |
27 #include "fcntl--.h" | |
28 #include "openat-priv.h" | |
29 #include "save-cwd.h" | |
30 #include "unistd--.h" | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
31 |
6527 | 32 #include <stdarg.h> |
33 #include <stddef.h> | |
34 #include <errno.h> | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
35 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
36 /* Replacement for Solaris' openat function. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
37 <http://www.google.com/search?q=openat+site:docs.sun.com> |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
38 Simulate it by doing save_cwd/fchdir/open/restore_cwd. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
39 If either the save_cwd or the restore_cwd fails (relatively unlikely, |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
40 and usually indicative of a problem that deserves close attention), |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
41 then give a diagnostic and exit nonzero. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
42 Otherwise, upon failure, set errno and return -1, as openat does. |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
43 Upon successful completion, return a file descriptor. */ |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
44 int |
6527 | 45 openat (int fd, char const *file, int flags, ...) |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
46 { |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
47 mode_t mode = 0; |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
48 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
49 if (flags & O_CREAT) |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
50 { |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
51 va_list arg; |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
52 va_start (arg, flags); |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
53 |
6527 | 54 /* If mode_t is narrower than int, use the promoted type (int), |
6846 | 55 not mode_t. Use sizeof to guess whether mode_t is narrower; |
6527 | 56 we don't know of any practical counterexamples. */ |
6845
287876ed7ba2
* openat.c (openat): Use ?:, not if, to work around GCC bug 4210
Paul Eggert <eggert@cs.ucla.edu>
parents:
6527
diff
changeset
|
57 mode = (sizeof (mode_t) < sizeof (int) |
287876ed7ba2
* openat.c (openat): Use ?:, not if, to work around GCC bug 4210
Paul Eggert <eggert@cs.ucla.edu>
parents:
6527
diff
changeset
|
58 ? va_arg (arg, int) |
287876ed7ba2
* openat.c (openat): Use ?:, not if, to work around GCC bug 4210
Paul Eggert <eggert@cs.ucla.edu>
parents:
6527
diff
changeset
|
59 : va_arg (arg, mode_t)); |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
60 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
61 va_end (arg); |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
62 } |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
63 |
6527 | 64 return openat_permissive (fd, file, flags, mode, NULL); |
65 } | |
66 | |
67 /* Like openat (FD, FILE, FLAGS, MODE), but if CWD_ERRNO is | |
68 nonnull, set *CWD_ERRNO to an errno value if unable to save | |
69 or restore the initial working directory. This is needed only | |
70 the first time remove.c's remove_dir opens a command-line | |
71 directory argument. | |
72 | |
73 If a previous attempt to restore the current working directory | |
74 failed, then we must not even try to access a `.'-relative name. | |
75 It is the caller's responsibility not to call this function | |
76 in that case. */ | |
77 | |
78 int | |
79 openat_permissive (int fd, char const *file, int flags, mode_t mode, | |
80 int *cwd_errno) | |
81 { | |
82 struct saved_cwd saved_cwd; | |
83 int saved_errno; | |
84 int err; | |
85 bool save_ok; | |
86 | |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
87 if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) |
5907 | 88 return open (file, flags, mode); |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
89 |
6527 | 90 { |
91 char *proc_file; | |
92 BUILD_PROC_NAME (proc_file, fd, file); | |
93 err = open (proc_file, flags, mode); | |
94 /* If the syscall succeeds, or if it fails with an unexpected | |
95 errno value, then return right away. Otherwise, fall through | |
96 and resort to using save_cwd/restore_cwd. */ | |
97 if (0 <= err || ! EXPECTED_ERRNO (errno)) | |
98 return err; | |
99 } | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
100 |
6527 | 101 save_ok = (save_cwd (&saved_cwd) == 0); |
102 if (! save_ok) | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
103 { |
6527 | 104 if (! cwd_errno) |
105 openat_save_fail (errno); | |
106 *cwd_errno = errno; | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
107 } |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
108 |
6527 | 109 err = fchdir (fd); |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
110 saved_errno = errno; |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
111 |
6527 | 112 if (! err) |
113 { | |
114 err = open (file, flags, mode); | |
115 saved_errno = errno; | |
116 if (save_ok && restore_cwd (&saved_cwd) != 0) | |
117 { | |
118 if (! cwd_errno) | |
119 openat_restore_fail (errno); | |
120 *cwd_errno = errno; | |
121 } | |
122 } | |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
123 |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
124 free_cwd (&saved_cwd); |
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
125 errno = saved_errno; |
6527 | 126 return err; |
5588
14b330875e48
* modules/chdir-long, modules/openat: New files.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff
changeset
|
127 } |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
128 |
6322 | 129 #if !HAVE_FDOPENDIR |
130 | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
131 /* Replacement for Solaris' function by the same name. |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
132 <http://www.google.com/search?q=fdopendir+site:docs.sun.com> |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
133 Simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd. |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
134 If either the save_cwd or the restore_cwd fails (relatively unlikely, |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
135 and usually indicative of a problem that deserves close attention), |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
136 then give a diagnostic and exit nonzero. |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
137 Otherwise, this function works just like Solaris' fdopendir. |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
138 |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
139 W A R N I N G: |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
140 Unlike the other fd-related functions here, this one |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
141 effectively consumes its FD parameter. The caller should not |
6322 | 142 close or otherwise manipulate FD if this function returns successfully. */ |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
143 DIR * |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
144 fdopendir (int fd) |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
145 { |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
146 struct saved_cwd saved_cwd; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
147 int saved_errno; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
148 DIR *dir; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
149 |
6527 | 150 char *proc_file; |
151 BUILD_PROC_NAME (proc_file, fd, "."); | |
152 dir = opendir (proc_file); | |
153 saved_errno = errno; | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
154 |
6527 | 155 /* If the syscall fails with an expected errno value, resort to |
156 save_cwd/restore_cwd. */ | |
157 if (! dir && EXPECTED_ERRNO (saved_errno)) | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
158 { |
6527 | 159 if (save_cwd (&saved_cwd) != 0) |
160 openat_save_fail (errno); | |
161 | |
162 if (fchdir (fd) != 0) | |
163 { | |
164 dir = NULL; | |
165 saved_errno = errno; | |
166 } | |
167 else | |
168 { | |
169 dir = opendir ("."); | |
170 saved_errno = errno; | |
171 | |
172 if (restore_cwd (&saved_cwd) != 0) | |
173 openat_restore_fail (errno); | |
174 } | |
175 | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
176 free_cwd (&saved_cwd); |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
177 } |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
178 |
6322 | 179 if (dir) |
180 close (fd); | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
181 errno = saved_errno; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
182 return dir; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
183 } |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
184 |
6322 | 185 #endif |
186 | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
187 /* Replacement for Solaris' function by the same name. |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
188 <http://www.google.com/search?q=fstatat+site:docs.sun.com> |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
189 Simulate it by doing save_cwd/fchdir/(stat|lstat)/restore_cwd. |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
190 If either the save_cwd or the restore_cwd fails (relatively unlikely, |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
191 and usually indicative of a problem that deserves close attention), |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
192 then give a diagnostic and exit nonzero. |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
193 Otherwise, this function works just like Solaris' fstatat. */ |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
194 int |
5907 | 195 fstatat (int fd, char const *file, struct stat *st, int flag) |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
196 { |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
197 struct saved_cwd saved_cwd; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
198 int saved_errno; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
199 int err; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
200 |
6527 | 201 if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
202 return (flag == AT_SYMLINK_NOFOLLOW |
5907 | 203 ? lstat (file, st) |
204 : stat (file, st)); | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
205 |
6527 | 206 { |
207 char *proc_file; | |
208 BUILD_PROC_NAME (proc_file, fd, file); | |
209 err = (flag == AT_SYMLINK_NOFOLLOW | |
210 ? lstat (proc_file, st) | |
211 : stat (proc_file, st)); | |
212 /* If the syscall succeeds, or if it fails with an unexpected | |
213 errno value, then return right away. Otherwise, fall through | |
214 and resort to using save_cwd/restore_cwd. */ | |
215 if (0 <= err || ! EXPECTED_ERRNO (errno)) | |
216 return err; | |
217 } | |
218 | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
219 if (save_cwd (&saved_cwd) != 0) |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
220 openat_save_fail (errno); |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
221 |
6527 | 222 err = fchdir (fd); |
223 saved_errno = errno; | |
224 | |
225 if (! err) | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
226 { |
6527 | 227 err = (flag == AT_SYMLINK_NOFOLLOW |
228 ? lstat (file, st) | |
229 : stat (file, st)); | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
230 saved_errno = errno; |
6527 | 231 |
232 if (restore_cwd (&saved_cwd) != 0) | |
233 openat_restore_fail (errno); | |
5609
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
234 } |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
235 |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
236 free_cwd (&saved_cwd); |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
237 errno = saved_errno; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
238 return err; |
84f75cbb306a
* modules/chdir-long (Depends-on): Remove mempcpy.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5588
diff
changeset
|
239 } |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
240 |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
241 /* Replacement for Solaris' function by the same name. |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
242 <http://www.google.com/search?q=unlinkat+site:docs.sun.com> |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
243 Simulate it by doing save_cwd/fchdir/(unlink|rmdir)/restore_cwd. |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
244 If either the save_cwd or the restore_cwd fails (relatively unlikely, |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
245 and usually indicative of a problem that deserves close attention), |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
246 then give a diagnostic and exit nonzero. |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
247 Otherwise, this function works just like Solaris' unlinkat. */ |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
248 int |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
249 unlinkat (int fd, char const *file, int flag) |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
250 { |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
251 struct saved_cwd saved_cwd; |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
252 int saved_errno; |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
253 int err; |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
254 |
6527 | 255 if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
256 return (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file)); |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
257 |
6527 | 258 { |
259 char *proc_file; | |
260 BUILD_PROC_NAME (proc_file, fd, file); | |
261 err = (flag == AT_REMOVEDIR ? rmdir (proc_file) : unlink (proc_file)); | |
262 /* If the syscall succeeds, or if it fails with an unexpected | |
263 errno value, then return right away. Otherwise, fall through | |
264 and resort to using save_cwd/restore_cwd. */ | |
265 if (0 <= err || ! EXPECTED_ERRNO (errno)) | |
266 return err; | |
267 } | |
268 | |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
269 if (save_cwd (&saved_cwd) != 0) |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
270 openat_save_fail (errno); |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
271 |
6527 | 272 err = fchdir (fd); |
273 saved_errno = errno; | |
274 | |
275 if (! err) | |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
276 { |
6527 | 277 err = (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file)); |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
278 saved_errno = errno; |
6527 | 279 |
280 if (restore_cwd (&saved_cwd) != 0) | |
281 openat_restore_fail (errno); | |
6272
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
282 } |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
283 |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
284 free_cwd (&saved_cwd); |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
285 errno = saved_errno; |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
286 return err; |
3baa574549ae
* modules/openat (Files): Add lib/openat-die.c.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
287 } |