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 <kzak@redhat.com>
This commit is contained in:
parent
9ae113ca73
commit
b1418ed146
|
@ -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, ...)
|
char *ul_path_get_abspath(struct path_cxt *pc, char *buf, size_t bufsz, const char *path, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 4, 5)));
|
__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_access(struct path_cxt *pc, int mode, const char *path);
|
||||||
int ul_path_accessf(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)));
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
|
|
48
lib/path.c
48
lib/path.c
|
@ -218,7 +218,7 @@ void ul_path_close_dirfd(struct path_cxt *pc)
|
||||||
assert(pc);
|
assert(pc);
|
||||||
|
|
||||||
if (pc->dir_fd >= 0) {
|
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);
|
close(pc->dir_fd);
|
||||||
pc->dir_fd = -1;
|
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 ul_path_access(struct path_cxt *pc, int mode, const char *path)
|
||||||
{
|
{
|
||||||
int dir, rc;
|
int rc;
|
||||||
|
|
||||||
dir = ul_path_get_dirfd(pc);
|
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)
|
if (dir < 0)
|
||||||
return dir;
|
return dir;
|
||||||
|
if (*path == '/')
|
||||||
|
path++;
|
||||||
|
|
||||||
DBG(CXT, ul_debugobj(pc, "access: '%s'", path));
|
|
||||||
rc = faccessat(dir, path, mode, 0);
|
rc = faccessat(dir, path, mode, 0);
|
||||||
|
|
||||||
if (rc && errno == ENOENT
|
if (rc && errno == ENOENT
|
||||||
&& pc->redirect_on_enoent
|
&& pc->redirect_on_enoent
|
||||||
&& pc->redirect_on_enoent(pc, path, &dir) == 0)
|
&& pc->redirect_on_enoent(pc, path, &dir) == 0)
|
||||||
rc = faccessat(dir, path, mode, 0);
|
rc = faccessat(dir, path, mode, 0);
|
||||||
|
|
||||||
|
DBG(CXT, ul_debugobj(pc, "access: '%s' [rc=%d]", path, rc));
|
||||||
|
}
|
||||||
return 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);
|
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 ul_path_open(struct path_cxt *pc, int flags, const char *path)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -330,6 +364,9 @@ int ul_path_open(struct path_cxt *pc, int flags, const char *path)
|
||||||
if (dir < 0)
|
if (dir < 0)
|
||||||
return dir;
|
return dir;
|
||||||
|
|
||||||
|
if (*path == '/')
|
||||||
|
path++;
|
||||||
|
|
||||||
fdx = fd = openat(dir, path, flags);
|
fdx = fd = openat(dir, path, flags);
|
||||||
|
|
||||||
if (fd < 0 && errno == ENOENT
|
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)
|
if (dirfd < 0)
|
||||||
return dirfd;
|
return dirfd;
|
||||||
|
|
||||||
|
if (*path == '/')
|
||||||
|
path++;
|
||||||
|
|
||||||
return readlinkat(dirfd, path, buf, bufsiz);
|
return readlinkat(dirfd, path, buf, bufsiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue