From: Daan De Meyer Date: Thu, 23 Mar 2023 13:30:43 +0000 (+0100) Subject: fs-util: Allow xopenat() to reopen existing file descriptors X-Git-Tag: v254-rc1~944^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=06ca2db39dc959a5b40690b309417d66659061ad;p=thirdparty%2Fsystemd.git fs-util: Allow xopenat() to reopen existing file descriptors --- diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 06bd5705f28..257c11ad715 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -1104,6 +1104,11 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); + if (isempty(path)) { + assert(!FLAGS_SET(flags, O_CREAT|O_EXCL)); + return fd_reopen(dir_fd, flags); + } + if (FLAGS_SET(flags, O_DIRECTORY|O_CREAT)) { r = RET_NERRNO(mkdirat(dir_fd, path, mode)); if (r == -EEXIST) { diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 2ad9c5b565a..0f942f6dcbb 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -1223,7 +1223,7 @@ TEST(openat_report_new) { TEST(xopenat) { _cleanup_(rm_rf_physical_and_freep) char *t = NULL; - _cleanup_close_ int tfd = -EBADF, fd = -EBADF; + _cleanup_close_ int tfd = -EBADF, fd = -EBADF, fd2 = -EBADF; assert_se((tfd = mkdtemp_open(NULL, 0, &t)) >= 0); @@ -1244,6 +1244,11 @@ TEST(xopenat) { assert_se((fd = xopenat(tfd, "def", O_CREAT|O_EXCL|O_CLOEXEC, 0644)) >= 0); assert_se(fd_verify_regular(fd) >= 0); fd = safe_close(fd); + + /* Test that we can reopen an existing fd with xopenat() by specifying an empty path. */ + + assert_se((fd = xopenat(tfd, "def", O_PATH|O_CLOEXEC, 0)) >= 0); + assert_se((fd2 = xopenat(fd, "", O_RDWR|O_CLOEXEC, 0644)) >= 0); } TEST(xopenat_lock) {