summaryrefslogtreecommitdiff
path: root/src/basic/fileio.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-03-23 12:33:41 +0100
committerLuca Boccassi <luca.boccassi@gmail.com>2023-03-23 22:48:00 +0000
commitb839101aacb38131f0f4313b1b76316e663e58e9 (patch)
tree0bd0c0442cddfb1dc8adcad384f269224c37f98c /src/basic/fileio.c
parent05bda20f073947b77423faca68ef360df5bfa464 (diff)
downloadsystemd-b839101aacb38131f0f4313b1b76316e663e58e9.tar.gz
fileio: add new helper fdopen_independent()
This is a combination of fdopen() and fd_reopen(). i.e. it first reopens the fd, and then converts that into a FILE*. We do this at various places already manually. let's move this into a helper call of its own.
Diffstat (limited to 'src/basic/fileio.c')
-rw-r--r--src/basic/fileio.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index c802db749b..c75981528e 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -1020,6 +1020,35 @@ int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **r
return 0;
}
+int fdopen_independent(int fd, const char *mode, FILE **ret) {
+ _cleanup_close_ int copy_fd = -EBADF;
+ _cleanup_fclose_ FILE *f = NULL;
+ int mode_flags;
+
+ assert(fd >= 0);
+ assert(mode);
+ assert(ret);
+
+ /* A combination of fdopen() + fd_reopen(). i.e. reopens the inode the specified fd points to and
+ * returns a FILE* for it */
+
+ mode_flags = fopen_mode_to_flags(mode);
+ if (mode_flags < 0)
+ return mode_flags;
+
+ copy_fd = fd_reopen(fd, mode_flags);
+ if (copy_fd < 0)
+ return copy_fd;
+
+ f = fdopen(copy_fd, mode);
+ if (!f)
+ return -errno;
+
+ TAKE_FD(copy_fd);
+ *ret = TAKE_PTR(f);
+ return 0;
+}
+
static int search_and_fopen_internal(
const char *path,
const char *mode,