Skip to content

Commit 5491233

Browse files
committed
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.
1 parent c431db9 commit 5491233

File tree

6 files changed

+79
-16
lines changed

6 files changed

+79
-16
lines changed

src/backend/commands/async.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.73 2000/11/28 23:27:54 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.74 2000/12/18 17:33:40 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -589,6 +589,7 @@ AtAbort_Notify()
589589
void
590590
Async_NotifyHandler(SIGNAL_ARGS)
591591
{
592+
int save_errno = errno;
592593

593594
/*
594595
* Note: this is a SIGNAL HANDLER. You must be very wary what you do
@@ -637,6 +638,8 @@ Async_NotifyHandler(SIGNAL_ARGS)
637638
*/
638639
notifyInterruptOccurred = 1;
639640
}
641+
642+
errno = save_errno;
640643
}
641644

642645
/*

src/backend/postmaster/postmaster.c

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.198 2000/12/03 20:45:34 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.199 2000/12/18 17:33:40 tgl Exp $
1515
*
1616
* NOTES
1717
*
@@ -217,7 +217,7 @@ static int initMasks(fd_set *rmask, fd_set *wmask);
217217
static char *canAcceptConnections(void);
218218
static long PostmasterRandom(void);
219219
static void RandomSalt(char *salt);
220-
static void SignalChildren(SIGNAL_ARGS);
220+
static void SignalChildren(int signal);
221221
static int CountChildren(void);
222222
static bool CreateOptsFile(int argc, char *argv[]);
223223

@@ -1303,10 +1303,13 @@ reset_shared(unsigned short port)
13031303
static void
13041304
SIGHUP_handler(SIGNAL_ARGS)
13051305
{
1306+
int save_errno = errno;
1307+
13061308
if (Shutdown > SmartShutdown)
13071309
return;
13081310
got_SIGHUP = true;
13091311
SignalChildren(SIGHUP);
1312+
errno = save_errno;
13101313
}
13111314

13121315

@@ -1317,6 +1320,8 @@ SIGHUP_handler(SIGNAL_ARGS)
13171320
static void
13181321
pmdie(SIGNAL_ARGS)
13191322
{
1323+
int save_errno = errno;
1324+
13201325
PG_SETMASK(&BlockSig);
13211326

13221327
if (DebugLvl >= 1)
@@ -1330,8 +1335,12 @@ pmdie(SIGNAL_ARGS)
13301335
* Send SIGUSR2 to all children (AsyncNotifyHandler)
13311336
*/
13321337
if (Shutdown > SmartShutdown)
1338+
{
1339+
errno = save_errno;
13331340
return;
1341+
}
13341342
SignalChildren(SIGUSR2);
1343+
errno = save_errno;
13351344
return;
13361345

13371346
case SIGTERM:
@@ -1342,24 +1351,34 @@ pmdie(SIGNAL_ARGS)
13421351
* let children to end their work and ShutdownDataBase.
13431352
*/
13441353
if (Shutdown >= SmartShutdown)
1354+
{
1355+
errno = save_errno;
13451356
return;
1357+
}
13461358
Shutdown = SmartShutdown;
13471359
tnow = time(NULL);
13481360
fprintf(stderr, "Smart Shutdown request at %s", ctime(&tnow));
13491361
fflush(stderr);
13501362
if (DLGetHead(BackendList)) /* let reaper() handle this */
1363+
{
1364+
errno = save_errno;
13511365
return;
1366+
}
13521367

13531368
/*
13541369
* No children left. Shutdown data base system.
13551370
*/
13561371
if (StartupPID > 0 || FatalError) /* let reaper() handle
13571372
* this */
1373+
{
1374+
errno = save_errno;
13581375
return;
1376+
}
13591377
if (ShutdownPID > 0)
13601378
abort();
13611379

13621380
ShutdownPID = ShutdownDataBase();
1381+
errno = save_errno;
13631382
return;
13641383

