From b1418ed14691567b4b1d6fc8b465821e3b060d5d Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 15 Oct 2019 11:59:16 +0200 Subject: [PATCH] lib/path: add ul_path_stat(), fix absolute paths * add ul_path_stat() * make sure all paths for ul_path_..() functions are always interpreted relatively to the context directory and prefix. This is difference between ul_path_ API and standard libc "at" functions. We do not use any exception for absolute paths. The reason is that we need to read from prefixed paths although application assume absolute path (/dev/sda1 means /prefix/dev/sda1 if a /prefix is defined). Signed-off-by: Karel Zak --- include/path.h | 1 + lib/path.c | 62 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/include/path.h b/include/path.h index d39a8ca372..1378a88576 100644 --- a/include/path.h +++ b/include/path.h @@ -45,6 +45,7 @@ int ul_path_isopen_dirfd(struct path_cxt *pc); char *ul_path_get_abspath(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...) __attribute__ ((__format__ (__printf__, 4, 5))); +int ul_path_stat(struct path_cxt *pc, struct stat *sb, const char *path); int ul_path_access(struct path_cxt *pc, int mode, const char *path); int ul_path_accessf(struct path_cxt *pc, int mode, const char *path, ...) __attribute__ ((__format__ (__printf__, 3, 4))); diff --git a/lib/path.c b/lib/path.c index 8dce1da408..64bf7c6f02 100644 --- a/lib/path.c +++ b/lib/path.c @@ -218,7 +218,7 @@ void ul_path_close_dirfd(struct path_cxt *pc) assert(pc); if (pc->dir_fd >= 0) { - DBG(CXT, ul_debugobj(pc, "closing dir: '%s'", pc->dir_path)); + DBG(CXT, ul_debugobj(pc, "closing dir")); close(pc->dir_fd); pc->dir_fd = -1; } @@ -289,19 +289,27 @@ char *ul_path_get_abspath(struct path_cxt *pc, char *buf, size_t bufsz, const ch int ul_path_access(struct path_cxt *pc, int mode, const char *path) { - int dir, rc; - - dir = ul_path_get_dirfd(pc); - if (dir < 0) - return dir; + int rc; - DBG(CXT, ul_debugobj(pc, "access: '%s'", path)); - rc = faccessat(dir, path, mode, 0); + if (!pc) { + rc = access(path, mode); + DBG(CXT, ul_debug("access '%s' [no context, rc=%d]", path, rc)); + } else { + int dir = ul_path_get_dirfd(pc); + if (dir < 0) + return dir; + if (*path == '/') + path++; - if (rc && errno == ENOENT - && pc->redirect_on_enoent - && pc->redirect_on_enoent(pc, path, &dir) == 0) rc = faccessat(dir, path, mode, 0); + + if (rc && errno == ENOENT + && pc->redirect_on_enoent + && pc->redirect_on_enoent(pc, path, &dir) == 0) + rc = faccessat(dir, path, mode, 0); + + DBG(CXT, ul_debugobj(pc, "access: '%s' [rc=%d]", path, rc)); + } return rc; } @@ -317,6 +325,32 @@ int ul_path_accessf(struct path_cxt *pc, int mode, const char *path, ...) return !p ? -errno : ul_path_access(pc, mode, p); } +int ul_path_stat(struct path_cxt *pc, struct stat *sb, const char *path) +{ + int rc; + + if (!pc) { + rc = stat(path, sb); + DBG(CXT, ul_debug("stat '%s' [no context, rc=%d]", path, rc)); + } else { + int dir = ul_path_get_dirfd(pc); + if (dir < 0) + return dir; + if (*path == '/') + path++; + + rc = fstatat(dir, path, sb, 0); + + if (rc && errno == ENOENT + && pc->redirect_on_enoent + && pc->redirect_on_enoent(pc, path, &dir) == 0) + rc = fstatat(dir, path, sb, 0); + + DBG(CXT, ul_debugobj(pc, "stat '%s' [rc=%d]", path, rc)); + } + return rc; +} + int ul_path_open(struct path_cxt *pc, int flags, const char *path) { int fd; @@ -330,6 +364,9 @@ int ul_path_open(struct path_cxt *pc, int flags, const char *path) if (dir < 0) return dir; + if (*path == '/') + path++; + fdx = fd = openat(dir, path, flags); if (fd < 0 && errno == ENOENT @@ -503,6 +540,9 @@ ssize_t ul_path_readlink(struct path_cxt *pc, char *buf, size_t bufsiz, const ch if (dirfd < 0) return dirfd; + if (*path == '/') + path++; + return readlinkat(dirfd, path, buf, bufsiz); } -- 2.47.2