Mercurial > hg > toybox
annotate toys/mkdir.c @ 587:82ffae226c40
Convert another realpath use to xrealpath().
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 01 Jun 2012 17:59:11 -0500 |
parents | a864aa8c6331 |
children |
rev | line source |
---|---|
526 | 1 /* vi: set sw=4 ts=4: |
2 * | |
3 * mkdir.c - Make directories | |
4 * | |
5 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> | |
6 * | |
7 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/mkdir.html | |
8 * | |
9 * TODO: Add -m | |
10 | |
11 USE_MKDIR(NEWTOY(mkdir, "<1p", TOYFLAG_BIN)) | |
12 | |
13 config MKDIR | |
14 bool "mkdir" | |
15 default y | |
16 help | |
17 usage: mkdir [-p] [dirname...] | |
18 Create one or more directories. | |
19 | |
20 -p make parent directories as needed. | |
21 */ | |
22 | |
23 #include "toys.h" | |
24 | |
527
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
25 DEFINE_GLOBALS( |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
26 long mode; |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
27 ) |
526 | 28 |
527
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
29 #define TT this.mkdir |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
30 |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
31 static int do_mkdir(char *dir) |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
32 { |
534
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
33 struct stat buf; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
34 char *s; |
526 | 35 |
534
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
36 // mkdir -p one/two/three is not an error if the path already exists, |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
37 // but is if "three" is a file. The others we dereference and catch |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
38 // not-a-directory along the way, but the last one we must explicitly |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
39 // test for. Might as well do it up front. |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
40 |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
41 if (!stat(dir, &buf) && !S_ISDIR(buf.st_mode)) { |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
42 errno = EEXIST; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
43 return 1; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
44 } |
526 | 45 |
534
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
46 for (s=dir; ; s++) { |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
47 char save=0; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
48 |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
49 // Skip leading / of absolute paths. |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
50 if (s!=dir && *s == '/' && toys.optflags) { |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
51 save = *s; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
52 *s = 0; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
53 } else if (*s) continue; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
54 |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
55 if (mkdir(dir, TT.mode)<0 && (!toys.optflags || errno != EEXIST)) |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
56 return 1; |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
57 |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
58 if (!(*s = save)) break; |
526 | 59 } |
534
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
60 |
a864aa8c6331
Fix mkdir -p to accept paths that already exist, and detect path ending in a file.
Rob Landley <rob@landley.net>
parents:
527
diff
changeset
|
61 return 0; |
526 | 62 } |
63 | |
64 void mkdir_main(void) | |
65 { | |
66 char **s; | |
527
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
67 |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
68 TT.mode = 0777; |
526 | 69 |
70 for (s=toys.optargs; *s; s++) { | |
527
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
71 if (do_mkdir(*s)) { |
a3116cb7ba1e
mkdir cleanups: Let umask do its thing at the syscall level, have mode be a global to prepare for -m, use do_blah name loopfiles() usually calls, one less redundant mkdir() call, go ahead and modify writeable args instead of strdup(), return before restoring / so error message is better, use perror_msg().
Rob Landley <rob@landley.net>
parents:
526
diff
changeset
|
72 perror_msg("cannot create directory '%s'", *s); |
526 | 73 toys.exitval = 1; |
74 } | |
75 } | |
76 } |