mkdir.c (2275B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include "../lib/lib_mkdir.h"
- #include "../lib/mode.h"
- #include <assert.h>
- #include <errno.h>
- #include <stdbool.h>
- #include <stdio.h> // fprintf
- #include <stdlib.h> // abort
- #include <string.h> // strerror
- #include <sys/stat.h> // mkdir
- #include <unistd.h> // getopt
- const char *argv0 = "mkdir";
- bool mkdir_parents_verbose = false;
- mode_t mkdir_parents_filemask;
- static int
- mkdir_simple(char *path, mode_t mode)
- {
- assert(errno == 0);
- if(mkdir(path, mode) < 0)
- {
- fprintf(stderr, "%s: error: Failed making directory '%s': %s\n", argv0, path, strerror(errno));
- errno = 0;
- return -1;
- }
- if(mkdir_parents_verbose) fprintf(stderr, "%s: Made directory: %s\n", argv0, path);
- return 0;
- }
- static void
- usage(void)
- {
- fprintf(stderr, "Usage: mkdir [-pv] [-m mode] path ...\n");
- }
- int
- main(int argc, char *argv[])
- {
- mkdir_parents_filemask = umask(0);
- umask(mkdir_parents_filemask);
- // clang-format off
- mode_t mode = (S_IRWXU | S_IRWXG | S_IRWXO | ~mkdir_parents_filemask) & 0777;
- bool opt_p = false;
- const char *errstr = NULL;
- // clang-format on
- int c = -1;
- while((c = getopt(argc, argv, ":pvm:")) != -1)
- {
- switch(c)
- {
- case 'p':
- opt_p = true;
- break;
- case 'v':
- mkdir_parents_verbose = true;
- break;
- case 'm':
- mode = new_mode(optarg, 0777, &errstr);
- if(errstr != NULL)
- {
- fprintf(stderr, "%s: error: Failed parsing mode '%s': %s\n", argv0, optarg, errstr);
- return 1;
- }
- break;
- case ':':
- fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
- usage();
- return 1;
- case '?':
- fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
- usage();
- return 1;
- default:
- abort();
- }
- }
- argc -= optind;
- argv += optind;
- assert(errno == 0);
- if(argc < 1)
- {
- fprintf(stderr, "%s: error: Missing operand\n", argv0);
- usage();
- return 1;
- }
- for(int i = 0; i < argc; i++)
- {
- int ret = 0;
- if(opt_p)
- ret = mkdir_parents(argv[i], mode);
- else
- ret = mkdir_simple(argv[i], mode);
- if(ret < 0) return 1;
- }
- return 0;
- }