summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-04 11:27:08 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-12 11:44:57 +0200
commit02e23d1a1a8c3baf73d82da5abbab3a4eeb1cbf4 (patch)
treea7b7f26ec3058af9278cd4e2e40f87d4232bdf94
parent41f6e627d7cfdf1ea50d5adbd7e118589dbcf8db (diff)
downloadsystemd-02e23d1a1a8c3baf73d82da5abbab3a4eeb1cbf4.tar.gz
Add fdopen_unlocked() wrapper
-rw-r--r--coccinelle/fopen-unlocked.cocci12
-rw-r--r--src/basic/fileio.c20
-rw-r--r--src/basic/fileio.h1
-rw-r--r--src/basic/tmpfile-util.c11
-rw-r--r--src/portable/portable.c10
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)