]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/path: add ul_path_stat(), fix absolute paths
authorKarel Zak <kzak@redhat.com>
Tue, 15 Oct 2019 09:59:16 +0000 (11:59 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 15 Oct 2019 09:59:16 +0000 (11:59 +0200)
* 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 <kzak@redhat.com>
include/path.h
lib/path.c

index d39a8ca372c0597e3eccaf30ed63702bf5d1358a..1378a885767e347a62fbff129eba8878e6ffa5af 100644 (file)
@@ -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)));
index 8dce1da408907dc9be249780244489e6753b2a59..64bf7c6f02d1ce311029bc75c012699f6b064962 100644 (file)
@@ -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);
 }