13651384
case SIGINT:
@@ -1371,7 +1390,10 @@ pmdie(SIGNAL_ARGS)
13711390
* and exit) and ShutdownDataBase.
13721391
*/
13731392
if (Shutdown >= FastShutdown)
1393+
{
1394+
errno = save_errno;
13741395
return;
1396+
}
13751397
tnow = time(NULL);
13761398
fprintf(stderr, "Fast Shutdown request at %s", ctime(&tnow));
13771399
fflush(stderr);
@@ -1384,11 +1406,13 @@ pmdie(SIGNAL_ARGS)
13841406
fflush(stderr);
13851407
SignalChildren(SIGTERM);
13861408
}
1409+
errno = save_errno;
13871410
return;
13881411
}
13891412
if (Shutdown > NoShutdown)
13901413
{
13911414
Shutdown = FastShutdown;
1415+
errno = save_errno;
13921416
return;
13931417
}
13941418
Shutdown = FastShutdown;
@@ -1398,11 +1422,15 @@ pmdie(SIGNAL_ARGS)
13981422
*/
13991423
if (StartupPID > 0 || FatalError) /* let reaper() handle
14001424
* this */
1425+
{
1426+
errno = save_errno;
14011427
return;
1428+
}
14021429
if (ShutdownPID > 0)
14031430
abort();
14041431

14051432
ShutdownPID = ShutdownDataBase();
1433+
errno = save_errno;
14061434
return;
14071435

14081436
case SIGQUIT:
@@ -1435,18 +1463,18 @@ pmdie(SIGNAL_ARGS)
14351463
static void
14361464
reaper(SIGNAL_ARGS)
14371465
{
1438-
/* GH: replace waitpid for !HAVE_WAITPID. Does this work ? */
1466+
int save_errno = errno;
14391467
#ifdef HAVE_WAITPID
14401468
int status; /* backend exit status */
1441-
14421469
#else
14431470
union wait status; /* backend exit status */
1444-
14451471
#endif
14461472
int exitstatus;
14471473
int pid; /* process id of dead backend */
14481474

14491475
PG_SETMASK(&BlockSig);
1476+
/* It's not really necessary to reset the handler each time is it? */
1477+
pqsignal(SIGCHLD, reaper);
14501478

14511479
if (DebugLvl)
14521480
fprintf(stderr, "%s: reaping dead processes...\n",
@@ -1499,12 +1527,11 @@ reaper(SIGNAL_ARGS)
14991527
CheckPointPID = 0;
15001528
checkpointed = time(NULL);
15011529

1502-
pqsignal(SIGCHLD, reaper);
1530+
errno = save_errno;
15031531
return;
15041532
}
15051533
CleanupProc(pid, exitstatus);
15061534
}
1507-
pqsignal(SIGCHLD, reaper);
15081535

15091536
if (FatalError)
15101537
{
@@ -1513,9 +1540,15 @@ reaper(SIGNAL_ARGS)
15131540
* Wait for all children exit, then reset shmem and StartupDataBase.
15141541
*/
15151542
if (DLGetHead(BackendList))
1543+
{
1544+
errno = save_errno;
15161545
return;
1546+
}
15171547
if (StartupPID > 0 || ShutdownPID > 0)
1548+
{
1549+
errno = save_errno;
15181550
return;
1551+
}
15191552
tnow = time(NULL);
15201553
fprintf(stderr, "Server processes were terminated at %s"
15211554
"Reinitializing shared memory and semaphores\n",
@@ -1526,18 +1559,26 @@ reaper(SIGNAL_ARGS)
15261559
reset_shared(PostPortNumber);
15271560

15281561
StartupPID = StartupDataBase();
1562+
errno = save_errno;
15291563
return;
15301564
}
15311565

15321566
if (Shutdown > NoShutdown)
15331567
{
15341568
if (DLGetHead(BackendList))
1569+
{
1570+
errno = save_errno;
15351571
return;
1572+
}
15361573
if (StartupPID > 0 || ShutdownPID > 0)
1574+
{
1575+
errno = save_errno;
15371576
return;
1577+
}
15381578
ShutdownPID = ShutdownDataBase();
15391579
}
15401580

1581+
errno = save_errno;
15411582
}
15421583

15431584
/*
@@ -2002,6 +2043,7 @@ ExitPostmaster(int status)
20022043
static void
20032044
dumpstatus(SIGNAL_ARGS)
20042045
{
2046+
int save_errno = errno;
20052047
Dlelem *curr;
20062048

20072049
PG_SETMASK(&BlockSig);
@@ -2015,6 +2057,7 @@ dumpstatus(SIGNAL_ARGS)
20152057
fprintf(stderr, "\tsock %d\n", port->sock);
20162058
curr = DLGetSucc(curr);
20172059
}
2060+
errno = save_errno;
20182061
}
20192062

20202063
/*

src/backend/storage/lmgr/proc.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.88 2000/12/18 17:33:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -48,10 +48,11 @@
4848
* This is so that we can support more backends. (system-wide semaphore
4949
* sets run out pretty fast.) -ay 4/95
5050
*
51-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.87 2000/12/18 00:44:47 tgl Exp $
51+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.88 2000/12/18 17:33:41 tgl Exp $
5252
*/
5353
#include "postgres.h"
5454

