[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