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