fs.c (1656B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- // For copy_file_range
- #define _GNU_SOURCE // musl, glibc
- #define _DEFAULT_SOURCE // FreeBSD
- #include "./fs.h"
- #include <errno.h>
- #include <stdio.h> // BUFSIZ
- #include <string.h> // strrchr
- #include <unistd.h> // copy_file_range
- char *
- static_basename(char *path)
- {
- char *sep = strrchr(path, '/');
- return (sep == NULL) ? path : sep + 1;
- }
- char *
- path_split_static(char *path, bool trim)
- {
- char *child = NULL;
- size_t path_len = strlen(path);
- // delete trailing slashes
- if(trim)
- for(int i = path_len - 1; i > 0 && path[i] == '/'; i--)
- path[i] = 0;
- for(int i = path_len - 1; i > 0; i--)
- if(path[i] == '/')
- {
- path[i] = 0;
- child = &path[i + 1];
- break;
- }
- return child;
- }
- #ifndef MIN
- #define MIN(a, b) (((a) < (b)) ? (a) : (b))
- #endif
- int
- manual_file_copy(int fd_in, int fd_out, off_t len, int flags)
- {
- do
- {
- char buf[BUFSIZ];
- ssize_t nread = read(fd_in, buf, MIN(BUFSIZ, len));
- if(nread < 0) return nread;
- ssize_t nwrite = write(fd_out, buf, (size_t)nread);
- if(nwrite < 0) return nwrite;
- len -= nwrite;
- } while(len > 0);
- return 0;
- }
- #ifdef HAS_COPY_FILE_RANGE
- int
- auto_file_copy(int fd_in, int fd_out, off_t len, int flags)
- {
- off_t ret = -1;
- do
- {
- ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
- if(ret < 0)
- {
- if(errno == EXDEV)
- {
- errno = 0;
- return manual_file_copy(fd_in, fd_out, len, flags);
- }
- return ret;
- }
- len -= ret;
- } while(len > 0 && ret > 0);
- return 0;
- }
- #endif