aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/os/unix/ngx_errno.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/src/os/unix/ngx_errno.c b/src/os/unix/ngx_errno.c
index e787b2377..b3303bf6f 100644
--- a/src/os/unix/ngx_errno.c
+++ b/src/os/unix/ngx_errno.c
@@ -27,6 +27,8 @@
static ngx_str_t *ngx_sys_errlist;
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
+static ngx_err_t ngx_first_error;
+static ngx_err_t ngx_last_error;
u_char *
@@ -34,8 +36,13 @@ ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{
ngx_str_t *msg;
- msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
- &ngx_unknown_error;
+ if (err >= ngx_first_error && err < ngx_last_error) {
+ msg = &ngx_sys_errlist[err - ngx_first_error];
+
+ } else {
+ msg = &ngx_unknown_error;
+ }
+
size = ngx_min(size, msg->len);
return ngx_cpymem(errstr, msg->data, size);
@@ -50,20 +57,92 @@ ngx_strerror_init(void)
size_t len;
ngx_err_t err;
+#if (NGX_SYS_NERR)
+ ngx_first_error = 0;
+ ngx_last_error = NGX_SYS_NERR;
+
+#elif (EPERM > 1000 && EPERM < 0x7fffffff - 1000)
+
+ /*
+ * If number of errors is not known, and EPERM error code has large
+ * but reasonable value, guess possible error codes based on the error
+ * messages returned by strerror(), starting from EPERM. Notably,
+ * this covers GNU/Hurd, where errors start at 0x40000001.
+ */
+
+ for (err = EPERM; err > EPERM - 1000; err--) {
+ ngx_set_errno(0);
+ msg = strerror(err);
+
+ if (errno == EINVAL
+ || msg == NULL
+ || strncmp(msg, "Unknown error", 13) == 0)
+ {
+ continue;
+ }
+
+ ngx_first_error = err;
+ }
+
+ for (err = EPERM; err < EPERM + 1000; err++) {
+ ngx_set_errno(0);
+ msg = strerror(err);
+
+ if (errno == EINVAL
+ || msg == NULL
+ || strncmp(msg, "Unknown error", 13) == 0)
+ {
+ continue;
+ }
+
+ ngx_last_error = err + 1;
+ }
+
+#else
+
+ /*
+ * If number of errors is not known, guess it based on the error
+ * messages returned by strerror().
+ */
+
+ ngx_first_error = 0;
+
+ for (err = 0; err < 1000; err++) {
+ ngx_set_errno(0);
+ msg = strerror(err);
+
+ if (errno == EINVAL
+ || msg == NULL
+ || strncmp(msg, "Unknown error", 13) == 0)
+ {
+ continue;
+ }
+
+ ngx_last_error = err + 1;
+ }
+
+#endif
+
/*
* 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);
+ len = (ngx_last_error - ngx_first_error) * 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 = ngx_first_error; err < ngx_last_error; err++) {
msg = strerror(err);
+
+ if (msg == NULL) {
+ ngx_sys_errlist[err - ngx_first_error] = ngx_unknown_error;
+ continue;
+ }
+
len = ngx_strlen(msg);
p = malloc(len);
@@ -72,8 +151,8 @@ ngx_strerror_init(void)
}
ngx_memcpy(p, msg, len);
- ngx_sys_errlist[err].len = len;
- ngx_sys_errlist[err].data = p;
+ ngx_sys_errlist[err - ngx_first_error].len = len;
+ ngx_sys_errlist[err - ngx_first_error].data = p;
}
return NGX_OK;