From 8067fe86ff56ffd89bd11c7537652fcd73f89723 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 30 Mar 2023 10:57:04 +0900 Subject: [PATCH 1/2] test: add tests for fd_get_path() --- src/test/test-fd-util.c | 112 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index bc2eed51354..797b774998d 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -9,6 +9,7 @@ #include "data-fd-util.h" #include "fd-util.h" #include "fileio.h" +#include "fs-util.h" #include "macro.h" #include "memory-util.h" #include "missing_syscall.h" @@ -633,4 +634,115 @@ TEST(dir_fd_is_root) { assert_se(dir_fd_is_root(fd) == 0); } +TEST(fd_get_path) { + _cleanup_(rm_rf_physical_and_freep) char *t = NULL; + _cleanup_close_ int tfd = -EBADF, fd = -EBADF; + _cleanup_free_ char *p = NULL, *q = NULL, *saved_cwd = NULL; + + tfd = mkdtemp_open(NULL, O_PATH, &t); + assert_se(tfd >= 0); + assert_se(fd_get_path(tfd, &p) >= 0); + assert_se(streq(p, t)); + + p = mfree(p); + + assert_se(safe_getcwd(&saved_cwd) >= 0); + assert_se(chdir(t) >= 0); + + assert_se(q = path_join(t, "regular")); + assert_se(touch(q) >= 0); + assert_se(mkdirat_parents(tfd, "subdir/symlink", 0755) >= 0); + assert_se(symlinkat("../regular", tfd, "subdir/symlink") >= 0); + assert_se(symlinkat("subdir", tfd, "symdir") >= 0); + + fd = openat(tfd, "regular", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(AT_FDCWD, "regular", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(tfd, "subdir/symlink", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(AT_FDCWD, "subdir/symlink", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(tfd, "symdir//./symlink", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(AT_FDCWD, "symdir//./symlink", O_CLOEXEC|O_PATH); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) >= 0); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + q = mfree(q); + fd = safe_close(fd); + + assert_se(q = path_join(t, "subdir/symlink")); + fd = openat(tfd, "subdir/symlink", O_CLOEXEC|O_PATH|O_NOFOLLOW); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) == -ELOOP); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(AT_FDCWD, "subdir/symlink", O_CLOEXEC|O_PATH|O_NOFOLLOW); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) == -ELOOP); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(tfd, "symdir//./symlink", O_CLOEXEC|O_PATH|O_NOFOLLOW); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) == -ELOOP); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + p = mfree(p); + fd = safe_close(fd); + + fd = openat(AT_FDCWD, "symdir//./symlink", O_CLOEXEC|O_PATH|O_NOFOLLOW); + assert_se(fd >= 0); + assert_se(fd_verify_regular(fd) == -ELOOP); + assert_se(fd_get_path(fd, &p) >= 0); + assert_se(streq(p, q)); + + assert_se(chdir(saved_cwd) >= 0); +} + DEFINE_TEST_MAIN(LOG_DEBUG); From 46693a7925d209bc215095a568dacbf8337ad288 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 30 Mar 2023 11:42:21 +0900 Subject: [PATCH 2/2] fd-util: make fd_get_path() support AT_FDCWD --- src/basic/fd-util.c | 5 +++++ src/test/test-fd-util.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index b968bf948c4..b58a080d90b 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -534,6 +534,11 @@ bool fdname_is_valid(const char *s) { int fd_get_path(int fd, char **ret) { int r; + assert(fd >= 0 || fd == AT_FDCWD); + + if (fd == AT_FDCWD) + return safe_getcwd(ret); + r = readlink_malloc(FORMAT_PROC_FD_PATH(fd), ret); if (r == -ENOENT) { /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 797b774998d..adcd851d7f5 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -649,6 +649,11 @@ TEST(fd_get_path) { assert_se(safe_getcwd(&saved_cwd) >= 0); assert_se(chdir(t) >= 0); + assert_se(fd_get_path(AT_FDCWD, &p) >= 0); + assert_se(streq(p, t)); + + p = mfree(p); + assert_se(q = path_join(t, "regular")); assert_se(touch(q) >= 0); assert_se(mkdirat_parents(tfd, "subdir/symlink", 0755) >= 0);