logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git

mkdir.c (1236B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "./mkdir.h"
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <limits.h> // PATH_MAX
  9. #include <stdio.h> // fprintf
  10. #include <string.h> // strlen, strerror
  11. #include <sys/stat.h> // mkdir
  12. int
  13. mkdir_parents(char *path, mode_t mode)
  14. {
  15. assert(errno == 0);
  16. for(int i = strlen(path) - 1; i >= 0; i--)
  17. {
  18. if(path[i] != '/') break;
  19. path[i] = 0;
  20. }
  21. char parent[PATH_MAX] = "";
  22. strncpy(parent, path, PATH_MAX);
  23. for(int i = strlen(parent) - 1; i >= 0; i--)
  24. {
  25. if(parent[i] == '/') break;
  26. parent[i] = 0;
  27. }
  28. if(path[0] == 0) return 0;
  29. mode_t parent_mode = (S_IWUSR | S_IXUSR | ~mkdir_parents_filemask) & 0777;
  30. if(mkdir_parents(parent, parent_mode) < 0) return -1;
  31. assert(errno == 0);
  32. if(mkdir(path, mode) < 0)
  33. {
  34. if(errno == EEXIST)
  35. {
  36. errno = 0;
  37. return 0;
  38. }
  39. fprintf(stderr, "%s: Failed making directory '%s': %s\n", argv0, path, strerror(errno));
  40. errno = 0;
  41. return -1;
  42. }
  43. if(mkdir_parents_verbose) fprintf(stderr, "%s: Made directory: %s\n", argv0, path);
  44. return 0;
  45. }