From 02e23d1a1a8c3baf73d82da5abbab3a4eeb1cbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 11:27:08 +0200 Subject: [PATCH] Add fdopen_unlocked() wrapper --- coccinelle/fopen-unlocked.cocci | 12 ++++++++++++ src/basic/fileio.c | 20 +++++++++++++++----- src/basic/fileio.h | 1 + src/basic/tmpfile-util.c | 11 +++++------ src/portable/portable.c | 10 ++++------ 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/coccinelle/fopen-unlocked.cocci b/coccinelle/fopen-unlocked.cocci index e6f2bc5681..bbd70a6338 100644 --- a/coccinelle/fopen-unlocked.cocci +++ b/coccinelle/fopen-unlocked.cocci @@ -49,3 +49,15 @@ expression f, g, path, p; if (r < 0) return ...; - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); +@@ +expression f, fd, options; +@@ +- f = fdopen(fd, options); ++ r = fdopen_unlocked(fd, options, &f); ++ if (r < 0) { +- if (!f) { + ... +- return -errno; ++ return r; + } +- (void) __fsetlocking(f, FSETLOCKING_BYCALLER); diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 2318f407b8..af22ec9110 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -42,6 +42,19 @@ int fopen_unlocked(const char *path, const char *options, FILE **ret) { return 0; } +int fdopen_unlocked(int fd, const char *options, FILE **ret) { + assert(ret); + + FILE *f = fdopen(fd, options); + if (!f) + return -errno; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + *ret = f; + return 0; +} + int write_string_stream_ts( FILE *f, const char *line, @@ -167,14 +180,11 @@ int write_string_file_ts( goto fail; } - f = fdopen(fd, "w"); - if (!f) { - r = -errno; + r = fdopen_unlocked(fd, "w", &f); + if (r < 0) { safe_close(fd); goto fail; } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); } if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) diff --git a/src/basic/fileio.h b/src/basic/fileio.h index bee3353439..7903b57c80 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -34,6 +34,7 @@ typedef enum { } ReadFullFileFlags; int fopen_unlocked(const char *path, const char *options, FILE **ret); +int fdopen_unlocked(int fd, const char *options, FILE **ret); int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { diff --git a/src/basic/tmpfile-util.c b/src/basic/tmpfile-util.c index 260443a1d6..3ed91520b9 100644 --- a/src/basic/tmpfile-util.c +++ b/src/basic/tmpfile-util.c @@ -6,6 +6,7 @@ #include "alloc-util.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "hexdecoct.h" #include "macro.h" @@ -42,16 +43,14 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { /* This assumes that returned FILE object is short-lived and used within the same single-threaded * context and never shared externally, hence locking is not necessary. */ - f = fdopen(fd, "w"); - if (!f) { - unlink_noerrno(t); + r = fdopen_unlocked(fd, "w", &f); + if (r < 0) { + unlink(t); free(t); safe_close(fd); - return -errno; + return r; } - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - *_f = f; *_temp_path = t; diff --git a/src/portable/portable.c b/src/portable/portable.c index 9b6cc21d2c..4aa879801f 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -1091,12 +1091,10 @@ static int test_chroot_dropin( return log_debug_errno(errno, "Failed to open %s/%s: %m", where, p); } - f = fdopen(fd, "r"); - if (!f) - return log_debug_errno(errno, "Failed to convert file handle: %m"); - fd = -1; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fdopen_unlocked(fd, "r", &f); + if (r < 0) + return log_debug_errno(r, "Failed to convert file handle: %m"); + TAKE_FD(fd); r = read_line(f, LONG_LINE_MAX, &line); if (r < 0)