Inspect source links without following them when COPYFILE_SYM is requested, before rejecting directories. This makes the documented option recreate link text instead of copying the referent, including dangling and directory links. Preserve requested link timestamps and report link-creation errors without overwriting the destination. Cover direct calls, destination directories, normal dereferencing and the existing rsync file caller.
Copy the bytes returned by fread instead of treating each input chunk as a NUL-terminated string. Preserve the public stream positions and report read and write failures rather than returning success after a partial copy. Add binary boundary, current-position, native pipe error and full-device regression coverage.
copyfile() passes the source mode to open(2), which applies the umask,
so a 0644 file copied with umask 0027 ends up 0640.
Apply the source mode with fchmod() after creating the destination.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
mkpath(dir, 0755) with umask 0027 silently creates a 0750 directory,
since mkdir(2) applies the umask to the requested mode. Callers pass
an explicit mode and expect exactly that.
Apply the mode with chmod() after each successful mkdir().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Avoid leaking memory when realloc() fails by using a temporary pointer
and only updating the original on success. Also remove redundant NULL
check before free().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For some builds using Buildroot, the system default _PATH_VARRUN did not
include a trailing slas '/', which cause the pidfile() function to fail.
Example:
pidfile("arg") => "/var/runarg.pid"
Since the __pidfile_path can be overridden we add a check if that prefix
path ends with '/', if not we add one in the path composition.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The runbg() function is a delayed execvp() that has double-forked to the
background (to not create zombies). It is useful for running commands
in the background for APIs that need to return a reply, e.g. a NETCONF
RPC to reboot the system.
Compared to the original in Infix, this version double forks to reparent
itself to PID 1 (init), closes all open files, including stdio.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The tree.h and queue.h include guards must remain so users don't
accidentally get their system queue.h included as well.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Turns out O_TMPFILE can fail in interesting ways when the underlying
filesystem doesn't support unnamed inodes, e.g. Azure used by GitHub
Actions. Here's the exact qoute from open(2):
"O_TMPFILE requires support by the underlying filesystem; only a
subset of Linux filesystems provide that support. In the initial
implementation, support was provided in the ext2, ext3, ext4, UDF,
Minix, and shmem filesystems. Support for other filesystems has
subsequently been added as follows: XFS (Linux 3.15); Btrfs (Linux
3.16); F2FS (Linux 3.16); and ubifs (Linux 4.9)"
This patch adds a silent fallback to tmpfile() in these cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The GNU libtool numbers are just SO confusing.
- New interfaces (new functions) added/removed/changed: 7 -> 8
- Interfaces added: 2 -> 3
End result, steps 5.2.0 to 5.3.0, which makes sense.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Coverity highlighted a problem with logically dead code from the change
prior that triggered this refactor. When system() returns we may have
exited either normally or due to a signal.
My reasoning behind systemf() is to allow users to treat external calls
as any other syscall, abstracting away the WIFFOO() macros. This leaves
us with either the return value of the external program >= 0, or -1 and
errno for everything else. I.e., if fork() or alloca() fails we may get
ENOMEM and if the program doesn't catch signals properly, EINTR.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The call to system() may return -1, e.g. if fork() fails or return
status from execl() cannot be read. In these cases we should end
immediately and not call WIFEXITED() et al.
Also, WEXITSTATUS() should only be called if WEXITED() returns true.
For details, see system(3) and wait(2).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>