use copied strerror() messages and autoconfigured sys_nerr value
Igor Sysoev
11 years ago
64 | 64 | fi |
65 | 65 | ;; |
66 | 66 | |
67 | value) | |
68 | # /bin/sh is used to intercept "Killed" or "Abort trap" messages | |
69 | if /bin/sh -c $NGX_AUTOTEST >/dev/null 2>&1; then | |
70 | echo " found" | |
71 | ngx_found=yes | |
72 | ||
73 | cat << END >> $NGX_AUTO_CONFIG_H | |
74 | ||
75 | #ifndef $ngx_feature_name | |
76 | #define $ngx_feature_name `$NGX_AUTOTEST` | |
77 | #endif | |
78 | ||
79 | END | |
80 | else | |
81 | echo " found but is not working" | |
82 | fi | |
83 | ;; | |
84 | ||
67 | 85 | bug) |
68 | 86 | # /bin/sh is used to intercept "Killed" or "Abort trap" messages |
69 | 87 | if /bin/sh -c $NGX_AUTOTEST >/dev/null 2>&1; then |
108 | 108 | . auto/feature |
109 | 109 | |
110 | 110 | |
111 | ngx_feature="strerror_r()" | |
112 | ngx_feature_name="NGX_HAVE_STRERROR_R" | |
113 | ngx_feature_run=yes | |
114 | ngx_feature_incs="#include <string.h>" | |
115 | ngx_feature_path= | |
116 | ngx_feature_libs= | |
117 | ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024); | |
118 | if (n < 0 || n > 1024) return 1;" | |
119 | . auto/feature | |
120 | ||
121 | ||
122 | # GNU style strerror_r() returns not length, but pointer | |
123 | ||
124 | ngx_feature="gnu style strerror_r()" | |
125 | ngx_feature_name="NGX_HAVE_GNU_STRERROR_R" | |
126 | ngx_feature_run=yes | |
127 | ngx_feature_incs="#include <string.h>" | |
128 | ngx_feature_path= | |
129 | ngx_feature_libs= | |
130 | ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024); | |
131 | if (n >= 0 && n < 1024) return 1;" | |
132 | . auto/feature | |
133 | ||
134 | ||
135 | ngx_feature="sys_errlist[]" | |
136 | ngx_feature_name="NGX_HAVE_SYS_ERRLIST" | |
137 | ngx_feature_run=yes | |
138 | ngx_feature_incs="#include <stdio.h>" | |
139 | ngx_feature_path= | |
140 | ngx_feature_libs= | |
141 | ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];" | |
111 | ngx_feature="sys_nerr" | |
112 | ngx_feature_name="NGX_SYS_NERR" | |
113 | ngx_feature_run=value | |
114 | ngx_feature_incs='#include <stdio.h>' | |
115 | ngx_feature_path= | |
116 | ngx_feature_libs= | |
117 | ngx_feature_test='printf("%d", sys_nerr);' | |
142 | 118 | . auto/feature |
143 | 119 | |
144 | 120 |
269 | 269 | |
270 | 270 | ngx_pid = ngx_getpid(); |
271 | 271 | |
272 | if (ngx_strerror_init() != NGX_OK) { | |
273 | return 1; | |
274 | } | |
275 | ||
272 | 276 | log = ngx_log_init(ngx_prefix); |
273 | 277 | if (log == NULL) { |
274 | 278 | return 1; |
247 | 247 | buf = ngx_slprintf(buf, last, " (%d: ", err); |
248 | 248 | #endif |
249 | 249 | |
250 | buf = ngx_strerror_r(err, buf, last - buf); | |
250 | buf = ngx_strerror(err, buf, last - buf); | |
251 | 251 | |
252 | 252 | if (buf < last) { |
253 | 253 | *buf++ = ')'; |
7 | 7 | #include <ngx_core.h> |
8 | 8 | |
9 | 9 | |
10 | #if (NGX_HAVE_STRERROR_R) | |
10 | /* | |
11 | * The strerror() messages are copied because: | |
12 | * | |
13 | * 1) strerror() and strerror_r() functions are not Async-Signal-Safe, | |
14 | * therefore, they can not be used in signal handlers; | |
15 | * | |
16 | * 2) a direct sys_errlist[] array may be used instead of these functions, | |
17 | * but Linux linker warns about its usage: | |
18 | * | |
19 | * warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead | |
20 | * warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead | |
21 | * | |
22 | * causing false bug reports. | |
23 | */ | |
24 | ||
25 | ||
26 | static ngx_str_t *ngx_sys_errlist; | |
27 | static ngx_str_t ngx_unknown_error = ngx_string("Unknown error"); | |
28 | ||
11 | 29 | |
12 | 30 | u_char * |
13 | ngx_strerror_r(int err, u_char *errstr, size_t size) | |
31 | ngx_strerror(ngx_err_t err, u_char *errstr, size_t size) | |
14 | 32 | { |
15 | if (size == 0) { | |
16 | return errstr; | |
33 | ngx_str_t *msg; | |
34 | ||
35 | msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]: | |
36 | &ngx_unknown_error; | |
37 | size = ngx_min(size, msg->len); | |
38 | ||
39 | return ngx_cpymem(errstr, msg->data, size); | |
40 | } | |
41 | ||
42 | ||
43 | ngx_uint_t | |
44 | ngx_strerror_init(void) | |
45 | { | |
46 | char *msg; | |
47 | u_char *p; | |
48 | size_t len; | |
49 | ngx_err_t err; | |
50 | ||
51 | /* | |
52 | * ngx_strerror() is not ready to work at this stage, therefore, | |
53 | * malloc() is used and possible errors are logged using strerror(). | |
54 | */ | |
55 | ||
56 | len = NGX_SYS_NERR * sizeof(ngx_str_t); | |
57 | ||
58 | ngx_sys_errlist = malloc(len); | |
59 | if (ngx_sys_errlist == NULL) { | |
60 | goto failed; | |
17 | 61 | } |
18 | 62 | |
19 | errstr[0] = '\0'; | |
63 | for (err = 0; err < NGX_SYS_NERR; err++) { | |
64 | msg = strerror(err); | |
65 | len = ngx_strlen(msg); | |
20 | 66 | |
21 | strerror_r(err, (char *) errstr, size); | |
67 | p = malloc(len); | |
68 | if (p == NULL) { | |
69 | goto failed; | |
70 | } | |
22 | 71 | |
23 | while (*errstr && size) { | |
24 | errstr++; | |
25 | size--; | |
72 | ngx_memcpy(p, msg, len); | |
73 | ngx_sys_errlist[err].len = len; | |
74 | ngx_sys_errlist[err].data = p; | |
26 | 75 | } |
27 | 76 | |
28 | return errstr; | |
77 | return NGX_OK; | |
78 | ||
79 | failed: | |
80 | ||
81 | err = errno; | |
82 | ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err)); | |
83 | ||
84 | return NGX_ERROR; | |
29 | 85 | } |
30 | ||
31 | #elif (NGX_HAVE_GNU_STRERROR_R) | |
32 | ||
33 | /* Linux strerror_r() */ | |
34 | ||
35 | u_char * | |
36 | ngx_strerror_r(int err, u_char *errstr, size_t size) | |
37 | { | |
38 | char *str; | |
39 | ||
40 | if (size == 0) { | |
41 | return errstr; | |
42 | } | |
43 | ||
44 | errstr[0] = '\0'; | |
45 | ||
46 | str = strerror_r(err, (char *) errstr, size); | |
47 | ||
48 | if (str != (char *) errstr) { | |
49 | return ngx_cpystrn(errstr, (u_char *) str, size); | |
50 | } | |
51 | ||
52 | while (*errstr && size) { | |
53 | errstr++; | |
54 | size--; | |
55 | } | |
56 | ||
57 | return errstr; | |
58 | } | |
59 | ||
60 | #endif |
59 | 59 | #define ngx_set_socket_errno(err) errno = err |
60 | 60 | |
61 | 61 | |
62 | #if (NGX_HAVE_STRERROR_R || NGX_HAVE_GNU_STRERROR_R) | |
63 | ||
64 | u_char *ngx_strerror_r(int err, u_char *errstr, size_t size); | |
65 | ||
66 | #else | |
67 | ||
68 | /* Solaris and Tru64 UNIX have thread-safe strerror() */ | |
69 | ||
70 | #define ngx_strerror_r(err, errstr, size) \ | |
71 | ngx_cpystrn(errstr, (u_char *) strerror(err), size) | |
72 | ||
73 | #endif | |
74 | ||
75 | ||
76 | #if (NGX_HAVE_SYS_ERRLIST) | |
77 | ||
78 | #define ngx_sigsafe_strerror(err) \ | |
79 | (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error" | |
80 | ||
81 | #else | |
82 | ||
83 | #define ngx_sigsafe_strerror(err) "" | |
84 | ||
85 | #endif | |
62 | u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size); | |
63 | ngx_uint_t ngx_strerror_init(void); | |
86 | 64 | |
87 | 65 | |
88 | 66 | #endif /* _NGX_ERRNO_H_INCLUDED_ */ |
478 | 478 | */ |
479 | 479 | |
480 | 480 | if (err == NGX_ECHILD) { |
481 | ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, | |
482 | "waitpid() failed (%d: %s)", | |
483 | err, ngx_sigsafe_strerror(err)); | |
481 | ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, err, | |
482 | "waitpid() failed"); | |
484 | 483 | return; |
485 | 484 | } |
486 | 485 | |
487 | 486 | #endif |
488 | 487 | |
489 | ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, | |
490 | "waitpid() failed (%d: %s)", | |
491 | err, ngx_sigsafe_strerror(err)); | |
488 | ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, | |
489 | "waitpid() failed"); | |
492 | 490 | return; |
493 | 491 | } |
494 | 492 |
8 | 8 | |
9 | 9 | |
10 | 10 | u_char * |
11 | ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size) | |
11 | ngx_strerror(ngx_err_t err, u_char *errstr, size_t size) | |
12 | 12 | { |
13 | 13 | u_int len; |
14 | 14 | static u_long lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); |
49 | 49 | |
50 | 50 | return &errstr[++len]; |
51 | 51 | } |
52 | ||
53 | ||
54 | ngx_uint_t | |
55 | ngx_strerror_init(void) | |
56 | { | |
57 | return NGX_OK; | |
58 | } |
53 | 53 | #define NGX_EALREADY WSAEALREADY |
54 | 54 | #define NGX_EINVAL WSAEINVAL |
55 | 55 | |
56 | u_char *ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size); | |
56 | ||
57 | u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size); | |
58 | ngx_uint_t ngx_strerror_init(void); | |
57 | 59 | |
58 | 60 | |
59 | 61 | #endif /* _NGX_ERRNO_H_INCLUDED_ */ |