Mercurial > hg > octave-kai > gnulib-hg
annotate lib/makepath.c @ 2470:431e1a12c573
*** empty log message ***
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Thu, 04 May 2000 06:36:10 +0000 |
parents | 12ebcc75940c |
children | 6c9f9532d6b5 |
rev | line source |
---|---|
5 | 1 /* makepath.c -- Ensure that a directory path exists. |
2439 | 2 Copyright (C) 1990, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. |
5 | 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 2, or (at your option) | |
7 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 | |
650
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
645
diff
changeset
|
15 along with this program; if not, write to the Free Software Foundation, |
b4ef1c1a0171
update FSF address in copyright
Jim Meyering <jim@meyering.net>
parents:
645
diff
changeset
|
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
5 | 17 |
645 | 18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu> and Jim Meyering. */ |
5 | 19 |
701 | 20 #if HAVE_CONFIG_H |
21 # include <config.h> | |
105 | 22 #endif |
23 | |
701 | 24 #if __GNUC__ |
25 # define alloca __builtin_alloca | |
5 | 26 #else |
701 | 27 # if HAVE_ALLOCA_H |
28 # include <alloca.h> | |
29 # else | |
30 # ifdef _AIX | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
31 # pragma alloca |
701 | 32 # else |
5 | 33 char *alloca (); |
701 | 34 # endif |
35 # endif | |
5 | 36 #endif |
37 | |
38 #include <stdio.h> | |
39 #include <sys/types.h> | |
40 #include <sys/stat.h> | |
701 | 41 #if HAVE_UNISTD_H |
42 # include <unistd.h> | |
5 | 43 #endif |
104 | 44 |
701 | 45 #if STAT_MACROS_BROKEN |
46 # undef S_ISDIR | |
776 | 47 #endif |
104 | 48 |
5 | 49 #if !defined(S_ISDIR) && defined(S_IFDIR) |
701 | 50 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
5 | 51 #endif |
52 | |
2439 | 53 #ifndef S_IRWXUGO |
54 # define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) | |
55 #endif | |
56 | |
701 | 57 #if STDC_HEADERS |
58 # include <stdlib.h> | |
82 | 59 #endif |
60 | |
701 | 61 #if HAVE_ERRNO_H |
62 # include <errno.h> | |
83 | 63 #endif |
64 | |
433
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
65 #ifndef errno |
5 | 66 extern int errno; |
67 #endif | |
68 | |
701 | 69 #if HAVE_STRING_H |
433
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
70 # include <string.h> |
5 | 71 #else |
433
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
72 # include <strings.h> |
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
73 # ifndef strchr |
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
74 # define strchr index |
c518df1ae5a3
(make_path): Use stat, not SAFE_STAT.
Jim Meyering <jim@meyering.net>
parents:
353
diff
changeset
|
75 # endif |
5 | 76 #endif |
77 | |
1815
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
78 #ifndef S_ISUID |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
79 # define S_ISUID 04000 |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
80 #endif |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
81 #ifndef S_ISGID |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
82 # define S_ISGID 02000 |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
83 #endif |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
84 #ifndef S_ISVTX |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
85 # define S_ISVTX 01000 |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
86 #endif |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
87 #ifndef S_IRUSR |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
88 # define S_IRUSR 0200 |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
89 #endif |
1192
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
90 #ifndef S_IWUSR |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
91 # define S_IWUSR 0200 |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
92 #endif |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
93 #ifndef S_IXUSR |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
94 # define S_IXUSR 0100 |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
95 #endif |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
96 |
1815
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
97 #ifndef S_IRWXU |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
98 # define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
99 #endif |
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
100 |
1192
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
101 #define WX_USR (S_IWUSR | S_IXUSR) |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
102 |
1827
201b8621ca15
Include makepath.h libintl.h, not after it.
Jim Meyering <jim@meyering.net>
parents:
1815
diff
changeset
|
103 /* Include this before libintl.h so we get our definition of PARAMS. */ |
201b8621ca15
Include makepath.h libintl.h, not after it.
Jim Meyering <jim@meyering.net>
parents:
1815
diff
changeset
|
104 #include "makepath.h" |
201b8621ca15
Include makepath.h libintl.h, not after it.
Jim Meyering <jim@meyering.net>
parents:
1815
diff
changeset
|
105 |
1607
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
106 #if HAVE_LOCALE_H |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
107 # include <locale.h> |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
108 #endif |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
109 |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
110 #if ENABLE_NLS |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
111 # include <libintl.h> |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
112 # define _(Text) gettext (Text) |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
113 #else |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
114 # define _(Text) Text |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
115 #endif |
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
116 |
5 | 117 #ifdef __MSDOS__ |
118 typedef int uid_t; | |
119 typedef int gid_t; | |
120 #endif | |
121 | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
122 #include "save-cwd.h" |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
123 #include "error.h" |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
124 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
125 void strip_trailing_slashes (); |
439
a9015d648b2e
No longer include safe-l?stat.h.
Jim Meyering <jim@meyering.net>
parents:
433
diff
changeset
|
126 |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
127 #define CLEANUP_CWD \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
128 do \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
129 { \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
130 /* We're done operating on basename_dir. \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
131 Restore working directory. */ \ |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
132 if (do_chdir) \ |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
133 { \ |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
134 int _fail = restore_cwd (&cwd, NULL, NULL); \ |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
135 free_cwd (&cwd); \ |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
136 if (_fail) \ |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
137 return 1; \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
138 } \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
139 } \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
140 while (0) |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
141 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
142 #define CLEANUP \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
143 do \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
144 { \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
145 umask (oldmask); \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
146 CLEANUP_CWD; \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
147 } \ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
148 while (0) |
5 | 149 |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
150 /* Attempt to create directory DIR (aka DIRPATH) with the specified MODE. |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
151 If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P to non-zero if this |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
152 function creates DIR and to zero otherwise. Give a diagnostic and |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
153 return non-zero if DIR cannot be created or cannot be determined to |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
154 exist already. Use DIRPATH in any diagnostic, not DIR. |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
155 Note that if DIR already exists, this function will return zero |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
156 (indicating success) and will set *CREATED_DIR_P to zero. */ |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
157 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
158 static int |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
159 make_dir (const char *dir, const char *dirpath, mode_t mode, int *created_dir_p) |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
160 { |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
161 int fail = 0; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
162 int created_dir; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
163 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
164 created_dir = (mkdir (dir, mode) == 0); |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
165 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
166 if (!created_dir) |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
167 { |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
168 struct stat stats; |
1831
ce6300b50014
(make_dir): When reporting a mkdir failure and the
Jim Meyering <jim@meyering.net>
parents:
1827
diff
changeset
|
169 int saved_errno = errno; |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
170 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
171 /* The mkdir and stat calls below may appear to be reversed. |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
172 They are not. It is important to call mkdir first and then to |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
173 call stat (to distinguish the three cases) only if mkdir fails. |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
174 The alternative to this approach is to `stat' each directory, |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
175 then to call mkdir if it doesn't exist. But if some other process |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
176 were to create the directory between the stat & mkdir, the mkdir |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
177 would fail with EEXIST. */ |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
178 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
179 if (stat (dir, &stats)) |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
180 { |
1831
ce6300b50014
(make_dir): When reporting a mkdir failure and the
Jim Meyering <jim@meyering.net>
parents:
1827
diff
changeset
|
181 error (0, saved_errno, _("cannot create directory `%s'"), dirpath); |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
182 fail = 1; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
183 } |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
184 else if (!S_ISDIR (stats.st_mode)) |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
185 { |
1607
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
186 error (0, 0, _("`%s' exists but is not a directory"), dirpath); |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
187 fail = 1; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
188 } |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
189 else |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
190 { |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
191 /* DIR (aka DIRPATH) already exists and is a directory. */ |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
192 } |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
193 } |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
194 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
195 if (created_dir_p) |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
196 *created_dir_p = created_dir; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
197 |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
198 return fail; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
199 } |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
200 |
5 | 201 /* Ensure that the directory ARGPATH exists. |
202 Remove any trailing slashes from ARGPATH before calling this function. | |
203 | |
348 | 204 Create any leading directories that don't already exist, with |
5 | 205 permissions PARENT_MODE. |
206 If the last element of ARGPATH does not exist, create it as | |
207 a new directory with permissions MODE. | |
348 | 208 If OWNER and GROUP are non-negative, use them to set the UID and GID of |
209 any created directories. | |
5 | 210 If VERBOSE_FMT_STRING is nonzero, use it as a printf format |
211 string for printing a message after successfully making a directory, | |
212 with the name of the directory that was just made as an argument. | |
348 | 213 If PRESERVE_EXISTING is non-zero and ARGPATH is an existing directory, |
214 then do not attempt to set its permissions and ownership. | |
5 | 215 |
216 Return 0 if ARGPATH exists as a directory with the proper | |
217 ownership and permissions when done, otherwise 1. */ | |
218 | |
353 | 219 int |
220 make_path (const char *argpath, | |
221 int mode, | |
222 int parent_mode, | |
223 uid_t owner, | |
224 gid_t group, | |
225 int preserve_existing, | |
226 const char *verbose_fmt_string) | |
5 | 227 { |
228 struct stat stats; | |
229 int retval = 0; | |
230 | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
231 if (stat (argpath, &stats)) |
5 | 232 { |
233 char *slash; | |
234 int tmp_mode; /* Initial perms for leading dirs. */ | |
235 int re_protect; /* Should leading dirs be unwritable? */ | |
236 struct ptr_list | |
237 { | |
238 char *dirname_end; | |
239 struct ptr_list *next; | |
240 }; | |
241 struct ptr_list *p, *leading_dirs = NULL; | |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
242 int do_chdir; /* Whether to chdir before each mkdir. */ |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
243 struct saved_cwd cwd; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
244 char *basename_dir; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
245 char *dirpath; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
246 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
247 /* Temporarily relax umask in case it's overly restrictive. */ |
1815
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
248 mode_t oldmask = umask (0); |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
249 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
250 /* Make a copy of ARGPATH that we can scribble NULs on. */ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
251 dirpath = (char *) alloca (strlen (argpath) + 1); |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
252 strcpy (dirpath, argpath); |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
253 strip_trailing_slashes (dirpath); |
5 | 254 |
255 /* If leading directories shouldn't be writable or executable, | |
256 or should have set[ug]id or sticky bits set and we are setting | |
257 their owners, we need to fix their permissions after making them. */ | |
1192
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
258 if (((parent_mode & WX_USR) != WX_USR) |
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
259 || ((owner != (uid_t) -1 || group != (gid_t) -1) |
1815
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
260 && (parent_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0)) |
5 | 261 { |
1815
9de6ea676212
(make_path): Use proper mode_t types and macros.
Jim Meyering <jim@meyering.net>
parents:
1607
diff
changeset
|
262 tmp_mode = S_IRWXU; |
5 | 263 re_protect = 1; |
264 } | |
265 else | |
266 { | |
267 tmp_mode = parent_mode; | |
268 re_protect = 0; | |
269 } | |
270 | |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
271 /* If we can record the current working directory, we may be able |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
272 to do the chdir optimization. */ |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
273 do_chdir = !save_cwd (&cwd); |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
274 |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
275 /* If we've saved the cwd and DIRPATH is an absolute pathname, |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
276 we must chdir to `/' in order to enable the chdir optimization. |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
277 So if chdir ("/") fails, turn off the optimization. */ |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
278 if (do_chdir && *dirpath == '/' && chdir ("/") < 0) |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
279 do_chdir = 0; |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
280 |
5 | 281 slash = dirpath; |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
282 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
283 /* Skip over leading slashes. */ |
5 | 284 while (*slash == '/') |
285 slash++; | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
286 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
287 while (1) |
5 | 288 { |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
289 int newly_created_dir; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
290 int fail; |
1053
433d747aceae
(make_path): Print message IFF the directory was
Jim Meyering <jim@meyering.net>
parents:
979
diff
changeset
|
291 |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
292 /* slash points to the leftmost unprocessed component of dirpath. */ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
293 basename_dir = slash; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
294 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
295 slash = strchr (slash, '/'); |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
296 if (slash == NULL) |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
297 break; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
298 |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
299 /* If we're *not* doing chdir before each mkdir, then we have to refer |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
300 to the target using the full (multi-component) directory name. */ |
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
301 if (!do_chdir) |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
302 basename_dir = dirpath; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
303 |
5 | 304 *slash = '\0'; |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
305 fail = make_dir (basename_dir, dirpath, tmp_mode, &newly_created_dir); |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
306 if (fail) |
5 | 307 { |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
308 CLEANUP; |
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
309 return 1; |
5 | 310 } |
960
6f2958d80ce3
(make_path): Reorder stat-then-mkdir-if-missing
Jim Meyering <jim@meyering.net>
parents:
937
diff
changeset
|
311 |
1206
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
312 if (newly_created_dir) |
5 | 313 { |
1206
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
314 if (verbose_fmt_string) |
2032
f2674deedbfe
(make_path): Consistently use error to output
Jim Meyering <jim@meyering.net>
parents:
2013
diff
changeset
|
315 error (0, 0, verbose_fmt_string, dirpath); |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
316 |
1206
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
317 if ((owner != (uid_t) -1 || group != (gid_t) -1) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
318 && chown (basename_dir, owner, group) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
319 #if defined(AFS) && defined (EPERM) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
320 && errno != EPERM |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
321 #endif |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
322 ) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
323 { |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
324 error (0, errno, "%s", dirpath); |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
325 CLEANUP; |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
326 return 1; |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
327 } |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
328 |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
329 if (re_protect) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
330 { |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
331 struct ptr_list *new = (struct ptr_list *) |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
332 alloca (sizeof (struct ptr_list)); |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
333 new->dirname_end = slash; |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
334 new->next = leading_dirs; |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
335 leading_dirs = new; |
5032c8c66257
(make_path): Reformat 3 if-stmts to test `if (newly_created_dir)' only once.
Jim Meyering <jim@meyering.net>
parents:
1205
diff
changeset
|
336 } |
960
6f2958d80ce3
(make_path): Reorder stat-then-mkdir-if-missing
Jim Meyering <jim@meyering.net>
parents:
937
diff
changeset
|
337 } |
6f2958d80ce3
(make_path): Reorder stat-then-mkdir-if-missing
Jim Meyering <jim@meyering.net>
parents:
937
diff
changeset
|
338 |
973 | 339 /* If we were able to save the initial working directory, |
340 then we can use chdir to change into each directory before | |
341 creating an entry in that directory. This avoids making | |
342 stat and mkdir process O(n^2) file name components. */ | |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
343 if (do_chdir && chdir (basename_dir) < 0) |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
344 { |
1607
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
345 error (0, errno, _("cannot chdir to directory, %s"), dirpath); |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
346 CLEANUP; |
5 | 347 return 1; |
348 } | |
349 | |
350 *slash++ = '/'; | |
351 | |
352 /* Avoid unnecessary calls to `stat' when given | |
353 pathnames containing multiple adjacent slashes. */ | |
354 while (*slash == '/') | |
355 slash++; | |
356 } | |
357 | |
979
302fd7682df7
(make_path): Chdir to `/' before starting if necessary.
Jim Meyering <jim@meyering.net>
parents:
973
diff
changeset
|
358 if (!do_chdir) |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
359 basename_dir = dirpath; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
360 |
5 | 361 /* We're done making leading directories. |
348 | 362 Create the final component of the path. */ |
5 | 363 |
1606
acfbb83ef181
(make_dir): New function, factored out of make_path.
Jim Meyering <jim@meyering.net>
parents:
1239
diff
changeset
|
364 if (make_dir (basename_dir, dirpath, mode, NULL)) |
5 | 365 { |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
366 CLEANUP; |
5 | 367 return 1; |
368 } | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
369 |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
370 /* Done creating directories. Restore original umask. */ |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
371 umask (oldmask); |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
372 |
5 | 373 if (verbose_fmt_string != NULL) |
374 error (0, 0, verbose_fmt_string, dirpath); | |
375 | |
2013
e4a5324fa543
(make_path): Fix long-latent bug (note others
Jim Meyering <jim@meyering.net>
parents:
1831
diff
changeset
|
376 if (owner != (uid_t) -1 || group != (gid_t) -1) |
5 | 377 { |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
378 if (chown (basename_dir, owner, group) |
5 | 379 #ifdef AFS |
380 && errno != EPERM | |
381 #endif | |
382 ) | |
383 { | |
1607
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
384 error (0, errno, _("cannot chown %s"), dirpath); |
5 | 385 retval = 1; |
386 } | |
2439 | 387 } |
388 | |
389 /* The above chown may have turned off some permission bits in MODE. | |
390 Another reason we may have to use chmod here is that mkdir(2) is | |
391 required to honor only the file permission bits. In particular, | |
2441 | 392 it need not honor the `special' bits, so if MODE includes any |
393 special bits, set them here. */ | |
2439 | 394 if ((mode & ~S_IRWXUGO) |
395 && chmod (basename_dir, mode)) | |
396 { | |
397 error (0, errno, _("cannot chmod %s"), dirpath); | |
398 retval = 1; | |
5 | 399 } |
400 | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
401 CLEANUP_CWD; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
402 |
5 | 403 /* If the mode for leading directories didn't include owner "wx" |
404 privileges, we have to reset their protections to the correct | |
405 value. */ | |
406 for (p = leading_dirs; p != NULL; p = p->next) | |
407 { | |
408 *(p->dirname_end) = '\0'; | |
409 if (chmod (dirpath, parent_mode)) | |
410 { | |
411 error (0, errno, "%s", dirpath); | |
412 retval = 1; | |
413 } | |
414 } | |
415 } | |
416 else | |
417 { | |
418 /* We get here if the entire path already exists. */ | |
419 | |
937
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
420 const char *dirpath = argpath; |
8147b16806cd
Rewrite using save-cwd.c and chdir to remove quadratic component of complexity.
Jim Meyering <jim@meyering.net>
parents:
776
diff
changeset
|
421 |
5 | 422 if (!S_ISDIR (stats.st_mode)) |
423 { | |
1607
06aac86fa3af
Include locale.h and libintl.h, and define `_()'.
Jim Meyering <jim@meyering.net>
parents:
1606
diff
changeset
|
424 error (0, 0, _("`%s' exists but is not a directory"), dirpath); |
5 | 425 return 1; |
426 } | |
427 | |
348 | 428 if (!preserve_existing) |
429 { | |
430 /* chown must precede chmod because on some systems, | |
431 chown clears the set[ug]id bits for non-superusers, | |
432 resulting in incorrect permissions. | |
433 On System V, users can give away files with chown and then not | |
434 be able to chmod them. So don't give files away. */ | |
5 | 435 |
1192
fcb9d43860d6
(make_path): Try to change ownership only if we've just created the
Jim Meyering <jim@meyering.net>
parents:
1187
diff
changeset
|
436 if ((owner != (uid_t) -1 || group != (gid_t) -1) |
348 | 437 && chown (dirpath, owner, group) |
5 | 438 #ifdef AFS |
348 | 439 && errno != EPERM |
5 | 440 #endif |
348 | 441 ) |
442 { | |
443 error (0, errno, "%s", dirpath); | |
444 retval = 1; | |
445 } | |
446 if (chmod (dirpath, mode)) | |
447 { | |
448 error (0, errno, "%s", dirpath); | |
449 retval = 1; | |
450 } | |
5 | 451 } |
452 } | |
453 | |
454 return retval; | |
455 } |