55+
#include <errno.h>
5556
#include <sys/time.h>
5657
#include <unistd.h>
5758
#include <signal.h>
@@ -298,7 +299,7 @@ InitProcess(void)
298299
}
299300

300301
/* -----------------------
301-
* get off the wait queue
302+
* get process off any wait queue it might be on
302303
* -----------------------
303304
*/
304305
static bool
@@ -623,10 +624,11 @@ ins:;
623624
waitQueue->size++;
624625

625626
lock->waitMask |= myMask;
626-
SpinRelease(spinlock);
627627

628628
MyProc->errType = NO_ERROR; /* initialize result for success */
629629

630+
SpinRelease(spinlock);
631+
630632
/* --------------
631633
* Set timer so we can wake up after awhile and check for a deadlock.
632634
* If a deadlock is detected, the handler releases the process's
@@ -826,6 +828,7 @@ ProcAddLock(SHM_QUEUE *elem)
826828
void
827829
HandleDeadLock(SIGNAL_ARGS)
828830
{
831+
int save_errno = errno;
829832
LOCK *mywaitlock;
830833

831834
LockLockTable();
@@ -846,6 +849,7 @@ HandleDeadLock(SIGNAL_ARGS)
846849
MyProc->links.next == INVALID_OFFSET)
847850
{
848851
UnlockLockTable();
852+
errno = save_errno;
849853
return;
850854
}
851855

@@ -858,6 +862,7 @@ HandleDeadLock(SIGNAL_ARGS)
858862
{
859863
/* No deadlock, so keep waiting */
860864
UnlockLockTable();
865+
errno = save_errno;
861866
return;
862867
}
863868

@@ -891,6 +896,7 @@ HandleDeadLock(SIGNAL_ARGS)
891896
* conditions. i don't claim to understand this...
892897
*/
893898
UnlockLockTable();
899+
errno = save_errno;
894900
}
895901

896902
void

src/backend/tcop/postgres.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.195 2000/12/18 00:44:47 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.196 2000/12/18 17:33:41 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -984,8 +984,11 @@ FloatExceptionHandler(SIGNAL_ARGS)
984984
static void
985985
QueryCancelHandler(SIGNAL_ARGS)
986986
{
987+
int save_errno = errno;
988+
987989
QueryCancel = true;
988990
LockWaitCancel();
991+
errno = save_errno;
989992
}
990993

991994
void
@@ -1646,7 +1649,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
16461649
if (!IsUnderPostmaster)
16471650
{
16481651
puts("\nPOSTGRES backend interactive interface ");
1649-
puts("$Revision: 1.195 $ $Date: 2000/12/18 00:44:47 $\n");
1652+
puts("$Revision: 1.196 $ $Date: 2000/12/18 17:33:41 $\n");
16501653
}
16511654

16521655
/*

src/bin/psql/common.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright 2000 by PostgreSQL Global Development Group
55
*
6-
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.28 2000/12/15 17:54:43 petere Exp $
6+
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.29 2000/12/18 17:33:42 tgl Exp $
77
*/
88
#include "postgres.h"
99
#include "common.h"
@@ -258,6 +258,8 @@ volatile bool cancel_pressed;
258258
void
259259
handle_sigint(SIGNAL_ARGS)
260260
{
261+
int save_errno = errno;
262+
261263
/* Don't muck around if copying in or prompting for a password. */
262264
if ((copy_in_state && pset.cur_cmd_interactive) || prompt_state)
263265
return;
@@ -274,6 +276,7 @@ handle_sigint(SIGNAL_ARGS)
274276
write_stderr("Could not send cancel request: ");
275277
write_stderr(PQerrorMessage(cancelConn));
276278
}
279+
errno = save_errno; /* just in case the write changed it */
277280
}
278281

279282
#endif /* not WIN32 */

0 commit comments

Comments
 (0)