xtc_fs(3)

---

xtc_fs(3)

portable synchronous filesystem helpers

XTC_FS(3) Library Functions Manual XTC_FS(3)

xtc_fs_open, xtc_fs_close, xtc_fs_pread, xtc_fs_pwrite, xtc_fs_fsync, xtc_fs_fdatasync, xtc_fs_ftruncate, xtc_fs_fsize, xtc_fs_stat, xtc_fs_exists, xtc_fs_unlink, xtc_fs_rename, xtc_fs_mkdir, xtc_fs_rmdir, xtc_fs_tmpdir, xtc_fs_mkstemp, xtc_fs_dir_open, xtc_fs_dir_next, xtc_fs_dir_closeportable synchronous filesystem helpers

#include <xtc.h>
#include <xtc_fs.h>

int
xtc_fs_open(const char *path, uint32_t flags, int *out_fd);

int
xtc_fs_close(int fd);

int
xtc_fs_pread(int fd, void *buf, size_t n, int64_t off, size_t *out_done);

int
xtc_fs_pwrite(int fd, const void *buf, size_t n, int64_t off, size_t *out_done);

int
xtc_fs_fsync(int fd);

int
xtc_fs_fdatasync(int fd);

int
xtc_fs_ftruncate(int fd, int64_t len);

int
xtc_fs_fsize(int fd, int64_t *out_size);

int
xtc_fs_stat(const char *path, xtc_fs_stat_t *out);

int
xtc_fs_exists(const char *path);

int
xtc_fs_unlink(const char *path);

int
xtc_fs_rename(const char *from, const char *to);

int
xtc_fs_mkdir(const char *path);

int
xtc_fs_rmdir(const char *path);

int
xtc_fs_tmpdir(char *buf, size_t cap);

int
xtc_fs_mkstemp(char *tmpl, int *out_fd);

int
xtc_fs_dir_open(const char *path, xtc_fs_dir_t **out);

int
xtc_fs_dir_next(xtc_fs_dir_t *d, const char **out_name);

void
xtc_fs_dir_close(xtc_fs_dir_t *d);

These functions are a small, uniform surface over the platform's file API (POSIX file descriptors and directories, or the Win32 equivalents), so callers need not re-roll open(2), stat(2), rename(2), directory walks, and the per-platform quirks (F_FULLFSYNC versus fdatasync(2) versus (), mkstemp(3) versus (), dirent versus ()).

Files are plain int file descriptors, so a handle returned by () or () composes directly with the asynchronous xtc_aio(3) operations and with raw read(2) / write(2).

() opens path according to flags, a bitwise OR of XTC_FS_READ, XTC_FS_WRITE, XTC_FS_CREATE, XTC_FS_TRUNC, XTC_FS_APPEND, and XTC_FS_EXCL, returning the descriptor in *out_fd. () and () perform positioned I/O, retrying on EINTR and EAGAIN and looping until n bytes are transferred or, for a read, end of file is reached; the byte count is returned in *out_done (a short read is end of file, not an error). () makes data and metadata durable; () makes the data durable (the page- and log-flush hot path).

() fills out with the size, last-modified time (nanoseconds since the epoch), and a directory flag. () returns 1 if path exists and 0 otherwise. () replaces to with from atomically.

() writes the temporary directory into buf, honoring TMPDIR, TMP, and TEMP (and falling back to /tmp, or () on Windows), with any trailing separator trimmed. xtc_fs_mkstemp() creates and opens a unique file from a tmpl ending in “XXXXXX”.

(), (), and () iterate a directory's entries, skipping “.” and “..”; xtc_fs_dir_next() sets *out_name to NULL at the end of the directory.

These are blocking calls. On a fiber loop, prefer xtc_aio(3) for the read/write hot path and use these for open, stat, rename, and directory management.

Each function returns XTC_OK (zero) on success or a negative xtc_err_t code on failure: XTC_E_INVAL for a bad argument, XTC_E_NOTFOUND for an absent path, XTC_E_NOMEM on allocation failure, or XTC_E_IO for an underlying I/O error. xtc_fs_exists() returns 1 or 0 and xtc_fs_dir_close() returns nothing.

xtc_aio(3), xtc_strerror(3)

The XTC Project

On Windows the file descriptors are C run-time descriptors; xtc_fs_pread() and xtc_fs_pwrite() use overlapped I/O internally for positioned access and do not disturb a file pointer. xtc_fs_fdatasync() and xtc_fs_fsync() both map to _commit(), which flushes data and metadata.

June 7, 2026 Debian

View the mdoc source