summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--utils/mkdir/mkdir.c54
2 files changed, 49 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 2c0859e8..ea5d627e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,5 @@
20110329
+ utils/mkdir/mkdir.c - add -p option [mechiel, issue 250]
emu/Linux/mkfile - try searching -lpthread after -lrt for sem_* [issue 247]
emu/port/devfs-posix.c - treat unix domain sockets as files (open/read/write/close) [npe, rsc, issue 254]
emu/port/devfs-posix.c - use volatile correctly; slight code tidy
diff --git a/utils/mkdir/mkdir.c b/utils/mkdir/mkdir.c
index 5bdf53c0..b47ee54d 100644
--- a/utils/mkdir/mkdir.c
+++ b/utils/mkdir/mkdir.c
@@ -1,14 +1,56 @@
#include <lib9.h>
-void
-main(int argc, char **argv)
+static void
+usage(void)
+{
+ fprint(2, "usage: mkdir [-p] dir ...\n");
+ exits("usage");
+}
+
+static int
+mkdirp(char *s, int pflag)
{
- for(argv++; *argv; argv++){
- if(access(*argv, 0) == 0){
- fprint(2, "mkdir: %s already exists\n", *argv);
+ char *p;
+
+ if(!pflag) {
+ if(access(s, 0) == 0){
+ fprint(2, "mkdir: %s already exists\n", s);
exits("exists");
}
- if(mkdir(*argv) < 0){
+ return mkdir(s);
+ }
+
+ /* create intermediate directories */
+ p = strchr(s+1, '/');
+ while(p != nil) {
+ *p = '\0';
+ if(access(s, 0) != 0 && mkdir(s) != 0)
+ return -1;
+ *p = '/';
+ p = strchr(p+1, '/');
+ }
+
+ /* create final directory */
+ if(access(s, 0) == 0)
+ return 0;
+ return mkdir(s);
+}
+
+void
+main(int argc, char **argv)
+{
+ int pflag;
+
+ pflag = 0;
+ ARGBEGIN{
+ case 'p':
+ pflag++;
+ break;
+ default:
+ usage();
+ }ARGEND
+ for(; *argv; argv++){
+ if(mkdirp(*argv, pflag) < 0){
fprint(2, "mkdir: can't create %s\n", *argv);
perror(0);
exits("error");