|  | 
 | /* | 
 |  * Copyright (C) Igor Sysoev | 
 |  * Copyright (C) Nginx, Inc. | 
 |  */ | 
 |  | 
 |  | 
 | #include <ngx_config.h> | 
 | #include <ngx_core.h> | 
 |  | 
 |  | 
 | /* | 
 |  * The strerror() messages are copied because: | 
 |  * | 
 |  * 1) strerror() and strerror_r() functions are not Async-Signal-Safe, | 
 |  *    therefore, they cannot be used in signal handlers; | 
 |  * | 
 |  * 2) a direct sys_errlist[] array may be used instead of these functions, | 
 |  *    but Linux linker warns about its usage: | 
 |  * | 
 |  * warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead | 
 |  * warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead | 
 |  * | 
 |  *    causing false bug reports. | 
 |  */ | 
 |  | 
 |  | 
 | static ngx_str_t  *ngx_sys_errlist; | 
 | static ngx_str_t   ngx_unknown_error = ngx_string("Unknown error"); | 
 |  | 
 |  | 
 | u_char * | 
 | 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; | 
 |     size = ngx_min(size, msg->len); | 
 |  | 
 |     return ngx_cpymem(errstr, msg->data, size); | 
 | } | 
 |  | 
 |  | 
 | ngx_int_t | 
 | ngx_strerror_init(void) | 
 | { | 
 |     char       *msg; | 
 |     u_char     *p; | 
 |     size_t      len; | 
 |     ngx_err_t   err; | 
 |  | 
 |     /* | 
 |      * 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); | 
 |  | 
 |     ngx_sys_errlist = malloc(len); | 
 |     if (ngx_sys_errlist == NULL) { | 
 |         goto failed; | 
 |     } | 
 |  | 
 |     for (err = 0; err < NGX_SYS_NERR; err++) { | 
 |         msg = strerror(err); | 
 |         len = ngx_strlen(msg); | 
 |  | 
 |         p = malloc(len); | 
 |         if (p == NULL) { | 
 |             goto failed; | 
 |         } | 
 |  | 
 |         ngx_memcpy(p, msg, len); | 
 |         ngx_sys_errlist[err].len = len; | 
 |         ngx_sys_errlist[err].data = p; | 
 |     } | 
 |  | 
 |     return NGX_OK; | 
 |  | 
 | failed: | 
 |  | 
 |     err = errno; | 
 |     ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err)); | 
 |  | 
 |     return NGX_ERROR; | 
 | } |