1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

Replace use of sys_siglist[] with strsignal().

This commit back-patches the v12-era commits a73d08319, cc92cca43,
and 7570df0f3 into supported pre-v12 branches.  The net effect is to
eliminate our former dependency on the never-standard sys_siglist[]
array, instead using POSIX-standard strsignal(3).

What motivates doing this now is that glibc just removed sys_siglist[]
from the set of symbols available to newly-built programs.  While our
code can survive without sys_siglist[], it then fails to print any
description of the signal that killed a child process, which is a
non-negligible loss of friendliness.  We can expect that people will
be wanting to build the back branches on platforms that include this
change, so we need to do something.

Since strsignal(3) has existed for quite a long time, and we've not
had any trouble with these patches so far in v12, it seems safe to
back-patch into older branches.

Discussion: https://postgr.es/m/3179114.1594853308@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2020-07-15 22:05:12 -04:00
parent 23924feca0
commit 0140dec180
12 changed files with 94 additions and 84 deletions

20
configure vendored
View File

@ -13256,7 +13256,7 @@ fi
LIBS_including_readline="$LIBS" LIBS_including_readline="$LIBS"
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'` LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
for ac_func in cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll posix_fallocate pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range towlower uselocale utime utimes wcstombs wcstombs_l for ac_func in cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll posix_fallocate pstat pthread_is_threaded_np readlink setproctitle setsid shm_open strsignal symlink sync_file_range towlower uselocale utime utimes wcstombs wcstombs_l
do : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -14122,24 +14122,6 @@ esac
fi fi
ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h>
/* NetBSD declares sys_siglist in unistd.h. */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
"
if test "x$ac_cv_have_decl_sys_siglist" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_SYS_SIGLIST $ac_have_decl
_ACEOF
ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog" ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
if test "x$ac_cv_func_syslog" = xyes; then : if test "x$ac_cv_func_syslog" = xyes; then :
ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"

View File

