[njs] Improved error handling in njs_file_tree_walk().
Dmitry Volyntsev
xeioex at nginx.com
Thu Aug 13 13:42:34 UTC 2020
details: https://hg.nginx.org/njs/rev/5a80b43b7098
branches:
changeset: 1492:5a80b43b7098
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Aug 13 13:40:36 2020 +0000
description:
Improved error handling in njs_file_tree_walk().
This also fixes Coverity CID 1465877.
diffstat:
src/njs_fs.c | 75 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 39 insertions(+), 36 deletions(-)
diffs (179 lines):
diff -r 5cce5069440e -r 5a80b43b7098 src/njs_fs.c
--- a/src/njs_fs.c Wed Aug 12 14:57:31 2020 +0000
+++ b/src/njs_fs.c Thu Aug 13 13:40:36 2020 +0000
@@ -81,7 +81,7 @@ typedef enum {
} njs_ftw_type_t;
-typedef int (*njs_file_tree_walk_cb_t)(const char *, const struct stat *,
+typedef njs_int_t (*njs_file_tree_walk_cb_t)(const char *, const struct stat *,
njs_ftw_type_t);
@@ -1257,7 +1257,7 @@ static int
njs_ftw(char *path, njs_file_tree_walk_cb_t cb, int fd_limit,
njs_ftw_flags_t flags, njs_ftw_trace_t *parent)
{
- int type, ret, dfd, err;
+ int type, ret, dfd;
DIR *d;
size_t base, len, length;
const char *d_name;
@@ -1272,7 +1272,7 @@ njs_ftw(char *path, njs_file_tree_walk_c
type = NJS_FTW_SLN;
} else if (errno != EACCES) {
- return -1;
+ return NJS_ERROR;
} else {
type = NJS_FTW_NS;
@@ -1289,12 +1289,12 @@ njs_ftw(char *path, njs_file_tree_walk_c
}
if ((flags & NJS_FTW_MOUNT) && parent != NULL && st.st_dev != parent->dev) {
- return 0;
+ return NJS_OK;
}
for (h = parent; h != NULL; h = h->chain) {
if (h->dev == st.st_dev && h->ino == st.st_ino) {
- return 0;
+ return NJS_OK;
}
}
@@ -1305,43 +1305,32 @@ njs_ftw(char *path, njs_file_tree_walk_c
trace.dev = st.st_dev;
trace.ino = st.st_ino;
- dfd = 0;
- err = 0;
+ d = NULL;
+ dfd = -1;
if (type == NJS_FTW_D || type == NJS_FTW_DP) {
dfd = open(path, O_RDONLY);
- err = errno;
if (dfd < 0) {
- if (err == EACCES) {
- type = NJS_FTW_DNR;
+ if (errno != EACCES) {
+ return NJS_ERROR;
}
- } else if (fd_limit == 0) {
- (void) close(dfd);
+ type = NJS_FTW_DNR;
}
}
if (!(flags & NJS_FTW_DEPTH)) {
ret = cb(path, &st, type);
if (njs_slow_path(ret != 0)) {
- if (dfd >= 0) {
- (void) close(dfd);
- }
-
- return ret;
+ goto done;
}
}
- if ((type == NJS_FTW_D || type == NJS_FTW_DP) && fd_limit != 0) {
- if (dfd < 0) {
- errno = err;
- return -1;
- }
-
+ if (type == NJS_FTW_D || type == NJS_FTW_DP) {
d = fdopendir(dfd);
if (njs_slow_path(d == NULL)) {
- (void) close(dfd);
- return -1;
+ ret = NJS_ERROR;
+ goto done;
}
for ( ;; ) {
@@ -1362,21 +1351,23 @@ njs_ftw(char *path, njs_file_tree_walk_c
if (njs_slow_path(length >= (PATH_MAX - len))) {
errno = ENAMETOOLONG;
- closedir(d);
- return -1;
+ ret = NJS_ERROR;
+ goto done;
}
path[base] = '/';
strcpy(path + base + 1, d_name);
- ret = njs_ftw(path, cb, fd_limit - 1, flags, &trace);
- if (njs_slow_path(ret != 0)) {
- closedir(d);
- return ret;
+ if (fd_limit != 0) {
+ ret = njs_ftw(path, cb, fd_limit - 1, flags, &trace);
+ if (njs_slow_path(ret != 0)) {
+ goto done;
+ }
}
}
closedir(d);
+ d = NULL;
}
path[len] = '\0';
@@ -1388,7 +1379,19 @@ njs_ftw(char *path, njs_file_tree_walk_c
}
}
- return 0;
+ ret = NJS_OK;
+
+done:
+
+ if (d != NULL) {
+ /* closedir() also closes underlying dfd. */
+ (void) closedir(d);
+
+ } else if (dfd >= 0) {
+ (void) close(dfd);
+ }
+
+ return ret;
}
@@ -1411,17 +1414,17 @@ njs_file_tree_walk(const char *path, njs
}
-static int
+static njs_int_t
njs_fs_rmtree_cb(const char *path, const struct stat *sb, njs_ftw_type_t type)
{
njs_int_t ret;
ret = remove(path);
if (ret != 0) {
- return -1;
+ return NJS_ERROR;
}
- return 0;
+ return NJS_OK;
}
@@ -1448,7 +1451,7 @@ njs_fs_rmtree(njs_vm_t *vm, const char *
ret = njs_file_tree_walk(path, njs_fs_rmtree_cb, 16,
NJS_FTW_PHYS | NJS_FTW_MOUNT | NJS_FTW_DEPTH);
- if (ret == 0) {
+ if (ret == NJS_OK) {
return NJS_OK;
}
More information about the nginx-devel
mailing list