mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-17 07:43:44 +00:00
Low: unix: new qb_sys_unlink_or_truncate{,_at} helpers
These are intended for subsequent qb_rb_{force_,}close refactorization
and utilization of this new truncate as a fallback after unlink failure
as detailed in the commit to follow.
For newer POSIX revision compliant systems, there's "at" variant using
openat/unlinkat functions so that paths do not have to be traversed
in full anew when not needed (as both unlink and truncate operate on
the same path).
This commit is contained in:
parent
189ca28db9
commit
7286215ec7
@ -217,7 +217,8 @@ AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \
|
||||
pthread_mutexattr_setpshared \
|
||||
pthread_condattr_setpshared \
|
||||
sem_timedwait semtimedop \
|
||||
getpeerucred getpeereid])
|
||||
getpeerucred getpeereid \
|
||||
openat unlinkat])
|
||||
|
||||
AM_CONDITIONAL(HAVE_SEM_TIMEDWAIT,
|
||||
[test "x$ac_cv_func_sem_timedwait" = xyes])
|
||||
|
||||
49
lib/unix.c
49
lib/unix.c
@ -255,6 +255,55 @@ qb_sys_fd_nonblock_cloexec_set(int32_t fd)
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_sys_unlink_or_truncate(const char *path, int32_t truncate_fallback)
|
||||
{
|
||||
int32_t res = 0;
|
||||
|
||||
if (unlink(path) == -1) {
|
||||
res = errno;
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"Unlinking file: %s",
|
||||
path);
|
||||
if (res != ENOENT && truncate_fallback) {
|
||||
res = errno = 0;
|
||||
if (truncate(path, 0) == -1) {
|
||||
res = errno;
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"Truncating file: %s", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -res;
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT)
|
||||
int32_t
|
||||
qb_sys_unlink_or_truncate_at(int32_t dirfd, const char *path,
|
||||
int32_t truncate_fallback)
|
||||
{
|
||||
int32_t fd, res = 0;
|
||||
|
||||
if (unlinkat(dirfd, path, 0) == -1) {
|
||||
res = errno;
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"Unlinking file at dir: %s", path);
|
||||
if (res != ENOENT && truncate_fallback) {
|
||||
res = errno = 0;
|
||||
if ((fd = openat(dirfd, path, O_WRONLY|O_TRUNC)) == -1) {
|
||||
res = errno;
|
||||
qb_util_perror(LOG_DEBUG,
|
||||
"Truncating file at dir: %s",
|
||||
path);
|
||||
} else {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -res;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
qb_sigpipe_ctl(enum qb_sigpipe_ctl ctl)
|
||||
{
|
||||
|
||||
@ -83,6 +83,25 @@ int32_t qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes);
|
||||
*/
|
||||
int32_t qb_sys_fd_nonblock_cloexec_set(int32_t fd);
|
||||
|
||||
/**
|
||||
* Try to unlink file, and possibly truncate it as a fallback.
|
||||
* @param path the file to be unlinked or truncated.
|
||||
* @param truncate_fallback whether to truncate the file when unlink fails.
|
||||
* @return 0 (success) or -errno
|
||||
*/
|
||||
int32_t qb_sys_unlink_or_truncate(const char *path, int32_t truncate_fallback);
|
||||
|
||||
#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT)
|
||||
/**
|
||||
* Try to unlinkat file, and possibly truncate it as a fallback ("at" variant).
|
||||
* @param path the file to be unlinked or truncated.
|
||||
* @param truncate_fallback whether to truncate the file when unlink fails.
|
||||
* @return 0 (success) or -errno
|
||||
*/
|
||||
int32_t qb_sys_unlink_or_truncate_at(int32_t dirfd, const char *path,
|
||||
int32_t truncate_fallback);
|
||||
#endif
|
||||
|
||||
enum qb_sigpipe_ctl {
|
||||
QB_SIGPIPE_IGNORE,
|
||||
QB_SIGPIPE_DEFAULT,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user