From fdeea3f4f1c0f78f1014582135d047265098fb82 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 10:17:16 +0200 Subject: [PATCH] Add fopen_unlocked() wrapper --- coccinelle/fopen-unlocked.cocci | 37 ++++++++++++++++++ src/basic/cgroup-util.c | 26 ++++++------- src/basic/fileio.c | 40 ++++++++++++------- src/basic/fileio.h | 2 + src/basic/mountpoint-util.c | 8 ++-- src/basic/process-util.c | 56 ++++++++++----------------- src/cryptsetup/cryptsetup-generator.c | 7 +--- src/shared/mount-util.c | 18 ++++----- 8 files changed, 108 insertions(+), 86 deletions(-) create mode 100644 coccinelle/fopen-unlocked.cocci diff --git a/coccinelle/fopen-unlocked.cocci b/coccinelle/fopen-unlocked.cocci new file mode 100644 index 00000000000..93b993dd556 --- /dev/null +++ b/coccinelle/fopen-unlocked.cocci @@ -0,0 +1,37 @@ +@@ +expression f, path, options; +@@ +- f = fopen(path, options); +- if (!f) +- return -errno; +- (void) __fsetlocking(f, FSETLOCKING_BYCALLER); ++ r = fopen_unlocked(path, options, &f); ++ if (r < 0) ++ return r; +@@ +expression f, path, options; +@@ +- f = fopen(path, options); +- if (!f) { +- if (errno == ENOENT) +- return -ESRCH; +- return -errno; +- } +- (void) __fsetlocking(f, FSETLOCKING_BYCALLER); ++ r = fopen_unlocked(path, options, &f); ++ if (r == -ENOENT) ++ return -ESRCH; ++ if (r < 0) ++ return r; +@@ +expression f, path, options; +@@ +- f = fopen(path, options); +- if (!f) +- return errno == ENOENT ? -ESRCH : -errno; +- (void) __fsetlocking(f, FSETLOCKING_BYCALLER); ++ r = fopen_unlocked(path, options, &f); ++ if (r == -ENOENT) ++ return -ESRCH; ++ if (r < 0) ++ return r; diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index fc28109db8d..11b4e3fce1a 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -1016,11 +1016,11 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { } fs = procfs_file_alloca(pid, "cgroup"); - f = fopen(fs, "re"); - if (!f) - return errno == ENOENT ? -ESRCH : -errno; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(fs, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; for (;;) { _cleanup_free_ char *line = NULL; @@ -2442,17 +2442,13 @@ int cg_kernel_controllers(Set **ret) { if (!controllers) return -ENOMEM; - f = fopen("/proc/cgroups", "re"); - if (!f) { - if (errno == ENOENT) { - *ret = NULL; - return 0; - } - - return -errno; + r = fopen_unlocked("/proc/cgroups", "re", &f); + if (r == -ENOENT) { + *ret = NULL; + return 0; } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + if (r < 0) + return r; /* Ignore the header line */ (void) read_line(f, (size_t) -1, NULL); diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 9ab2f501c76..4599440b45e 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -29,6 +29,19 @@ #define READ_FULL_BYTES_MAX (4U*1024U*1024U) +int fopen_unlocked(const char *path, const char *options, FILE **ret) { + assert(ret); + + FILE *f = fopen(path, options); + if (!f) + return -errno; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + *ret = f; + return 0; +} + int write_string_stream_ts( FILE *f, const char *line, @@ -213,15 +226,14 @@ int write_string_filef( int read_one_line_file(const char *fn, char **line) { _cleanup_fclose_ FILE *f = NULL; + int r; assert(fn); assert(line); - f = fopen(fn, "re"); - if (!f) - return -errno; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(fn, "re", &f); + if (r < 0) + return r; return read_line(f, LONG_LINE_MAX, line); } @@ -230,6 +242,7 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *buf = NULL; size_t l, k; + int r; assert(fn); assert(blob); @@ -243,11 +256,9 @@ int verify_file(const char *fn, const char *blob, bool accept_extra_nl) { if (!buf) return -ENOMEM; - f = fopen(fn, "re"); - if (!f) - return -errno; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(fn, "re", &f); + if (r < 0) + return r; /* We try to read one byte more than we need, so that we know whether we hit eof */ errno = 0; @@ -390,15 +401,14 @@ finalize: int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { _cleanup_fclose_ FILE *f = NULL; + int r; assert(filename); assert(contents); - f = fopen(filename, "re"); - if (!f) - return -errno; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(filename, "re", &f); + if (r < 0) + return r; return read_full_stream_full(f, filename, flags, contents, size); } diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 760e7386884..bee33534392 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -33,6 +33,8 @@ typedef enum { READ_FULL_FILE_UNBASE64 = 1 << 1, } ReadFullFileFlags; +int fopen_unlocked(const char *path, 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) { return write_string_stream_ts(f, line, flags, NULL); diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index 1e946a0bb67..48494320fdb 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -378,11 +378,9 @@ int dev_is_devtmpfs(void) { if (r < 0) return r; - proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); - if (!proc_self_mountinfo) - return -errno; - - (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER); + r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo); + if (r < 0) + return r; for (;;) { _cleanup_free_ char *line = NULL; diff --git a/src/basic/process-util.c b/src/basic/process-util.c index f773eeaffd0..568f400d975 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -106,7 +106,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * char *k; _cleanup_free_ char *ans = NULL; const char *p; - int c; + int c, r; assert(line); assert(pid >= 0); @@ -121,15 +121,11 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * * comm_fallback is false). Returns 0 and sets *line otherwise. */ p = procfs_file_alloca(pid, "cmdline"); - - f = fopen(p, "re"); - if (!f) { - if (errno == ENOENT) - return -ESRCH; - return -errno; - } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; if (max_length == 0) { /* This is supposed to be a safety guard against runaway command lines. */ @@ -513,14 +509,11 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) { return -EINVAL; p = procfs_file_alloca(pid, "status"); - f = fopen(p, "re"); - if (!f) { - if (errno == ENOENT) - return -ESRCH; - return -errno; - } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; for (;;) { _cleanup_free_ char *line = NULL; @@ -602,14 +595,11 @@ int get_process_environ(pid_t pid, char **env) { p = procfs_file_alloca(pid, "environ"); - f = fopen(p, "re"); - if (!f) { - if (errno == ENOENT) - return -ESRCH; - return -errno; - } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(p, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; for (;;) { char c; @@ -895,15 +885,11 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) { path = procfs_file_alloca(pid, "environ"); - f = fopen(path, "re"); - if (!f) { - if (errno == ENOENT) - return -ESRCH; - - return -errno; - } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + r = fopen_unlocked(path, "re", &f); + if (r == -ENOENT) + return -ESRCH; + if (r < 0) + return r; l = strlen(field); for (;;) { diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index e9b21689c72..fbb443c6e26 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -479,15 +478,13 @@ static int add_crypttab_devices(void) { if (!arg_read_crypttab) return 0; - f = fopen("/etc/crypttab", "re"); - if (!f) { + r = fopen_unlocked("/etc/crypttab", "re", &f); + if (r < 0) { if (errno != ENOENT) log_error_errno(errno, "Failed to open /etc/crypttab: %m"); return 0; } - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - if (fstat(fileno(f), &st) < 0) { log_error_errno(errno, "Failed to stat /etc/crypttab: %m"); return 0; diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 9987b6f80ce..1b50716731e 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -40,13 +40,10 @@ int umount_recursive(const char *prefix, int flags) { _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; again = false; - r = 0; - proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); - if (!proc_self_mountinfo) - return -errno; - - (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER); + r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo); + if (r < 0) + return r; for (;;) { _cleanup_free_ char *path = NULL, *p = NULL; @@ -302,12 +299,11 @@ int bind_remount_recursive_with_mountinfo( int bind_remount_recursive(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **blacklist) { _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; + int r; - proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); - if (!proc_self_mountinfo) - return -errno; - - (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER); + r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo); + if (r < 0) + return r; return bind_remount_recursive_with_mountinfo(prefix, new_flags, flags_mask, blacklist, proc_self_mountinfo); } -- 2.39.2