| |
| /* |
| * 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; |
| } |