1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyev/*
13e18a033bSKonstantin Ananyev * The strerror() messages are copied because:
14e18a033bSKonstantin Ananyev *
15e18a033bSKonstantin Ananyev * 1) strerror() and strerror_r() functions are not Async-Signal-Safe,
16e18a033bSKonstantin Ananyev *    therefore, they cannot be used in signal handlers;
17e18a033bSKonstantin Ananyev *
18e18a033bSKonstantin Ananyev * 2) a direct sys_errlist[] array may be used instead of these functions,
19e18a033bSKonstantin Ananyev *    but Linux linker warns about its usage:
20e18a033bSKonstantin Ananyev *
21e18a033bSKonstantin Ananyev * warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
22e18a033bSKonstantin Ananyev * warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
23e18a033bSKonstantin Ananyev *
24e18a033bSKonstantin Ananyev *    causing false bug reports.
25e18a033bSKonstantin Ananyev */
26e18a033bSKonstantin Ananyev
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyevstatic ngx_str_t  *ngx_sys_errlist;
29e18a033bSKonstantin Ananyevstatic ngx_str_t   ngx_unknown_error = ngx_string("Unknown error");
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyev
32e18a033bSKonstantin Ananyevu_char *
33e18a033bSKonstantin Ananyevngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
34e18a033bSKonstantin Ananyev{
35e18a033bSKonstantin Ananyev    ngx_str_t  *msg;
36e18a033bSKonstantin Ananyev
37e18a033bSKonstantin Ananyev    msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
38e18a033bSKonstantin Ananyev                                              &ngx_unknown_error;
39e18a033bSKonstantin Ananyev    size = ngx_min(size, msg->len);
40e18a033bSKonstantin Ananyev
41e18a033bSKonstantin Ananyev    return ngx_cpymem(errstr, msg->data, size);
42e18a033bSKonstantin Ananyev}
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev
45e18a033bSKonstantin Ananyevngx_int_t
46e18a033bSKonstantin Ananyevngx_strerror_init(void)
47e18a033bSKonstantin Ananyev{
48e18a033bSKonstantin Ananyev    char       *msg;
49e18a033bSKonstantin Ananyev    u_char     *p;
50e18a033bSKonstantin Ananyev    size_t      len;
51e18a033bSKonstantin Ananyev    ngx_err_t   err;
52e18a033bSKonstantin Ananyev
53e18a033bSKonstantin Ananyev    /*
54e18a033bSKonstantin Ananyev     * ngx_strerror() is not ready to work at this stage, therefore,
55e18a033bSKonstantin Ananyev     * malloc() is used and possible errors are logged using strerror().
56e18a033bSKonstantin Ananyev     */
57e18a033bSKonstantin Ananyev
58e18a033bSKonstantin Ananyev    len = NGX_SYS_NERR * sizeof(ngx_str_t);
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev    ngx_sys_errlist = malloc(len);
61e18a033bSKonstantin Ananyev    if (ngx_sys_errlist == NULL) {
62e18a033bSKonstantin Ananyev        goto failed;
63e18a033bSKonstantin Ananyev    }
64e18a033bSKonstantin Ananyev
65e18a033bSKonstantin Ananyev    for (err = 0; err < NGX_SYS_NERR; err++) {
66e18a033bSKonstantin Ananyev        msg = strerror(err);
67e18a033bSKonstantin Ananyev        len = ngx_strlen(msg);
68e18a033bSKonstantin Ananyev
69e18a033bSKonstantin Ananyev        p = malloc(len);
70e18a033bSKonstantin Ananyev        if (p == NULL) {
71e18a033bSKonstantin Ananyev            goto failed;
72e18a033bSKonstantin Ananyev        }
73e18a033bSKonstantin Ananyev
74e18a033bSKonstantin Ananyev        ngx_memcpy(p, msg, len);
75e18a033bSKonstantin Ananyev        ngx_sys_errlist[err].len = len;
76e18a033bSKonstantin Ananyev        ngx_sys_errlist[err].data = p;
77e18a033bSKonstantin Ananyev    }
78e18a033bSKonstantin Ananyev
79e18a033bSKonstantin Ananyev    return NGX_OK;
80e18a033bSKonstantin Ananyev
81e18a033bSKonstantin Ananyevfailed:
82e18a033bSKonstantin Ananyev
83e18a033bSKonstantin Ananyev    err = errno;
84e18a033bSKonstantin Ananyev    ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));
85e18a033bSKonstantin Ananyev
86e18a033bSKonstantin Ananyev    return NGX_ERROR;
87e18a033bSKonstantin Ananyev}