]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
file_utils: add fdopenat()
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 1 Feb 2021 10:11:15 +0000 (11:11 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 1 Feb 2021 10:32:46 +0000 (11:32 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/file_utils.c
src/lxc/file_utils.h
src/lxc/utils.c
src/lxc/utils.h

index 02856153ac15d161f627e72aacc2c099c7ebd12e..5e88cf893bc1e80e654cfbea6345d6a9c626b7a5 100644 (file)
@@ -517,6 +517,64 @@ FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer)
        return f;
 }
 
+int fd_cloexec(int fd, bool cloexec)
+{
+       int oflags, nflags;
+
+       oflags = fcntl(fd, F_GETFD, 0);
+       if (oflags < 0)
+               return -errno;
+
+       if (cloexec)
+               nflags = oflags | FD_CLOEXEC;
+       else
+               nflags = oflags & ~FD_CLOEXEC;
+
+       if (nflags == oflags)
+               return 0;
+
+       if (fcntl(fd, F_SETFD, nflags) < 0)
+               return -errno;
+
+       return 0;
+}
+
+static inline int dup_cloexec(int fd)
+{
+       __do_close int fd_dup = -EBADF;
+
+       fd_dup = dup(fd);
+       if (fd_dup < 0)
+               return -errno;
+
+       if (fd_cloexec(fd_dup, true))
+               return -errno;
+
+       return move_fd(fd_dup);
+}
+
+FILE *fdopenat(int dfd, const char *path, const char *mode)
+{
+       __do_close int fd = -EBADF;
+       __do_fclose FILE *f = NULL;
+
+       if (is_empty_string(path))
+               fd = dup_cloexec(dfd);
+       else
+               fd = openat(dfd, path, O_CLOEXEC | O_NOCTTY | O_NOFOLLOW);
+       if (fd < 0)
+               return NULL;
+
+       f = fdopen(fd, "re");
+       if (!f)
+               return NULL;
+
+       /* Transfer ownership of fd. */
+       move_fd(fd);
+
+       return move_ptr(f);
+}
+
 int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset)
 {
        __do_close int fd = -EBADF;
index 7652b09ff405b28dbe6b77e15618783409691631..2091f7e49a40bf392037f5d49046d5595d733478 100644 (file)
@@ -73,8 +73,10 @@ static inline int fd_to_fd(int from, int to)
 {
        return __fd_to_fd(from, to) >= 0;
 }
+__hidden extern int fd_cloexec(int fd, bool cloexec);
 __hidden extern int lxc_open_dirfd(const char *dir);
 __hidden extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer);
+__hidden extern FILE *fdopenat(int dfd, const char *path, const char *mode);
 __hidden extern FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer);
 __hidden extern int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset);
 __hidden extern bool exists_dir_at(int dir_fd, const char *path);
index bb7074cca6e54f001f77eeabd7ebec95334d533b..ad2d6eea04bb1fad76e73c6656ee67ea4ca787e4 100644 (file)
@@ -1779,28 +1779,6 @@ int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd)
        return 0;
 }
 
-int fd_cloexec(int fd, bool cloexec)
-{
-       int oflags, nflags;
-
-       oflags = fcntl(fd, F_GETFD, 0);
-       if (oflags < 0)
-               return -errno;
-
-       if (cloexec)
-               nflags = oflags | FD_CLOEXEC;
-       else
-               nflags = oflags & ~FD_CLOEXEC;
-
-       if (nflags == oflags)
-               return 0;
-
-       if (fcntl(fd, F_SETFD, nflags) < 0)
-               return -errno;
-
-       return 0;
-}
-
 int lxc_rm_rf(const char *dirname)
 {
        __do_closedir DIR *dir = NULL;
index 4825599c4e0186c4765127bd1d092fe69a4e5424..c3dc5cfb9f9fef7e79de4e8e5bf9790861fa3dfc 100644 (file)
@@ -223,7 +223,6 @@ __hidden extern uint64_t lxc_find_next_power2(uint64_t n);
 
 /* Set a signal the child process will receive after the parent has died. */
 __hidden extern int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd);
-__hidden extern int fd_cloexec(int fd, bool cloexec);
 __hidden extern int lxc_rm_rf(const char *dirname);
 __hidden extern bool lxc_can_use_pidfd(int pidfd);