mkdir.c (1243B)
- // 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 "./mkdir.h"
- #include <assert.h>
- #include <errno.h>
- #include <limits.h> // PATH_MAX
- #include <stdio.h> // fprintf
- #include <string.h> // strlen, strerror
- #include <sys/stat.h> // mkdir
- int
- mkdir_parents(char *path, mode_t mode)
- {
- assert(errno == 0);
- for(int i = strlen(path) - 1; i >= 0; i--)
- {
- if(path[i] != '/') break;
- path[i] = 0;
- }
- char parent[PATH_MAX] = "";
- strncpy(parent, path, PATH_MAX);
- for(int i = strlen(parent) - 1; i >= 0; i--)
- {
- if(parent[i] == '/') break;
- parent[i] = 0;
- }
- if(path[0] == 0) return 0;
- mode_t parent_mode = (S_IWUSR | S_IXUSR | ~mkdir_parents_filemask) & 0777;
- if(mkdir_parents(parent, parent_mode) < 0) return -1;
- assert(errno == 0);
- if(mkdir(path, mode) < 0)
- {
- if(errno == EEXIST)
- {
- errno = 0;
- return 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;
- }