diff --git a/coccinelle/safe_closedir.cocci b/coccinelle/safe_closedir.cocci new file mode 100644 index 0000000000..743ffd97ef --- /dev/null +++ b/coccinelle/safe_closedir.cocci @@ -0,0 +1,27 @@ +@@ +expression p; +@@ +- if (p) { +- closedir(p); +- p = NULL; +- } ++ p = safe_closedir(p); +@@ +expression p; +@@ +- if (p) +- closedir(p); +- p = NULL; ++ p = safe_closedir(p); +@@ +expression p; +@@ +- closedir(p); +- p = NULL; ++ p = safe_closedir(p); +@@ +expression p; +@@ +- if (p) +- closedir(p); ++ safe_closedir(p); diff --git a/src/basic/util.c b/src/basic/util.c index e3b2af8e02..0c3ef2a68c 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -354,6 +354,17 @@ FILE* safe_fclose(FILE *f) { return NULL; } +DIR* safe_closedir(DIR *d) { + + if (d) { + PROTECT_ERRNO; + + assert_se(closedir(d) >= 0 || errno != EBADF); + } + + return NULL; +} + int unlink_noerrno(const char *path) { PROTECT_ERRNO; int r; diff --git a/src/basic/util.h b/src/basic/util.h index 8abaa740b2..db5dd74770 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -151,6 +151,7 @@ void close_many(const int fds[], unsigned n_fd); int fclose_nointr(FILE *f); FILE* safe_fclose(FILE *f); +DIR* safe_closedir(DIR *f); int parse_size(const char *t, uint64_t base, uint64_t *size); diff --git a/src/core/manager.c b/src/core/manager.c index 4e672a8c48..1c1763c902 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1071,8 +1071,7 @@ static void manager_build_unit_path_cache(Manager *m) { goto fail; } - closedir(d); - d = NULL; + d = safe_closedir(d); } return; diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index f9950c8ab9..964750076a 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -806,8 +806,7 @@ static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_servic if (!path) return -ENOMEM; - if (d) - closedir(d); + safe_closedir(d); d = opendir(path); if (!d) {