From 2fbe635a83a79f8889afec421ae3990ea106fb91 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 13 Sep 2012 22:30:26 +0200 Subject: [PATCH 1/1] macro: introduce _cleanup_free_ macro for automatic freeing of scoped vars and make use of it --- src/core/hostname-setup.c | 3 +- src/core/load-fragment.c | 6 +-- src/shared/macro.h | 3 ++ src/shared/util.c | 90 ++++++++++++++++----------------------- src/shared/util.h | 3 ++ 5 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c index 25ea09c73..120024065 100644 --- a/src/core/hostname-setup.c +++ b/src/core/hostname-setup.c @@ -67,7 +67,7 @@ static int read_distro_hostname(char **hn) { #if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) int r; - FILE *f; + _cleanup_fclose_ FILE *f = NULL; assert(hn); @@ -114,7 +114,6 @@ static int read_distro_hostname(char **hn) { r = -ENOENT; finish: - fclose(f); return r; #elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 482d28b79..1f3da70ac 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1469,7 +1469,7 @@ int config_parse_unit_condition_path( Unit *u = data; bool trigger, negate; Condition *c; - char *p; + _cleanup_free_ char *p = NULL; assert(filename); assert(lvalue); @@ -1496,7 +1496,6 @@ int config_parse_unit_condition_path( c = condition_new(cond, p, trigger, negate); if (!c) return -ENOMEM; - free(p); LIST_PREPEND(Condition, conditions, u->conditions, c); return 0; @@ -1516,7 +1515,7 @@ int config_parse_unit_condition_string( Unit *u = data; bool trigger, negate; Condition *c; - char *s; + _cleanup_free_ char *s = NULL; assert(filename); assert(lvalue); @@ -1538,7 +1537,6 @@ int config_parse_unit_condition_string( c = condition_new(cond, s, trigger, negate); if (!c) return log_oom(); - free(s); LIST_PREPEND(Condition, conditions, u->conditions, c); return 0; diff --git a/src/shared/macro.h b/src/shared/macro.h index 459575039..df17617b1 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -187,4 +187,7 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { return k; } +#define _cleanup_free_ __attribute__((cleanup(freep))) +#define _cleanup_fclose_ __attribute__((cleanup(fclosep))) + #include "log.h" diff --git a/src/shared/util.c b/src/shared/util.c index eaf272138..887cc6749 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -489,7 +489,7 @@ char *split_quoted(const char *c, size_t *l, char **state) { int get_parent_of_pid(pid_t pid, pid_t *_ppid) { int r; - FILE *f; + _cleanup_fclose_ FILE *f = NULL; char fn[PATH_MAX], line[LINE_MAX], *p; long unsigned ppid; @@ -499,22 +499,22 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) { assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); char_array_0(fn); - if (!(f = fopen(fn, "re"))) + f = fopen(fn, "re"); + if (!f) return -errno; - if (!(fgets(line, sizeof(line), f))) { + if (!fgets(line, sizeof(line), f)) { r = feof(f) ? -EIO : -errno; fclose(f); return r; } - fclose(f); - /* Let's skip the pid and comm fields. The latter is enclosed * in () but does not escape any () in its value, so let's * skip over it manually */ - if (!(p = strrchr(line, ')'))) + p = strrchr(line, ')'); + if (!p) return -EIO; p++; @@ -685,8 +685,7 @@ finish: } int read_one_line_file(const char *fn, char **line) { - FILE *f; - int r; + _cleanup_fclose_ FILE *f = NULL; char t[LINE_MAX], *c; assert(fn); @@ -698,50 +697,37 @@ int read_one_line_file(const char *fn, char **line) { if (!fgets(t, sizeof(t), f)) { - if (ferror(f)) { - r = -errno; - goto finish; - } + if (ferror(f)) + return -errno; t[0] = 0; } c = strdup(t); - if (!c) { - r = -ENOMEM; - goto finish; - } - + if (!c) + return -ENOMEM; truncate_nl(c); *line = c; - r = 0; - -finish: - fclose(f); - return r; + return 0; } int read_full_file(const char *fn, char **contents, size_t *size) { - FILE *f; - int r; + _cleanup_fclose_ FILE *f = NULL; size_t n, l; - char *buf = NULL; + _cleanup_free_ char *buf = NULL; struct stat st; - if (!(f = fopen(fn, "re"))) + f = fopen(fn, "re"); + if (!f) return -errno; - if (fstat(fileno(f), &st) < 0) { - r = -errno; - goto finish; - } + if (fstat(fileno(f), &st) < 0) + return -errno; /* Safety check */ - if (st.st_size > 4*1024*1024) { - r = -E2BIG; - goto finish; - } + if (st.st_size > 4*1024*1024) + return -E2BIG; n = st.st_size > 0 ? st.st_size : LINE_MAX; l = 0; @@ -750,19 +736,16 @@ int read_full_file(const char *fn, char **contents, size_t *size) { char *t; size_t k; - if (!(t = realloc(buf, n+1))) { - r = -ENOMEM; - goto finish; - } + t = realloc(buf, n+1); + if (!t) + return -ENOMEM; buf = t; k = fread(buf + l, 1, n - l, f); if (k <= 0) { - if (ferror(f)) { - r = -errno; - goto finish; - } + if (ferror(f)) + return -errno; break; } @@ -771,10 +754,8 @@ int read_full_file(const char *fn, char **contents, size_t *size) { n *= 2; /* Safety check */ - if (n > 4*1024*1024) { - r = -E2BIG; - goto finish; - } + if (n > 4*1024*1024) + return -E2BIG; } buf[l] = 0; @@ -784,13 +765,7 @@ int read_full_file(const char *fn, char **contents, size_t *size) { if (size) *size = l; - r = 0; - -finish: - fclose(f); - free(buf); - - return r; + return 0; } int parse_env_file( @@ -5903,3 +5878,12 @@ int get_shell(char **_sh) { *_sh = sh; return 0; } + +void freep(void *p) { + free(*(void**) p); +} + +void fclosep(FILE **f) { + if (*f) + fclose(*f); +} diff --git a/src/shared/util.h b/src/shared/util.h index 19edf9835..770a00822 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -528,3 +528,6 @@ void warn_melody(void); int get_shell(char **ret); int get_home_dir(char **ret); + +void freep(void *p); +void fclosep(FILE **f); -- 2.30.2