logo

utils-std

Collection of commonly available Unix tools

fs.c (1656B)


  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. // For copy_file_range
  5. #define _GNU_SOURCE // musl, glibc
  6. #define _DEFAULT_SOURCE // FreeBSD
  7. #include "./fs.h"
  8. #include <errno.h>
  9. #include <stdio.h> // BUFSIZ
  10. #include <string.h> // strrchr
  11. #include <unistd.h> // copy_file_range
  12. char *
  13. static_basename(char *path)
  14. {
  15. char *sep = strrchr(path, '/');
  16. return (sep == NULL) ? path : sep + 1;
  17. }
  18. char *
  19. path_split_static(char *path, bool trim)
  20. {
  21. char *child = NULL;
  22. size_t path_len = strlen(path);
  23. // delete trailing slashes
  24. if(trim)
  25. for(int i = path_len - 1; i > 0 && path[i] == '/'; i--)
  26. path[i] = 0;
  27. for(int i = path_len - 1; i > 0; i--)
  28. if(path[i] == '/')
  29. {
  30. path[i] = 0;
  31. child = &path[i + 1];
  32. break;
  33. }
  34. return child;
  35. }
  36. #ifndef MIN
  37. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  38. #endif
  39. int
  40. manual_file_copy(int fd_in, int fd_out, off_t len, int flags)
  41. {
  42. do
  43. {
  44. char buf[BUFSIZ];
  45. ssize_t nread = read(fd_in, buf, MIN(BUFSIZ, len));
  46. if(nread < 0) return nread;
  47. ssize_t nwrite = write(fd_out, buf, (size_t)nread);
  48. if(nwrite < 0) return nwrite;
  49. len -= nwrite;
  50. } while(len > 0);
  51. return 0;
  52. }
  53. #ifdef HAS_COPY_FILE_RANGE
  54. int
  55. auto_file_copy(int fd_in, int fd_out, off_t len, int flags)
  56. {
  57. off_t ret = -1;
  58. do
  59. {
  60. ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
  61. if(ret < 0)
  62. {
  63. if(errno == EXDEV)
  64. {
  65. errno = 0;
  66. return manual_file_copy(fd_in, fd_out, len, flags);
  67. }
  68. return ret;
  69. }
  70. len -= ret;
  71. } while(len > 0 && ret > 0);
  72. return 0;
  73. }
  74. #endif