From: Karel Zak Date: Tue, 30 Jun 2026 15:08:53 +0000 (+0200) Subject: lib/path: add VFS support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cb720116485e0a1c4e6cca1afeffb766b31e11c;p=thirdparty%2Futil-linux.git lib/path: add VFS support Add ul_path_refer_vfs() to set a borrowed VFS ops pointer on path_cxt. Replace direct I/O in the read/write/fopen paths with VFS dispatch: - ul_path_read(): ul_vfs_read_all + ul_vfs_close - ul_path_write_string(): ul_vfs_write_all + ul_vfs_close - ul_path_write_s64/u64(): ul_vfs_write_all + ul_vfs_close - ul_path_fopen(): ul_vfs_fdopen (fopencookie when VFS set) Addresses: https://github.com/util-linux/util-linux/issues/4308 Signed-off-by: Karel Zak --- diff --git a/include/path.h b/include/path.h index 84bd42c6d..a54651c42 100644 --- a/include/path.h +++ b/include/path.h @@ -25,6 +25,8 @@ struct path_cxt { void *dialect; void (*free_dialect)(struct path_cxt *); int (*redirect_on_enoent)(struct path_cxt *, const char *, int *); + + const struct ul_vfs_ops *vfs; }; struct path_cxt *ul_new_path(const char *dir, ...) @@ -44,6 +46,9 @@ int ul_path_set_dialect(struct path_cxt *pc, void *data, void free_data(struct p void *ul_path_get_dialect(struct path_cxt *pc); int ul_path_set_enoent_redirect(struct path_cxt *pc, int (*func)(struct path_cxt *, const char *, int *)); + +struct ul_vfs_ops; +void ul_path_refer_vfs(struct path_cxt *pc, const struct ul_vfs_ops *vfs); int ul_path_get_dirfd(struct path_cxt *pc); void ul_path_close_dirfd(struct path_cxt *pc); int ul_path_isopen_dirfd(struct path_cxt *pc); diff --git a/lib/path.c b/lib/path.c index 65a7b5648..90aac2058 100644 --- a/lib/path.c +++ b/lib/path.c @@ -102,6 +102,12 @@ void ul_unref_path(struct path_cxt *pc) } } +void ul_path_refer_vfs(struct path_cxt *pc, const struct ul_vfs_ops *vfs) +{ + if (pc) + pc->vfs = vfs; +} + int ul_path_set_prefix(struct path_cxt *pc, const char *prefix) { char *p = NULL; @@ -511,7 +517,7 @@ FILE *ul_path_fopen(struct path_cxt *pc, const char *mode, const char *path) if (fd < 0) return NULL; - return fdopen(fd, mode); + return ul_vfs_fdopen(pc ? pc->vfs : NULL, fd, mode); } @@ -649,10 +655,10 @@ int ul_path_read(struct path_cxt *pc, char *buf, size_t len, const char *path) return -errno; DBG(CXT, ul_debug(" reading '%s'", path)); - rc = ul_read_all(fd, buf, len); + rc = ul_vfs_read_all(pc ? pc->vfs : NULL, fd, buf, len); errsv = errno; - close(fd); + ul_vfs_close(pc ? pc->vfs : NULL, fd); errno = errsv; return rc; } @@ -926,10 +932,10 @@ int ul_path_write_string(struct path_cxt *pc, const char *str, const char *path) if (fd < 0) return -errno; - rc = ul_write_all(fd, str, strlen(str)); + rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, str, strlen(str)); errsv = errno; - close(fd); + ul_vfs_close(pc ? pc->vfs : NULL, fd); errno = errsv; return rc; } @@ -960,10 +966,10 @@ int ul_path_write_s64(struct path_cxt *pc, int64_t num, const char *path) if (len < 0 || (size_t) len >= sizeof(buf)) rc = len < 0 ? -errno : -E2BIG; else - rc = ul_write_all(fd, buf, len); + rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, buf, len); errsv = errno; - close(fd); + ul_vfs_close(pc ? pc->vfs : NULL, fd); errno = errsv; return rc; } @@ -982,10 +988,10 @@ int ul_path_write_u64(struct path_cxt *pc, uint64_t num, const char *path) if (len < 0 || (size_t) len >= sizeof(buf)) rc = len < 0 ? -errno : -E2BIG; else - rc = ul_write_all(fd, buf, len); + rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, buf, len); errsv = errno; - close(fd); + ul_vfs_close(pc ? pc->vfs : NULL, fd); errno = errsv; return rc; }