Commit 5491233f authored by Tom Lane's avatar Tom Lane

Ensure that 'errno' is saved and restored by all signal handlers that

might change it.  Experimentation shows that the signal handler call
mechanism does not save/restore errno for you, at least not on Linux
or HPUX, so this is definitely a real risk.
parent c431db97
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.73 2000/11/28 23:27:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.74 2000/12/18 17:33:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -589,6 +589,7 @@ AtAbort_Notify() ...@@ -589,6 +589,7 @@ AtAbort_Notify()
void void
Async_NotifyHandler(SIGNAL_ARGS) Async_NotifyHandler(SIGNAL_ARGS)
{ {
int save_errno = errno;
/* /*
* Note: this is a SIGNAL HANDLER. You must be very wary what you do * Note: this is a SIGNAL HANDLER. You must be very wary what you do
...@@ -637,6 +638,8 @@ Async_NotifyHandler(SIGNAL_ARGS) ...@@ -637,6 +638,8 @@ Async_NotifyHandler(SIGNAL_ARGS)
*/ */
notifyInterruptOccurred = 1; notifyInterruptOccurred = 1;
} }
errno = save_errno;
} }
/* /*
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.198 2000/12/03 20:45:34 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.199 2000/12/18 17:33:40 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -217,7 +217,7 @@ static int initMasks(fd_set *rmask, fd_set *wmask); ...@@ -217,7 +217,7 @@ static int initMasks(fd_set *rmask, fd_set *wmask);
static char *canAcceptConnections(void); static char *canAcceptConnections(void);
static long PostmasterRandom(void); static long PostmasterRandom(void);
static void RandomSalt(char *salt); static void RandomSalt(char *salt);
static void SignalChildren(SIGNAL_ARGS); static void SignalChildren(int signal);
static int CountChildren(void); static int CountChildren(void);
static bool CreateOptsFile(int argc, char *argv[]); static bool CreateOptsFile(int argc, char *argv[]);
...@@ -1303,10 +1303,13 @@ reset_shared(unsigned short port) ...@@ -1303,10 +1303,13 @@ reset_shared(unsigned short port)
static void static void
SIGHUP_handler(SIGNAL_ARGS) SIGHUP_handler(SIGNAL_ARGS)
{ {
int save_errno = errno;
if (Shutdown > SmartShutdown) if (Shutdown > SmartShutdown)
return; return;
got_SIGHUP = true; got_SIGHUP = true;
SignalChildren(SIGHUP); SignalChildren(SIGHUP);
errno = save_errno;
} }
...@@ -1317,6 +1320,8 @@ SIGHUP_handler(SIGNAL_ARGS) ...@@ -1317,6 +1320,8 @@ SIGHUP_handler(SIGNAL_ARGS)
static void static void
pmdie(SIGNAL_ARGS) pmdie(SIGNAL_ARGS)
{ {
int save_errno = errno;
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
if (DebugLvl >= 1) if (DebugLvl >= 1)
...@@ -1330,8 +1335,12 @@ pmdie(SIGNAL_ARGS) ...@@ -1330,8 +1335,12 @@ pmdie(SIGNAL_ARGS)
* Send SIGUSR2 to all children (AsyncNotifyHandler) * Send SIGUSR2 to all children (AsyncNotifyHandler)
*/ */
if (Shutdown > SmartShutdown) if (Shutdown > SmartShutdown)
{
errno = save_errno;
return; return;
}
SignalChildren(SIGUSR2); SignalChildren(SIGUSR2);
errno = save_errno;
return; return;
case SIGTERM: case SIGTERM:
...@@ -1342,24 +1351,34 @@ pmdie(SIGNAL_ARGS) ...@@ -1342,24 +1351,34 @@ pmdie(SIGNAL_ARGS)
* let children to end their work and ShutdownDataBase. * let children to end their work and ShutdownDataBase.
*/ */
if (Shutdown >= SmartShutdown) if (Shutdown >= SmartShutdown)
{
errno = save_errno;
return; return;
}
Shutdown = SmartShutdown; Shutdown = SmartShutdown;
tnow = time(NULL); tnow = time(NULL);
fprintf(stderr, "Smart Shutdown request at %s", ctime(&tnow)); fprintf(stderr, "Smart Shutdown request at %s", ctime(&tnow));
fflush(stderr); fflush(stderr);
if (DLGetHead(BackendList)) /* let reaper() handle this */ if (DLGetHead(BackendList)) /* let reaper() handle this */
{
errno = save_errno;
return; return;
}
/* /*
* No children left. Shutdown data base system. * No children left. Shutdown data base system.
*/ */
if (StartupPID > 0 || FatalError) /* let reaper() handle if (StartupPID > 0 || FatalError) /* let reaper() handle
* this */ * this */
{
errno = save_errno;
return; return;
}
if (ShutdownPID > 0) if (ShutdownPID > 0)
abort(); abort();
ShutdownPID = ShutdownDataBase(); ShutdownPID = ShutdownDataBase();
errno = save_errno;
return; return;
case SIGINT: case SIGINT:
...@@ -1371,7 +1390,10 @@ pmdie(SIGNAL_ARGS) ...@@ -1371,7 +1390,10 @@ pmdie(SIGNAL_ARGS)
* and exit) and ShutdownDataBase. * and exit) and ShutdownDataBase.
*/ */
if (Shutdown >= FastShutdown) if (Shutdown >= FastShutdown)
{
errno = save_errno;
return; return;
}
tnow = time(NULL); tnow = time(NULL);
fprintf(stderr, "Fast Shutdown request at %s", ctime(&tnow)); fprintf(stderr, "Fast Shutdown request at %s", ctime(&tnow));
fflush(stderr); fflush(stderr);
...@@ -1384,11 +1406,13 @@ pmdie(SIGNAL_ARGS) ...@@ -1384,11 +1406,13 @@ pmdie(SIGNAL_ARGS)
fflush(stderr); fflush(stderr);
SignalChildren(SIGTERM); SignalChildren(SIGTERM);
} }
errno = save_errno;
return; return;
} }
if (Shutdown > NoShutdown) if (Shutdown > NoShutdown)
{ {
Shutdown = FastShutdown; Shutdown = FastShutdown;
errno = save_errno;
return; return;
} }
Shutdown = FastShutdown; Shutdown = FastShutdown;
...@@ -1398,11 +1422,15 @@ pmdie(SIGNAL_ARGS) ...@@ -1398,11 +1422,15 @@ pmdie(SIGNAL_ARGS)
*/ */
if (StartupPID > 0 || FatalError) /* let reaper() handle if (StartupPID > 0 || FatalError) /* let reaper() handle
* this */ * this */
{
errno = save_errno;
return; return;
}
if (ShutdownPID > 0) if (ShutdownPID > 0)
abort(); abort();
ShutdownPID = ShutdownDataBase(); ShutdownPID = ShutdownDataBase();
errno = save_errno;
return; return;
case SIGQUIT: case SIGQUIT:
...@@ -1435,18 +1463,18 @@ pmdie(SIGNAL_ARGS) ...@@ -1435,18 +1463,18 @@ pmdie(SIGNAL_ARGS)
static void static void
reaper(SIGNAL_ARGS) reaper(SIGNAL_ARGS)
{ {
/* GH: replace waitpid for !HAVE_WAITPID. Does this work ? */ int save_errno = errno;
#ifdef HAVE_WAITPID #ifdef HAVE_WAITPID
int status; /* backend exit status */ int status; /* backend exit status */
#else #else
union wait status; /* backend exit status */ union wait status; /* backend exit status */
#endif #endif
int exitstatus; int exitstatus;
int pid; /* process id of dead backend */ int pid; /* process id of dead backend */
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* It's not really necessary to reset the handler each time is it? */
pqsignal(SIGCHLD, reaper);
if (DebugLvl) if (DebugLvl)
fprintf(stderr, "%s: reaping dead processes...\n", fprintf(stderr, "%s: reaping dead processes...\n",
...@@ -1499,12 +1527,11 @@ reaper(SIGNAL_ARGS) ...@@ -1499,12 +1527,11 @@ reaper(SIGNAL_ARGS)
CheckPointPID = 0; CheckPointPID = 0;
checkpointed = time(NULL); checkpointed = time(NULL);
pqsignal(SIGCHLD, reaper); errno = save_errno;
return; return;
} }
CleanupProc(pid, exitstatus); CleanupProc(pid, exitstatus);
} }
pqsignal(SIGCHLD, reaper);
if (FatalError) if (FatalError)
{ {
...@@ -1513,9 +1540,15 @@ reaper(SIGNAL_ARGS) ...@@ -1513,9 +1540,15 @@ reaper(SIGNAL_ARGS)
* Wait for all children exit, then reset shmem and StartupDataBase. * Wait for all children exit, then reset shmem and StartupDataBase.
*/ */
if (DLGetHead(BackendList)) if (DLGetHead(BackendList))
{
errno = save_errno;
return; return;
}
if (StartupPID > 0 || ShutdownPID > 0) if (StartupPID > 0 || ShutdownPID > 0)
{
errno = save_errno;
return; return;
}
tnow = time(NULL); tnow = time(NULL);
fprintf(stderr, "Server processes were terminated at %s" fprintf(stderr, "Server processes were terminated at %s"
"Reinitializing shared memory and semaphores\n", "Reinitializing shared memory and semaphores\n",
...@@ -1526,18 +1559,26 @@ reaper(SIGNAL_ARGS) ...@@ -1526,18 +1559,26 @@ reaper(SIGNAL_ARGS)
reset_shared(PostPortNumber); reset_shared(PostPortNumber);
StartupPID = StartupDataBase(); StartupPID = StartupDataBase();
errno = save_errno;
return; return;
} }
if (Shutdown > NoShutdown) if (Shutdown > NoShutdown)
{ {
if (DLGetHead(BackendList)) if (DLGetHead(BackendList))
{
errno = save_errno;
return; return;
}
if (StartupPID > 0 || ShutdownPID > 0) if (StartupPID > 0 || ShutdownPID > 0)
{
errno = save_errno;
return; return;
}
ShutdownPID = ShutdownDataBase(); ShutdownPID = ShutdownDataBase();
} }
errno = save_errno;
} }
/* /*
...@@ -2002,6 +2043,7 @@ ExitPostmaster(int status) ...@@ -2002,6 +2043,7 @@ ExitPostmaster(int status)
static void static void
dumpstatus(SIGNAL_ARGS) dumpstatus(SIGNAL_ARGS)
{ {
int save_errno = errno;
Dlelem *curr; Dlelem *curr;
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
...@@ -2015,6 +2057,7 @@ dumpstatus(SIGNAL_ARGS) ...@@ -2015,6 +2057,7 @@ dumpstatus(SIGNAL_ARGS)
fprintf(stderr, "\tsock %d\n", port->sock); fprintf(stderr, "\tsock %d\n", port->sock);
curr = DLGetSucc(curr); curr = DLGetSucc(curr);
} }
errno = save_errno;
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.88 2000/12/18 17:33:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -48,10 +48,11 @@ ...@@ -48,10 +48,11 @@
* This is so that we can support more backends. (system-wide semaphore * This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95 * sets run out pretty fast.) -ay 4/95
* *
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.88 2000/12/18 17:33:41 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
#include <errno.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
...@@ -298,7 +299,7 @@ InitProcess(void) ...@@ -298,7 +299,7 @@ InitProcess(void)
} }
/* ----------------------- /* -----------------------
* get off the wait queue * get process off any wait queue it might be on
* ----------------------- * -----------------------
*/ */
static bool static bool
...@@ -623,10 +624,11 @@ ins:; ...@@ -623,10 +624,11 @@ ins:;
waitQueue->size++; waitQueue->size++;
lock->waitMask |= myMask; lock->waitMask |= myMask;
SpinRelease(spinlock);
MyProc->errType = NO_ERROR; /* initialize result for success */ MyProc->errType = NO_ERROR; /* initialize result for success */
SpinRelease(spinlock);
/* -------------- /* --------------
* Set timer so we can wake up after awhile and check for a deadlock. * Set timer so we can wake up after awhile and check for a deadlock.
* If a deadlock is detected, the handler releases the process's * If a deadlock is detected, the handler releases the process's
...@@ -826,6 +828,7 @@ ProcAddLock(SHM_QUEUE *elem) ...@@ -826,6 +828,7 @@ ProcAddLock(SHM_QUEUE *elem)
void void
HandleDeadLock(SIGNAL_ARGS) HandleDeadLock(SIGNAL_ARGS)
{ {
int save_errno = errno;
LOCK *mywaitlock; LOCK *mywaitlock;
LockLockTable(); LockLockTable();
...@@ -846,6 +849,7 @@ HandleDeadLock(SIGNAL_ARGS) ...@@ -846,6 +849,7 @@ HandleDeadLock(SIGNAL_ARGS)
MyProc->links.next == INVALID_OFFSET) MyProc->links.next == INVALID_OFFSET)
{ {
UnlockLockTable(); UnlockLockTable();
errno = save_errno;
return; return;
} }
...@@ -858,6 +862,7 @@ HandleDeadLock(SIGNAL_ARGS) ...@@ -858,6 +862,7 @@ HandleDeadLock(SIGNAL_ARGS)
{ {
/* No deadlock, so keep waiting */ /* No deadlock, so keep waiting */
UnlockLockTable(); UnlockLockTable();
errno = save_errno;
return; return;
} }
...@@ -891,6 +896,7 @@ HandleDeadLock(SIGNAL_ARGS) ...@@ -891,6 +896,7 @@ HandleDeadLock(SIGNAL_ARGS)
* conditions. i don't claim to understand this... * conditions. i don't claim to understand this...
*/ */
UnlockLockTable(); UnlockLockTable();
errno = save_errno;
} }
void void
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.195 2000/12/18 00:44:47 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.196 2000/12/18 17:33:41 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -984,8 +984,11 @@ FloatExceptionHandler(SIGNAL_ARGS) ...@@ -984,8 +984,11 @@ FloatExceptionHandler(SIGNAL_ARGS)
static void static void
QueryCancelHandler(SIGNAL_ARGS) QueryCancelHandler(SIGNAL_ARGS)
{ {
int save_errno = errno;
QueryCancel = true; QueryCancel = true;
LockWaitCancel(); LockWaitCancel();
errno = save_errno;
} }
void void
...@@ -1646,7 +1649,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1646,7 +1649,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.195 $ $Date: 2000/12/18 00:44:47 $\n"); puts("$Revision: 1.196 $ $Date: 2000/12/18 17:33:41 $\n");
} }
/* /*
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.28 2000/12/15 17:54:43 petere Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.29 2000/12/18 17:33:42 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
#include "common.h" #include "common.h"
...@@ -258,6 +258,8 @@ volatile bool cancel_pressed; ...@@ -258,6 +258,8 @@ volatile bool cancel_pressed;
void void
handle_sigint(SIGNAL_ARGS) handle_sigint(SIGNAL_ARGS)
{ {
int save_errno = errno;
/* Don't muck around if copying in or prompting for a password. */ /* Don't muck around if copying in or prompting for a password. */
if ((copy_in_state && pset.cur_cmd_interactive) || prompt_state) if ((copy_in_state && pset.cur_cmd_interactive) || prompt_state)
return; return;
...@@ -274,6 +276,7 @@ handle_sigint(SIGNAL_ARGS) ...@@ -274,6 +276,7 @@ handle_sigint(SIGNAL_ARGS)
write_stderr("Could not send cancel request: "); write_stderr("Could not send cancel request: ");
write_stderr(PQerrorMessage(cancelConn)); write_stderr(PQerrorMessage(cancelConn));
} }
errno = save_errno; /* just in case the write changed it */
} }
#endif /* not WIN32 */ #endif /* not WIN32 */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.154 2000/12/07 02:04:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.155 2000/12/18 17:33:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2084,6 +2084,7 @@ PQresetPoll(PGconn *conn) ...@@ -2084,6 +2084,7 @@ PQresetPoll(PGconn *conn)
* malloc/free are often non-reentrant, and anything that might call them is * malloc/free are often non-reentrant, and anything that might call them is
* just as dangerous. We avoid sprintf here for that reason. Building up * just as dangerous. We avoid sprintf here for that reason. Building up
* error messages with strcpy/strcat is tedious but should be quite safe. * error messages with strcpy/strcat is tedious but should be quite safe.
* We also save/restore errno in case the signal handler support doesn't.
* *
* NOTE: this routine must not generate any error message longer than * NOTE: this routine must not generate any error message longer than
* INITIAL_EXPBUFFER_SIZE (currently 256), since we dare not try to * INITIAL_EXPBUFFER_SIZE (currently 256), since we dare not try to
...@@ -2093,6 +2094,7 @@ PQresetPoll(PGconn *conn) ...@@ -2093,6 +2094,7 @@ PQresetPoll(PGconn *conn)
int int
PQrequestCancel(PGconn *conn) PQrequestCancel(PGconn *conn)
{ {
int save_errno = errno;
int tmpsock = -1; int tmpsock = -1;
struct struct
{ {
...@@ -2109,6 +2111,7 @@ PQrequestCancel(PGconn *conn) ...@@ -2109,6 +2111,7 @@ PQrequestCancel(PGconn *conn)
strcpy(conn->errorMessage.data, strcpy(conn->errorMessage.data,
"PQrequestCancel() -- connection is not open\n"); "PQrequestCancel() -- connection is not open\n");
conn->errorMessage.len = strlen(conn->errorMessage.data); conn->errorMessage.len = strlen(conn->errorMessage.data);
errno = save_errno;
return FALSE; return FALSE;
} }
...@@ -2154,6 +2157,7 @@ PQrequestCancel(PGconn *conn) ...@@ -2154,6 +2157,7 @@ PQrequestCancel(PGconn *conn)
close(tmpsock); close(tmpsock);
#endif #endif
errno = save_errno;
return TRUE; return TRUE;
cancel_errReturn: cancel_errReturn:
...@@ -2168,6 +2172,7 @@ cancel_errReturn: ...@@ -2168,6 +2172,7 @@ cancel_errReturn:
close(tmpsock); close(tmpsock);
#endif #endif
} }
errno = save_errno;
return FALSE; return FALSE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment