libunixonacid
libskarnet
skalibs
Software
www.skarnet.org

The unix-transactional library interface

The following functions are declared in the skalibs/unix-transactional.h header, and implemented in the libskarnet.a or libskarnet.so library.

General information

unix-transactional provides an API for transactional/reliable filesystem operations.

Most functions are safe wrappers around the Unix *at system calls. They differ from the traditional system calls (safe-wrapped in djbunix and allreadwrite) in that they take an additional argument fd. When file is relative, it is opened relative to the directory associated with the file descriptor fd instead of the current working directory.

If file is absolute, they are equivalent to their djbunix and allreadwrite counterparts.

On systems that do not implement the *at system calls, these functions fall back to changing the current working directory, opening file with the corresponding libstddjb function, and restoring the original working directory using fd_chdir.

Functions

Basic fd operations relative to a directory

int open2_at (int fd, char const *file, int flags)
Safe wrapper around openat() when it takes 2 arguments.

int open3_at (int fd, char const *file, int flags)
Safe wrapper around openat() when it takes 3 arguments.

int access_at (int fd, char const *file, int amode, unsigned int flag)
Calls faccessat() with flags set either to zero, or AT_EACCESS, if flag is nonzero. This function ensures a fall back on platforms without *at system calls.

int stat_at (int fd, char const *file, struct stat *st)
int lstat_at (int fd, char const *file, struct stat *st)
Calls fstatat() without and with the AT_SYMLINK_NOFOLLOW flag, respectively. This function ensures a fall back on platforms without *at system calls.

DIR *opendir_at (int dfd, char const *name)
Relative version of opendir().

int opengetlnclose (char const *file, stralloc *sa, int sep)
int opengetlnclose_at (int dirfd, char const *file, stralloc *sa, int sep)
Slurps file (relative to dirfd in the _at version) into *sa up to (and including) the first sep character. Returns 1 on success, 0 if some bytes were read but no sep was found, -1 EPIPE on immediate EOF and -1 (and sets errno) on error.

size_t openwritenclose_at (int dirfd, char const *file, char const *s, size_t n)
size_t openwritevnclose_at (int dirfd, char const *file, struct iovec const *v, unsigned int n)
Relative versions of openwritenclose_unsafe_sync and openwritevnclose_unsafe_sync in djbunix, except for the fact that they return the number of bytes written instead of just 1 and 0.

The remaining functions are named after their corresponding libstddjb functions.

Atomic filesystem deletion

int atomic_rm_rf (char const *filename)
int atomic_rm_rf_tmp (char const *filename, stralloc *tmp)
Renames filename to a unique name and deletes its filesystem subtree. The difference between these two functions is the same as that between rm_rf and rm_rf_tmp in djbunix.