Mercurial > hg > octave-shane > gnulib-hg
annotate lib/mkdir-p.c @ 17282:a4996fb12971
locale: port to Solaris 2.6 and 7 + GNU gettext
* lib/locale.in.h: Just include_next <locale.h> when
being invoked recursively. This prevents problems on Solaris 2.6 and 7
when combining the localename module with GNU gettext 0.18.2.
Problem reported by Tom G. Christensen in
<http://lists.gnu.org/archive/html/bug-gnulib/2013-01/msg00084.html>.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Thu, 10 Jan 2013 13:24:13 -0800 |
parents | e542fd46ad6f |
children | 21bdea0c916e |
rev | line source |
---|---|
5907 | 1 /* mkdir-p.c -- Ensure that a directory and its parents exist. |
2 | |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16358
diff
changeset
|
3 Copyright (C) 1990, 1997-2000, 2002-2007, 2009-2013 Free Software |
12559
c2cbabec01dd
update nearly all FSF copyright year lists to include 2010
Jim Meyering <meyering@redhat.com>
parents:
12518
diff
changeset
|
4 Foundation, Inc. |
5907 | 5 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8059
diff
changeset
|
6 This program is free software: you can redistribute it and/or modify |
5907 | 7 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:
8059
diff
changeset
|
8 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:
8059
diff
changeset
|
9 (at your option) any later version. |
5907 | 10 |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8059
diff
changeset
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
5907 | 18 |
6969 | 19 /* Written by Paul Eggert, David MacKenzie, and Jim Meyering. */ |
5907 | 20 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
6969
diff
changeset
|
21 #include <config.h> |
5907 | 22 |
23 #include "mkdir-p.h" | |
24 | |
6969 | 25 #include <errno.h> |
5907 | 26 #include <sys/stat.h> |
7380
d12ab9dc1e7e
* mkdir-p.c: Include "dirchownmod.h", not "dirchownmod.c".
Jim Meyering <jim@meyering.net>
parents:
7312
diff
changeset
|
27 #include <unistd.h> |
5907 | 28 |
29 #include "gettext.h" | |
30 #define _(msgid) gettext (msgid) | |
31 | |
7380
d12ab9dc1e7e
* mkdir-p.c: Include "dirchownmod.h", not "dirchownmod.c".
Jim Meyering <jim@meyering.net>
parents:
7312
diff
changeset
|
32 #include "dirchownmod.h" |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
33 #include "dirname.h" |
5907 | 34 #include "error.h" |
35 #include "quote.h" | |
6969 | 36 #include "mkancesdirs.h" |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
37 #include "savewd.h" |
5907 | 38 |
7479
a21f992ed2b2
* lib/mkdir-p.c (HAVE_FCHMOD): Define to false if not already
Paul Eggert <eggert@cs.ucla.edu>
parents:
7418
diff
changeset
|
39 #ifndef HAVE_FCHMOD |
a21f992ed2b2
* lib/mkdir-p.c (HAVE_FCHMOD): Define to false if not already
Paul Eggert <eggert@cs.ucla.edu>
parents:
7418
diff
changeset
|
40 # define HAVE_FCHMOD false |
a21f992ed2b2
* lib/mkdir-p.c (HAVE_FCHMOD): Define to false if not already
Paul Eggert <eggert@cs.ucla.edu>
parents:
7418
diff
changeset
|
41 #endif |
a21f992ed2b2
* lib/mkdir-p.c (HAVE_FCHMOD): Define to false if not already
Paul Eggert <eggert@cs.ucla.edu>
parents:
7418
diff
changeset
|
42 |
6969 | 43 /* Ensure that the directory DIR exists. |
44 | |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
45 WD is the working directory, as in savewd.c. |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
46 |
6969 | 47 If MAKE_ANCESTOR is not null, create any ancestor directories that |
7418
77a75e20049c
* mkancesdirs.c (mkancesdirs): Pass to MAKE_DIR both the full file
Paul Eggert <eggert@cs.ucla.edu>
parents:
7380
diff
changeset
|
48 don't already exist, by invoking MAKE_ANCESTOR (DIR, ANCESTOR, OPTIONS). |
6969 | 49 This function should return zero if successful, -1 (setting errno) |
50 otherwise. In this case, DIR may be modified by storing '\0' bytes | |
51 into it, to access the ancestor directories, and this modification | |
52 is retained on return if the ancestor directories could not be | |
53 created. | |
54 | |
55 Create DIR as a new directory with using mkdir with permissions | |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
56 MODE. It is also OK if MAKE_ANCESTOR is not null and a |
6969 | 57 directory DIR already exists. |
58 | |
59 Call ANNOUNCE (DIR, OPTIONS) just after successfully making DIR, | |
60 even if some of the following actions fail. | |
5907 | 61 |
6969 | 62 Set DIR's owner to OWNER and group to GROUP, but leave the owner |
63 alone if OWNER is (uid_t) -1, and similarly for GROUP. | |
5907 | 64 |
6969 | 65 Set DIR's mode bits to MODE, except preserve any of the bits that |
66 correspond to zero bits in MODE_BITS. In other words, MODE_BITS is | |
67 a mask that specifies which of DIR's mode bits should be set or | |
68 cleared. MODE should be a subset of MODE_BITS, which in turn | |
69 should be a subset of CHMOD_MODE_BITS. Changing the mode in this | |
70 way is necessary if DIR already existed or if MODE and MODE_BITS | |
71 specify non-permissions bits like S_ISUID. | |
6271
fdd622fe6d47
* mkdir-p.c (ENOSYS): Define to EEXIST if not defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
72 |
6969 | 73 However, if PRESERVE_EXISTING is true and DIR already exists, |
74 do not attempt to set DIR's ownership and file mode bits. | |
75 | |
76 This implementation assumes the current umask is zero. | |
77 | |
78 Return true if DIR exists as a directory with the proper ownership | |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
79 and file mode bits when done, or if a child process has been |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
80 dispatched to do the real work (though the child process may not |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
81 have finished yet -- it is the caller's responsibility to handle |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
82 this). Report a diagnostic and return false on failure, storing |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
83 '\0' into *DIR if an ancestor directory had problems. */ |
5907 | 84 |
85 bool | |
6969 | 86 make_dir_parents (char *dir, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
87 struct savewd *wd, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
88 int (*make_ancestor) (char const *, char const *, void *), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
89 void *options, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
90 mode_t mode, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
91 void (*announce) (char const *, void *), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
92 mode_t mode_bits, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
93 uid_t owner, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
94 gid_t group, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
95 bool preserve_existing) |
5907 | 96 { |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
97 int mkdir_errno = (IS_ABSOLUTE_FILE_NAME (dir) ? 0 : savewd_errno (wd)); |
5907 | 98 |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
99 if (mkdir_errno == 0) |
6271
fdd622fe6d47
* mkdir-p.c (ENOSYS): Define to EEXIST if not defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
100 { |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
101 ptrdiff_t prefix_len = 0; |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
102 int savewd_chdir_options = (HAVE_FCHMOD ? SAVEWD_CHDIR_SKIP_READABLE : 0); |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
103 |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
104 if (make_ancestor) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
105 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
106 prefix_len = mkancesdirs (dir, wd, make_ancestor, options); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
107 if (prefix_len < 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
108 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
109 if (prefix_len < -1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
110 return true; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
111 mkdir_errno = errno; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
112 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
113 } |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
114 |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
115 if (0 <= prefix_len) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
116 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
117 /* If the ownership might change, or if the directory will be |
16358 | 118 writable to other users and its special mode bits may |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
119 change after the directory is created, create it with |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
120 more restrictive permissions at first, so unauthorized |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
121 users cannot nip in before the directory is ready. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
122 bool keep_owner = owner == (uid_t) -1 && group == (gid_t) -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
123 bool keep_special_mode_bits = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
124 ((mode_bits & (S_ISUID | S_ISGID)) | (mode & S_ISVTX)) == 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
125 mode_t mkdir_mode = mode; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
126 if (! keep_owner) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
127 mkdir_mode &= ~ (S_IRWXG | S_IRWXO); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
128 else if (! keep_special_mode_bits) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
129 mkdir_mode &= ~ (S_IWGRP | S_IWOTH); |
7711
17e5da0fb096
* lib/mkdir-p.c (make_dir_parents): Fix race condition when making
Paul Eggert <eggert@cs.ucla.edu>
parents:
7581
diff
changeset
|
130 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
131 if (mkdir (dir + prefix_len, mkdir_mode) == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
132 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
133 announce (dir, options); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
134 preserve_existing = keep_owner & keep_special_mode_bits; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
135 savewd_chdir_options |= |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
136 (SAVEWD_CHDIR_NOFOLLOW |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
137 | (mode & S_IRUSR ? SAVEWD_CHDIR_READABLE : 0)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
138 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
139 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
140 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
141 mkdir_errno = errno; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
142 mkdir_mode = -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
143 } |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
144 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
145 if (preserve_existing) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
146 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
147 struct stat st; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
148 if (mkdir_errno == 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
149 || (mkdir_errno != ENOENT && make_ancestor |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
150 && stat (dir + prefix_len, &st) == 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
151 && S_ISDIR (st.st_mode))) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
152 return true; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
153 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
154 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
155 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
156 int open_result[2]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
157 int chdir_result = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
158 savewd_chdir (wd, dir + prefix_len, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
159 savewd_chdir_options, open_result); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
160 if (chdir_result < -1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
161 return true; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
162 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
163 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
164 bool chdir_ok = (chdir_result == 0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
165 int chdir_errno = errno; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
166 int fd = open_result[0]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
167 bool chdir_failed_unexpectedly = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
168 (mkdir_errno == 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
169 && ((! chdir_ok && (mode & S_IXUSR)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
170 || (fd < 0 && (mode & S_IRUSR)))); |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
171 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
172 if (chdir_failed_unexpectedly) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
173 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
174 /* No need to save errno here; it's irrelevant. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
175 if (0 <= fd) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
176 close (fd); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
177 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
178 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
179 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
180 char const *subdir = (chdir_ok ? "." : dir + prefix_len); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
181 if (dirchownmod (fd, subdir, mkdir_mode, owner, group, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
182 mode, mode_bits) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
183 == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
184 return true; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
185 } |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
186 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
187 if (mkdir_errno == 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
188 || (mkdir_errno != ENOENT && make_ancestor |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
189 && errno != ENOTDIR)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
190 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
191 error (0, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
192 (! chdir_failed_unexpectedly ? errno |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
193 : ! chdir_ok && (mode & S_IXUSR) ? chdir_errno |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
194 : open_result[1]), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
195 _(keep_owner |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
196 ? "cannot change permissions of %s" |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
197 : "cannot change owner and permissions of %s"), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
198 quote (dir)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
199 return false; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
200 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
201 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
202 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
203 } |
6969 | 204 } |
6271
fdd622fe6d47
* mkdir-p.c (ENOSYS): Define to EEXIST if not defined.
Paul Eggert <eggert@cs.ucla.edu>
parents:
6259
diff
changeset
|
205 |
7312
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
206 error (0, mkdir_errno, _("cannot create directory %s"), quote (dir)); |
796e1837ac66
* lib/dirchownmod.c: Don't include fcntl.h; no longer needed.
Paul Eggert <eggert@cs.ucla.edu>
parents:
7302
diff
changeset
|
207 return false; |
5907 | 208 } |