diff options
Diffstat (limited to 'src/commands/mkdir.c')
-rw-r--r-- | src/commands/mkdir.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/commands/mkdir.c b/src/commands/mkdir.c new file mode 100644 index 0000000..3ff1afd --- /dev/null +++ b/src/commands/mkdir.c @@ -0,0 +1,60 @@ +#include "../command.h" + +static struct { + bool make_parent; + mode_t mode; +} flags; + +static int short_arg(char c, char* next) { + switch (c) { + case 'p': + flags.make_parent = true; + break; + case 'm': + check_arg(next); + flags.mode = get_mode(next); + return ARG_USED; + default: + return ARG_INVALID; + } + return ARG_UNUSED; +} + +static void help(void) { + printf("Usage: mkdir [-m MODE] [-p] DIRECTORY...\n\n"); + printf("Create DIRECTORY\n\n"); + printf("\t-m\tMODE\n"); + printf("\t-p\tNo error if exists; make parent directories as needed\n"); +} + +static bool mkdir_parents(char* path) { + for (size_t i = 1; i < strlen(path); i++) { + if (path[i] != '/') continue; + path[i] = '\0'; + if (mkdir(path, flags.mode) < 0 && errno != EEXIST) { + error_s("failed to create directory '%s': %s", path, strerror(errno)); + return false; + }; + path[i] = '/'; + } + return true; +} + +COMMAND(makedir) { + if (argc < 1) global_help(help); + + flags.make_parent = false; + flags.mode = 0755; + int start = parse_args(argc, argv, help, short_arg, NULL); + + for (int i = start; i < argc; i++) { + if (flags.make_parent && !mkdir_parents(argv[i])) { + continue; + } + if (mkdir(argv[i], flags.mode) < 0) { + error_s("failed to create directory '%s': %s", argv[i], strerror(errno)); + } + } + + return EXIT_SUCCESS; +} |