use copied strerror() messages and autoconfigured sys_nerr value

This commit is contained in:
Igor Sysoev 2010-11-25 11:04:03 +00:00
parent 40747ad861
commit 7f31a2098d
9 changed files with 103 additions and 95 deletions

View File

@ -65,6 +65,24 @@ if [ -x $NGX_AUTOTEST ]; then
fi fi
;; ;;
value)
# /bin/sh is used to intercept "Killed" or "Abort trap" messages
if /bin/sh -c $NGX_AUTOTEST >/dev/null 2>&1; then
echo " found"
ngx_found=yes
cat << END >> $NGX_AUTO_CONFIG_H
#ifndef $ngx_feature_name
#define $ngx_feature_name `$NGX_AUTOTEST`
#endif
END
else
echo " found but is not working"
fi
;;
bug) bug)
# /bin/sh is used to intercept "Killed" or "Abort trap" messages # /bin/sh is used to intercept "Killed" or "Abort trap" messages
if /bin/sh -c $NGX_AUTOTEST >/dev/null 2>&1; then if /bin/sh -c $NGX_AUTOTEST >/dev/null 2>&1; then

View File

@ -109,37 +109,13 @@ ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0)"
. auto/feature . auto/feature
ngx_feature="strerror_r()" ngx_feature="sys_nerr"
ngx_feature_name="NGX_HAVE_STRERROR_R" ngx_feature_name="NGX_SYS_NERR"
ngx_feature_run=yes ngx_feature_run=value
ngx_feature_incs="#include <string.h>" ngx_feature_incs='#include <stdio.h>'
ngx_feature_path= ngx_feature_path=
ngx_feature_libs= ngx_feature_libs=
ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024); ngx_feature_test='printf("%d", sys_nerr);'
if (n < 0 || n > 1024) return 1;"
. auto/feature
# GNU style strerror_r() returns not length, but pointer
ngx_feature="gnu style strerror_r()"
ngx_feature_name="NGX_HAVE_GNU_STRERROR_R"
ngx_feature_run=yes
ngx_feature_incs="#include <string.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024);
if (n >= 0 && n < 1024) return 1;"
. auto/feature
ngx_feature="sys_errlist[]"
ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
ngx_feature_run=yes
ngx_feature_incs="#include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
. auto/feature . auto/feature

View File

@ -270,6 +270,10 @@ main(int argc, char *const *argv)
ngx_pid = ngx_getpid(); ngx_pid = ngx_getpid();
if (ngx_strerror_init() != NGX_OK) {
return 1;
}
log = ngx_log_init(ngx_prefix); log = ngx_log_init(ngx_prefix);
if (log == NULL) { if (log == NULL) {
return 1; return 1;

View File

@ -248,7 +248,7 @@ ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
buf = ngx_slprintf(buf, last, " (%d: ", err); buf = ngx_slprintf(buf, last, " (%d: ", err);
#endif #endif
buf = ngx_strerror_r(err, buf, last - buf); buf = ngx_strerror(err, buf, last - buf);
if (buf < last) { if (buf < last) {
*buf++ = ')'; *buf++ = ')';

View File

@ -8,54 +8,79 @@
#include <ngx_core.h> #include <ngx_core.h>
#if (NGX_HAVE_STRERROR_R) /*
* The strerror() messages are copied because:
*
* 1) strerror() and strerror_r() functions are not Async-Signal-Safe,
* therefore, they can not 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 * u_char *
ngx_strerror_r(int err, u_char *errstr, size_t size) ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{ {
if (size == 0) { ngx_str_t *msg;
return errstr;
}
errstr[0] = '\0'; msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
&ngx_unknown_error;
size = ngx_min(size, msg->len);
strerror_r(err, (char *) errstr, size); return ngx_cpymem(errstr, msg->data, size);
while (*errstr && size) {
errstr++;
size--;
}
return errstr;
} }
#elif (NGX_HAVE_GNU_STRERROR_R)
/* Linux strerror_r() */ ngx_uint_t
ngx_strerror_init(void)
u_char *
ngx_strerror_r(int err, u_char *errstr, size_t size)
{ {
char *str; char *msg;
u_char *p;
size_t len;
ngx_err_t err;
if (size == 0) { /*
return errstr; * 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;
} }
errstr[0] = '\0'; for (err = 0; err < NGX_SYS_NERR; err++) {
msg = strerror(err);
len = ngx_strlen(msg);
str = strerror_r(err, (char *) errstr, size); p = malloc(len);
if (p == NULL) {
goto failed;
}
if (str != (char *) errstr) { ngx_memcpy(p, msg, len);
return ngx_cpystrn(errstr, (u_char *) str, size); ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
} }
while (*errstr && size) { return NGX_OK;
errstr++;
size--;
}
return errstr; failed:
err = errno;
ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));
return NGX_ERROR;
} }
#endif

View File

@ -60,30 +60,8 @@ typedef int ngx_err_t;
#define ngx_set_socket_errno(err) errno = err #define ngx_set_socket_errno(err) errno = err
#if (NGX_HAVE_STRERROR_R || NGX_HAVE_GNU_STRERROR_R) u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size);
ngx_uint_t ngx_strerror_init(void);
u_char *ngx_strerror_r(int err, u_char *errstr, size_t size);
#else
/* Solaris and Tru64 UNIX have thread-safe strerror() */
#define ngx_strerror_r(err, errstr, size) \
ngx_cpystrn(errstr, (u_char *) strerror(err), size)
#endif
#if (NGX_HAVE_SYS_ERRLIST)
#define ngx_sigsafe_strerror(err) \
(err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error"
#else
#define ngx_sigsafe_strerror(err) ""
#endif
#endif /* _NGX_ERRNO_H_INCLUDED_ */ #endif /* _NGX_ERRNO_H_INCLUDED_ */

View File

@ -479,17 +479,15 @@ ngx_process_get_status(void)
*/ */
if (err == NGX_ECHILD) { if (err == NGX_ECHILD) {
ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, err,
"waitpid() failed (%d: %s)", "waitpid() failed");
err, ngx_sigsafe_strerror(err));
return; return;
} }
#endif #endif
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
"waitpid() failed (%d: %s)", "waitpid() failed");
err, ngx_sigsafe_strerror(err));
return; return;
} }

View File

@ -9,7 +9,7 @@
u_char * u_char *
ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size) ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{ {
u_int len; u_int len;
static u_long lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); static u_long lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
@ -50,3 +50,10 @@ ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size)
return &errstr[++len]; return &errstr[++len];
} }
ngx_uint_t
ngx_strerror_init(void)
{
return NGX_OK;
}

View File

@ -54,7 +54,9 @@ typedef DWORD ngx_err_t;
#define NGX_EALREADY WSAEALREADY #define NGX_EALREADY WSAEALREADY
#define NGX_EINVAL WSAEINVAL #define NGX_EINVAL WSAEINVAL
u_char *ngx_strerror_r(ngx_err_t err, u_char *errstr, size_t size);
u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size);
ngx_uint_t ngx_strerror_init(void);
#endif /* _NGX_ERRNO_H_INCLUDED_ */ #endif /* _NGX_ERRNO_H_INCLUDED_ */