[PATCH] Core: detect valid error numbers at run-time

Piotr Sikora piotrsikora at google.com
Fri Jul 1 21:31:41 UTC 2016


# HG changeset patch
# User Piotr Sikora <piotrsikora at google.com>
# Date 1467064814 25200
#      Mon Jun 27 15:00:14 2016 -0700
# Node ID be7eadea3d089f18c5ea685c09824ddcd99c3fe5
# Parent  d452cb27639f714bc43b7f3ede417e3e7f8efdd6
Core: detect valid error numbers at run-time.

Strings for some error numbers might be omitted, at least on Linux,
so stop after 3 unknown errors in a row and not after the first one.

Signed-off-by: Piotr Sikora <piotrsikora at google.com>

diff -r d452cb27639f -r be7eadea3d08 auto/unix
--- a/auto/unix
+++ b/auto/unix
@@ -697,60 +697,6 @@ ngx_feature_test="char buf[1]; struct io
 . auto/feature
 
 
-ngx_feature="sys_nerr"
-ngx_feature_name="NGX_SYS_NERR"
-ngx_feature_run=value
-ngx_feature_incs='#include <errno.h>
-                  #include <stdio.h>'
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test='printf("%d", sys_nerr);'
-. auto/feature
-
-
-if [ $ngx_found = no ]; then
-
-    # Cygiwn defines _sys_nerr
-    ngx_feature="_sys_nerr"
-    ngx_feature_name="NGX_SYS_NERR"
-    ngx_feature_run=value
-    ngx_feature_incs='#include <errno.h>
-                      #include <stdio.h>'
-    ngx_feature_path=
-    ngx_feature_libs=
-    ngx_feature_test='printf("%d", _sys_nerr);'
-    . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
-    # Solaris has no sys_nerr
-    ngx_feature='maximum errno'
-    ngx_feature_name=NGX_SYS_NERR
-    ngx_feature_run=value
-    ngx_feature_incs='#include <errno.h>
-                      #include <string.h>
-                      #include <stdio.h>'
-    ngx_feature_path=
-    ngx_feature_libs=
-    ngx_feature_test='int  n;
-                      char *p;
-                      for (n = 1; n < 1000; n++) {
-                          errno = 0;
-                          p = strerror(n);
-                          if (errno == EINVAL
-                              || p == NULL
-                              || strncmp(p, "Unknown error", 13) == 0)
-                          {
-                              break;
-                          }
-                      }
-                      printf("%d", n);'
-    . auto/feature
-fi
-
-
 ngx_feature="localtime_r()"
 ngx_feature_name="NGX_HAVE_LOCALTIME_R"
 ngx_feature_run=no
diff -r d452cb27639f -r be7eadea3d08 src/os/unix/ngx_errno.c
--- a/src/os/unix/ngx_errno.c
+++ b/src/os/unix/ngx_errno.c
@@ -26,6 +26,7 @@
 
 
 static ngx_str_t  *ngx_sys_errlist;
+static ngx_err_t   ngx_sys_errlist_n;
 static ngx_str_t   ngx_unknown_error = ngx_string("Unknown error");
 
 
@@ -34,8 +35,8 @@ ngx_strerror(ngx_err_t err, u_char *errs
 {
     ngx_str_t  *msg;
 
-    msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
-                                              &ngx_unknown_error;
+    msg = (err < ngx_sys_errlist_n) ? &ngx_sys_errlist[err]
+                                    : &ngx_unknown_error;
     size = ngx_min(size, msg->len);
 
     return ngx_cpymem(errstr, msg->data, size);
@@ -45,25 +46,58 @@ ngx_strerror(ngx_err_t err, u_char *errs
 ngx_int_t
 ngx_strerror_init(void)
 {
-    char       *msg;
-    u_char     *p;
-    size_t      len;
-    ngx_err_t   err;
+    char        *msg;
+    u_char      *p;
+    size_t       len;
+    ngx_err_t    err;
+    ngx_uint_t   count;
 
     /*
      * ngx_strerror() is not ready to work at this stage, therefore,
      * malloc() is used and possible errors are logged using strerror().
      */
 
-    len = NGX_SYS_NERR * sizeof(ngx_str_t);
+    count = 0;
+    ngx_sys_errlist_n = 1000;
+
+    for (err = 0; err < ngx_sys_errlist_n; err++) {
+
+        errno = 0;
+        msg = strerror(err);
+        if (errno == EINVAL
+            || msg == NULL
+            || ngx_strncmp(msg, "Unknown error", 13) == 0)
+        {
+            if (++count > 2) {
+                ngx_sys_errlist_n = err - 2;
+                break;
+            }
+
+            continue;
+        }
+
+        count = 0;
+    }
+
+    len = ngx_sys_errlist_n * sizeof(ngx_str_t);
 
     ngx_sys_errlist = malloc(len);
     if (ngx_sys_errlist == NULL) {
         goto failed;
     }
 
-    for (err = 0; err < NGX_SYS_NERR; err++) {
+    for (err = 0; err < ngx_sys_errlist_n; err++) {
+
+        errno = 0;
         msg = strerror(err);
+        if (errno == EINVAL
+            || msg == NULL
+            || ngx_strncmp(msg, "Unknown error", 13) == 0)
+        {
+            ngx_sys_errlist[err] = ngx_unknown_error;
+            continue;
+        }
+
         len = ngx_strlen(msg);
 
         p = malloc(len);



More information about the nginx-devel mailing list