path.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include "path.h"
  3. #include "cache.h"
  4. #include <linux/kernel.h>
  5. #include <limits.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <dirent.h>
  11. #include <unistd.h>
  12. static char *cleanup_path(char *path)
  13. {
  14. /* Clean it up */
  15. if (!memcmp(path, "./", 2)) {
  16. path += 2;
  17. while (*path == '/')
  18. path++;
  19. }
  20. return path;
  21. }
  22. char *mkpath(char *path_buf, size_t sz, const char *fmt, ...)
  23. {
  24. va_list args;
  25. unsigned len;
  26. va_start(args, fmt);
  27. len = vsnprintf(path_buf, sz, fmt, args);
  28. va_end(args);
  29. if (len >= sz)
  30. strncpy(path_buf, "/bad-path/", sz);
  31. return cleanup_path(path_buf);
  32. }
  33. int path__join(char *bf, size_t size, const char *path1, const char *path2)
  34. {
  35. return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2);
  36. }
  37. int path__join3(char *bf, size_t size, const char *path1, const char *path2, const char *path3)
  38. {
  39. return scnprintf(bf, size, "%s%s%s%s%s", path1, path1[0] ? "/" : "",
  40. path2, path2[0] ? "/" : "", path3);
  41. }
  42. bool is_regular_file(const char *file)
  43. {
  44. struct stat st;
  45. if (stat(file, &st))
  46. return false;
  47. return S_ISREG(st.st_mode);
  48. }
  49. /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */
  50. bool is_directory(const char *base_path, const struct dirent *dent)
  51. {
  52. char path[PATH_MAX];
  53. struct stat st;
  54. snprintf(path, sizeof(path), "%s/%s", base_path, dent->d_name);
  55. if (stat(path, &st))
  56. return false;
  57. return S_ISDIR(st.st_mode);
  58. }
  59. bool is_directory_at(int dir_fd, const char *path)
  60. {
  61. struct stat st;
  62. if (fstatat(dir_fd, path, &st, /*flags=*/0))
  63. return false;
  64. return S_ISDIR(st.st_mode);
  65. }