24 #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
25 # include <sys/time.h>
26 #elif defined(HAVE__FUTIME)
27 # include <sys/utime.h>
28 #elif defined(HAVE_UTIME)
33 # ifdef HAVE_SYS_CAPSICUM_H
34 # include <sys/capsicum.h>
36 # include <sys/capability.h>
51 #if EAGAIN == EWOULDBLOCK
52 # define IS_EAGAIN_OR_EWOULDBLOCK(e) ((e) == EAGAIN)
54 # define IS_EAGAIN_OR_EWOULDBLOCK(e) \
55 ((e) == EAGAIN || (e) == EWOULDBLOCK)
71 static bool sandbox_allowed =
false;
74 #ifndef TUKLIB_DOSLIKE
103 #ifndef TUKLIB_DOSLIKE
114 for (
unsigned i = 0;
i < 2; ++
i) {
126 _djstat_flags = _STAT_EXEC_EXT | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
133 #ifndef TUKLIB_DOSLIKE
158 #ifdef ENABLE_SANDBOX
160 io_allow_sandbox(
void)
162 sandbox_allowed =
true;
170 io_sandbox_enter(
int src_fd)
172 if (!sandbox_allowed) {
181 const char dummy_str[] =
"x";
195 if (cap_rights_limit(src_fd, cap_rights_init(&rights,
196 CAP_EVENT, CAP_FCNTL, CAP_LOOKUP, CAP_READ, CAP_SEEK)))
200 CAP_EVENT, CAP_FCNTL, CAP_FSTAT, CAP_LOOKUP,
201 CAP_WRITE, CAP_SEEK)))
216 # error ENABLE_SANDBOX is defined but no sandboxing method was found.
229 #ifndef TUKLIB_DOSLIKE
247 pfd[0].events = POLLIN;
250 pfd[0].events = POLLOUT;
254 pfd[1].events = POLLIN;
276 if (pfd[0].revents != 0)
292 #if defined(TUKLIB_DOSLIKE)
315 || memcmp(&new_st.st_ino, &known_st->st_ino,
316 sizeof(new_st.st_ino)) != 0
319 || new_st.st_dev != known_st->st_dev
320 || new_st.st_ino != known_st->st_ino
334 "not removing"),
name);
341 name, strerror(errno));
355 #ifndef TUKLIB_DOSLIKE
383 & (pair->
src_st.st_mode & 0007);
404 # if defined(HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
406 atime_nsec = pair->
src_st.st_atim.tv_nsec;
407 mtime_nsec = pair->
src_st.st_mtim.tv_nsec;
409 # elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
411 atime_nsec = pair->
src_st.st_atimespec.tv_nsec;
412 mtime_nsec = pair->
src_st.st_mtimespec.tv_nsec;
414 # elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
416 atime_nsec = pair->
src_st.st_atimensec;
417 mtime_nsec = pair->
src_st.st_mtimensec;
419 # elif defined(HAVE_STRUCT_STAT_ST_UATIME)
421 atime_nsec = pair->
src_st.st_uatime * 1000;
422 mtime_nsec = pair->
src_st.st_umtime * 1000;
424 # elif defined(HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC)
426 atime_nsec = pair->
src_st.st_atim.st__tim.tv_nsec;
427 mtime_nsec = pair->
src_st.st_mtim.st__tim.tv_nsec;
437 #if defined(HAVE_FUTIMENS)
440 tv[0].tv_sec = pair->
src_st.st_atime;
441 tv[0].tv_nsec = atime_nsec;
442 tv[1].tv_sec = pair->
src_st.st_mtime;
443 tv[1].tv_nsec = mtime_nsec;
447 #elif defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
450 tv[0].tv_sec = pair->
src_st.st_atime;
451 tv[0].tv_usec = atime_nsec / 1000;
452 tv[1].tv_sec = pair->
src_st.st_mtime;
453 tv[1].tv_usec = mtime_nsec / 1000;
455 # if defined(HAVE_FUTIMES)
457 # elif defined(HAVE_FUTIMESAT)
464 #elif defined(HAVE__FUTIME)
469 struct _utimbuf
buf = {
470 .actime = pair->
src_st.st_atime,
471 .modtime = pair->
src_st.st_mtime,
480 #elif defined(HAVE_UTIME)
485 .actime = pair->
src_st.st_atime,
486 .modtime = pair->
src_st.st_mtime,
507 #ifdef TUKLIB_DOSLIKE
518 "from standard input: %s"),
528 #ifdef HAVE_POSIX_FADVISE
533 : POSIX_FADV_SEQUENTIAL);
550 #ifndef TUKLIB_DOSLIKE
559 #if defined(O_NOFOLLOW)
560 if (!follow_symlinks)
562 #elif !defined(TUKLIB_DOSLIKE)
566 if (!follow_symlinks) {
573 }
else if (S_ISLNK(st.st_mode)) {
581 (void)follow_symlinks;
609 bool was_symlink =
false;
611 # if defined(__FreeBSD__) || defined(__DragonFly__)
615 # elif defined(__digital__) && defined(__unix__)
616 if (errno == ENOTSUP)
619 # elif defined(__NetBSD__)
624 if (errno == ELOOP && !follow_symlinks) {
625 const int saved_errno = errno;
628 && S_ISLNK(st.st_mode))
676 #ifndef TUKLIB_DOSLIKE
678 if (pair->
src_st.st_mode & (S_ISUID | S_ISGID)) {
689 "setgid bit set, skipping"),
694 if (pair->
src_st.st_mode & S_ISVTX) {
701 if (pair->
src_st.st_nlink > 1) {
703 "than one hard link, "
722 #ifdef HAVE_POSIX_FADVISE
724 (void)posix_fadvise(pair->
src_fd, 0, 0,
727 : POSIX_FADV_SEQUENTIAL);
756 .src_has_seen_input =
false,
757 .flush_needed =
false,
758 .dest_try_sparse =
false,
759 .dest_pending_sparse = 0,
768 #ifdef ENABLE_SANDBOX
770 io_sandbox_enter(pair.
src_fd);
785 #ifndef TUKLIB_DOSLIKE
793 "to standard input: %s"),
828 #ifdef TUKLIB_DOSLIKE
841 "from standard output: %s"),
860 if (st.st_dev == -1) {
862 "a DOS special file",
869 if (st.st_dev == pair->
src_st.st_dev
870 && st.st_ino == pair->
src_st.st_ino) {
891 #ifndef TUKLIB_DOSLIKE
905 #ifndef TUKLIB_DOSLIKE
1010 #ifndef TUKLIB_DOSLIKE
1019 "to standard output: %s"),
1067 "to create a sparse file: %s"),
1071 const uint8_t zero[1] = {
'\0' };
1105 if (rewind_size > 0) {
1133 if (errno ==
EINTR) {
1140 #ifndef TUKLIB_DOSLIKE
1200 if (amount !=
size) {
1216 if (
buf->u64[
i] != 0)
1231 if (errno ==
EINTR) {
1238 #ifndef TUKLIB_DOSLIKE
1293 const off_t pending_max
1300 }
else if (
size == 0) {
1310 "trying to create a sparse "
const char stdin_filename[]
enum operation_mode opt_mode
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval tv
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count fchmod
static static fork const void static count close
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset fstat
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep lseek
static bool io_open_dest_real(file_pair *pair)
static void io_copy_attrs(const file_pair *pair)
Copies owner/group and permissions.
#define IS_EAGAIN_OR_EWOULDBLOCK(e)
static bool restore_stdout_flags
void io_no_sparse(void)
Disable creation of sparse files when decompressing.
static bool io_close_dest(file_pair *pair, bool success)
Closes destination file of the file_pair structure.
void io_write_to_user_abort_pipe(void)
Write a byte to user_abort_pipe[1].
bool io_write(file_pair *pair, const io_buf *buf, size_t size)
Writes a buffer to the destination file.
void io_init(void)
Initialize the I/O module.
bool io_open_dest(file_pair *pair)
Open the destination file.
static bool is_sparse(const io_buf *buf)
static io_wait_ret io_wait(file_pair *pair, int timeout, bool is_reading)
Waits for input or output to become available or for a signal.
static bool restore_stdin_flags
static void io_unlink(const char *name, const struct stat *known_st)
Unlink a file.
void io_close(file_pair *pair, bool success)
Closes the file descriptors and frees possible allocated memory.
static bool try_sparse
If true, try to create sparse files when decompressing.
void io_fix_src_pos(file_pair *pair, size_t rewind_size)
Fix the position in src_fd.
static void io_close_src(file_pair *pair, bool success)
Closes source file of the file_pair structure.
file_pair * io_open_src(const char *src_name)
Open the source file.
static bool io_write_buf(file_pair *pair, const uint8_t *buf, size_t size)
size_t io_read(file_pair *pair, io_buf *buf, size_t size)
Reads from the source file to a buffer.
static int user_abort_pipe[2]
static bool io_open_src_real(file_pair *pair)
Opens the source file. Returns false on success, true on error.
bool io_pread(file_pair *pair, io_buf *buf, size_t size, off_t pos)
Read from source file from given offset to a buffer.
RZ_API void Ht_() free(HtName_(Ht) *ht)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds utime
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage struct sysinfo static info unsigned static __unused struct utsname static buf const char static size const char static name static pid unsigned static persona static fsgid const void static flags const struct iovec static count static fd const void static len static munlockall struct sched_param static p static sched_yield static policy const struct timespec struct timespec static rem uid_t uid_t uid_t static suid poll
static static fork const void static count static fd const char static mode unlink
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname pipe
assert(limit<=UINT32_MAX/2)
void message_error(const char *fmt,...)
void message_warning(const char *fmt,...)
void message_fatal(const char *fmt,...)
int mytime_get_flush_timeout(void)
Get the number of milliseconds until the next flush.
void mytime_set_flush_time(void)
Store the time of when compressor was flushed.
static struct sockaddr static addrlen static backlog const void static flags void flags
volatile sig_atomic_t user_abort
void signals_unblock(void)
Unblock the signals blocked by signals_block().
struct stat dest_st
Stat of the destination file.
bool flush_needed
For –flush-timeout: True when flushing is needed.
off_t dest_pending_sparse
int dest_fd
File descriptor of the target file.
struct stat src_st
Stat of the source file.
int src_fd
File descriptor of the source file.
bool src_eof
True once end of the source file has been detected.
Common includes, definitions, and prototypes.
bool is_empty_filename(const char *filename)
Check if filename is empty and print an error message.
char * suffix_get_dest_name(const char *src_name)
Get the name of the destination file.
#define tuklib_mbstr_width
void tuklib_open_stdxxx(int err_status)
Make sure that file descriptors 0, 1, and 2 are open.
void error(const char *msg)
int read(izstream &zs, T *x, Items items)