@ -1516,6 +1516,7 @@ AC_CHECK_FUNCS(m4_normalize([
setproctitle setproctitle
setsid setsid
shm_open shm_open
strsignal
symlink symlink
sync_file_range sync_file_range
towlower towlower
@ -1717,14 +1718,6 @@ if test "$PORTNAME" = "cygwin"; then
AC_LIBOBJ(dirmod) AC_LIBOBJ(dirmod)
fi fi
AC_CHECK_DECLS([sys_siglist], [], [],
[#include <signal.h>
/* NetBSD declares sys_siglist in unistd.h. */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
])
AC_CHECK_FUNC(syslog, AC_CHECK_FUNC(syslog,
[AC_CHECK_HEADER(syslog.h, [AC_CHECK_HEADER(syslog.h,
[AC_DEFINE(HAVE_SYSLOG, 1, [Define to 1 if you have the syslog interface.])])]) [AC_DEFINE(HAVE_SYSLOG, 1, [Define to 1 if you have the syslog interface.])])])

View File

@ -596,17 +596,10 @@ pgarch_archiveXlog(char *xlog)
errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."), errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
errdetail("The failed archive command was: %s", errdetail("The failed archive command was: %s",
xlogarchcmd))); xlogarchcmd)));
#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST
ereport(lev,
(errmsg("archive command was terminated by signal %d: %s",
WTERMSIG(rc),
WTERMSIG(rc) < NSIG ? sys_siglist[WTERMSIG(rc)] : "(unknown)"),
errdetail("The failed archive command was: %s",
xlogarchcmd)));
#else #else
ereport(lev, ereport(lev,
(errmsg("archive command was terminated by signal %d", (errmsg("archive command was terminated by signal %d: %s",
WTERMSIG(rc)), WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
errdetail("The failed archive command was: %s", errdetail("The failed archive command was: %s",
xlogarchcmd))); xlogarchcmd)));
#endif #endif

View File

@ -3611,6 +3611,7 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
procname, pid, WEXITSTATUS(exitstatus)), procname, pid, WEXITSTATUS(exitstatus)),
activity ? errdetail("Failed process was running: %s", activity) : 0)); activity ? errdetail("Failed process was running: %s", activity) : 0));
else if (WIFSIGNALED(exitstatus)) else if (WIFSIGNALED(exitstatus))
{
#if defined(WIN32) #if defined(WIN32)
ereport(lev, ereport(lev,
@ -3621,7 +3622,7 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
procname, pid, WTERMSIG(exitstatus)), procname, pid, WTERMSIG(exitstatus)),
errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."), errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
activity ? errdetail("Failed process was running: %s", activity) : 0)); activity ? errdetail("Failed process was running: %s", activity) : 0));
#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST #else
ereport(lev, ereport(lev,
/*------ /*------
@ -3629,19 +3630,10 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
"server process" */ "server process" */
(errmsg("%s (PID %d) was terminated by signal %d: %s", (errmsg("%s (PID %d) was terminated by signal %d: %s",
procname, pid, WTERMSIG(exitstatus), procname, pid, WTERMSIG(exitstatus),
WTERMSIG(exitstatus) < NSIG ? pg_strsignal(WTERMSIG(exitstatus))),
sys_siglist[WTERMSIG(exitstatus)] : "(unknown)"),
activity ? errdetail("Failed process was running: %s", activity) : 0));
#else
ereport(lev,
/*------
translator: %s is a noun phrase describing a child process, such as
"server process" */
(errmsg("%s (PID %d) was terminated by signal %d",
procname, pid, WTERMSIG(exitstatus)),
activity ? errdetail("Failed process was running: %s", activity) : 0)); activity ? errdetail("Failed process was running: %s", activity) : 0));
#endif #endif
}
else else
ereport(lev, ereport(lev,

View File

@ -1965,7 +1965,7 @@ BaseBackup(void)
{ {
#ifndef WIN32 #ifndef WIN32
int status; int status;
int r; pid_t r;
#else #else
DWORD status; DWORD status;
@ -1993,7 +1993,7 @@ BaseBackup(void)
/* Just wait for the background process to exit */ /* Just wait for the background process to exit */
r = waitpid(bgchild, &status, 0); r = waitpid(bgchild, &status, 0);
if (r == -1) if (r == (pid_t) -1)
{ {
fprintf(stderr, _("%s: could not wait for child process: %s\n"), fprintf(stderr, _("%s: could not wait for child process: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
@ -2002,19 +2002,13 @@ BaseBackup(void)
if (r != bgchild) if (r != bgchild)
{ {
fprintf(stderr, _("%s: child %d died, expected %d\n"), fprintf(stderr, _("%s: child %d died, expected %d\n"),
progname, r, (int) bgchild); progname, (int) r, (int) bgchild);
disconnect_and_exit(1); disconnect_and_exit(1);
} }
if (!WIFEXITED(status)) if (status != 0)
{ {
fprintf(stderr, _("%s: child process did not exit normally\n"), fprintf(stderr, "%s: %s\n",
progname); progname, wait_result_to_str(status));
disconnect_and_exit(1);
}
if (WEXITSTATUS(status) != 0)
{
fprintf(stderr, _("%s: child process exited with error %d\n"),
progname, WEXITSTATUS(status));
disconnect_and_exit(1); disconnect_and_exit(1);
} }
/* Exited normally, we're happy! */ /* Exited normally, we're happy! */

View File

@ -56,25 +56,17 @@ wait_result_to_str(int exitstatus)
} }
} }
else if (WIFSIGNALED(exitstatus)) else if (WIFSIGNALED(exitstatus))
{
#if defined(WIN32) #if defined(WIN32)
snprintf(str, sizeof(str), snprintf(str, sizeof(str),
_("child process was terminated by exception 0x%X"), _("child process was terminated by exception 0x%X"),
WTERMSIG(exitstatus)); WTERMSIG(exitstatus));
#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST
{
char str2[256];
snprintf(str2, sizeof(str2), "%d: %s", WTERMSIG(exitstatus),
WTERMSIG(exitstatus) < NSIG ?
sys_siglist[WTERMSIG(exitstatus)] : "(unknown)");
snprintf(str, sizeof(str),
_("child process was terminated by signal %s"), str2);
}
#else #else
snprintf(str, sizeof(str), snprintf(str, sizeof(str),
_("child process was terminated by signal %d"), _("child process was terminated by signal %d: %s"),
WTERMSIG(exitstatus)); WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus)));
#endif #endif
}
else else
snprintf(str, sizeof(str), snprintf(str, sizeof(str),
_("child process exited with unrecognized status %d"), _("child process exited with unrecognized status %d"),

View File

@ -158,10 +158,6 @@
don't. */ don't. */
#undef HAVE_DECL_STRTOULL #undef HAVE_DECL_STRTOULL
/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
don't. */
#undef HAVE_DECL_SYS_SIGLIST
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you /* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */ don't. */
#undef HAVE_DECL_VSNPRINTF #undef HAVE_DECL_VSNPRINTF
@ -511,6 +507,9 @@
/* Define to use have a strong random number source */ /* Define to use have a strong random number source */
#undef HAVE_STRONG_RANDOM #undef HAVE_STRONG_RANDOM
/* Define to 1 if you have the `strsignal' function. */
#undef HAVE_STRSIGNAL
/* Define to 1 if you have the `strtoll' function. */ /* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL #undef HAVE_STRTOLL

View File

@ -364,6 +364,9 @@
/* Define to use have a strong random number source */ /* Define to use have a strong random number source */
#define HAVE_STRONG_RANDOM 1 #define HAVE_STRONG_RANDOM 1
/* Define to 1 if you have the `strsignal' function. */
/* #undef HAVE_STRSIGNAL */
/* Define to 1 if you have the `strtoll' function. */ /* Define to 1 if you have the `strtoll' function. */
#ifdef HAVE_LONG_LONG_INT_64 #ifdef HAVE_LONG_LONG_INT_64
#define HAVE_STRTOLL 1 #define HAVE_STRTOLL 1

View File

@ -205,6 +205,9 @@ extern char *pgwin32_setlocale(int category, const char *locale);
#define setlocale(a,b) pgwin32_setlocale(a,b) #define setlocale(a,b) pgwin32_setlocale(a,b)
#endif /* WIN32 */ #endif /* WIN32 */
/* Wrap strsignal(), or provide our own version if necessary */
extern const char *pg_strsignal(int signum);
/* Portable prompt handling */ /* Portable prompt handling */
extern void simple_prompt(const char *prompt, char *destination, size_t destlen, extern void simple_prompt(const char *prompt, char *destination, size_t destlen,
bool echo); bool echo);

View File

@ -32,7 +32,7 @@ LIBS += $(PTHREAD_LIBS)
OBJS = $(LIBOBJS) $(PG_CRC32C_OBJS) chklocale.o erand48.o inet_net_ntop.o \ OBJS = $(LIBOBJS) $(PG_CRC32C_OBJS) chklocale.o erand48.o inet_net_ntop.o \
noblock.o path.o pgcheckdir.o pgmkdirp.o pgsleep.o \ noblock.o path.o pgcheckdir.o pgmkdirp.o pgsleep.o \
pgstrcasecmp.o pqsignal.o \ pgstrcasecmp.o pgstrsignal.o pqsignal.o \
qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o
ifeq ($(enable_strong_random), yes) ifeq ($(enable_strong_random), yes)

64
src/port/pgstrsignal.c Normal file
View File

@ -0,0 +1,64 @@
/*-------------------------------------------------------------------------
*
* pgstrsignal.c
* Identify a Unix signal number
*
* On platforms compliant with modern POSIX, this just wraps strsignal(3).
* Elsewhere, we do the best we can.
*
* This file is not currently built in MSVC builds, since it's useless
* on non-Unix platforms.
*
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/port/pgstrsignal.c
*
*-------------------------------------------------------------------------
*/
#include "c.h"
/*
* pg_strsignal
*
* Return a string identifying the given Unix signal number.
*
* The result is declared "const char *" because callers should not
* modify the string. Note, however, that POSIX does not promise that
* the string will remain valid across later calls to strsignal().
*
* This version guarantees to return a non-NULL pointer, although
* some platforms' versions of strsignal() reputedly do not.
*
* Note that the fallback cases just return constant strings such as
* "unrecognized signal". Project style is for callers to print the
* numeric signal value along with the result of this function, so
* there's no need to work harder than that.
*/
const char *
pg_strsignal(int signum)
{
const char *result;
/*
* If we have strsignal(3), use that --- but check its result for NULL.
*/
#ifdef HAVE_STRSIGNAL
result = strsignal(signum);
if (result == NULL)
result = "unrecognized signal";
#else
/*
* We used to have code here to try to use sys_siglist[] if available.
* However, it seems that all platforms with sys_siglist[] have also had
* strsignal() for many years now, so that was just a waste of code.
*/
result = "(signal names not available on this platform)";
#endif
return result;
}

View File

@ -1559,14 +1559,9 @@ log_child_failure(int exitstatus)
#if defined(WIN32) #if defined(WIN32)
status(_(" (test process was terminated by exception 0x%X)"), status(_(" (test process was terminated by exception 0x%X)"),
WTERMSIG(exitstatus)); WTERMSIG(exitstatus));
#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST
status(_(" (test process was terminated by signal %d: %s)"),
WTERMSIG(exitstatus),
WTERMSIG(exitstatus) < NSIG ?
sys_siglist[WTERMSIG(exitstatus)] : "(unknown))");
#else #else
status(_(" (test process was terminated by signal %d)"), status(_(" (test process was terminated by signal %d: %s)"),
WTERMSIG(exitstatus)); WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus)));
#endif #endif
} }
else else