annotate toys/mkdir.c @ 562:4d802d438983

Match uint64_t with PRIu64 to avoid warnings on 64 bit builds.
author Rob Landley <rob@landley.net>
date Sat, 14 Apr 2012 21:27:00 -0500
parents a864aa8c6331
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
526
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
1 /* vi: set sw=4 ts=4:
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
2 *
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
3 * mkdir.c - Make directories
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
4 *
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
5 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
6 *
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
7 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/mkdir.html
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
8 *
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
9 * TODO: Add -m
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
10
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
11 USE_MKDIR(NEWTOY(mkdir, "<1p", TOYFLAG_BIN))
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
12
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
13 config MKDIR
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
14 bool "mkdir"
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
15 default y
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
16 help
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
17 usage: mkdir [-p] [dirname...]
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
18 Create one or more directories.
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
19
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
20 -p make parent directories as needed.
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
21 */
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
22
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
23 #include "toys.h"
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
62 }
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
63
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
64 void mkdir_main(void)
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
65 {
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
69
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
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
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
73 toys.exitval = 1;
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
74 }
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
75 }
f435e8e3a0ba Add mkdir.
Georgi Chorbadzhiyski <georgi@unixsol.org>
parents:
diff changeset
76 }