summaryrefslogtreecommitdiff
path: root/src/backend/port/sysv_sema.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-01-29 20:04:01 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-01-29 20:04:01 -0500
commitbf8ee6f157fa587f1c71bc9252e53a34bdc4e8be (patch)
tree839813e16a425d1af197b9136b611d31287747ba /src/backend/port/sysv_sema.c
parent56c08df55be5a3f12ddc45edcf29b6ecc4111e59 (diff)
Fix unsafe references to errno within error messaging logic.
Various places were supposing that errno could be expected to hold still within an ereport() nest or similar contexts. This isn't true necessarily, though in some cases it accidentally failed to fail depending on how the compiler chanced to order the subexpressions. This class of thinko explains recent reports of odd failures on clang-built versions, typically missing or inappropriate HINT fields in messages. Problem identified by Christian Kruse, who also submitted the patch this commit is based on. (I fixed a few issues in his patch and found a couple of additional places with the same disease.) Back-patch as appropriate to all supported branches.
Diffstat (limited to 'src/backend/port/sysv_sema.c')
-rw-r--r--src/backend/port/sysv_sema.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c
index 2988561d0ae..a7fccdfc059 100644
--- a/src/backend/port/sysv_sema.c
+++ b/src/backend/port/sysv_sema.c
@@ -91,15 +91,17 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
if (semId < 0)
{
+ int saved_errno = errno;
+
/*
* Fail quietly if error indicates a collision with existing set. One
* would expect EEXIST, given that we said IPC_EXCL, but perhaps we
* could get a permission violation instead? Also, EIDRM might occur
* if an old set is slated for destruction but not gone yet.
*/
- if (errno == EEXIST || errno == EACCES
+ if (saved_errno == EEXIST || saved_errno == EACCES
#ifdef EIDRM
- || errno == EIDRM
+ || saved_errno == EIDRM
#endif
)
return -1;
@@ -112,7 +114,7 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
errdetail("Failed system call was semget(%lu, %d, 0%o).",
(unsigned long) semKey, numSems,
IPC_CREAT | IPC_EXCL | IPCProtection),
- (errno == ENOSPC) ?
+ (saved_errno == ENOSPC) ?
errhint("This error does *not* mean that you have run out of disk space. "
"It occurs when either the system limit for the maximum number of "
"semaphore sets (SEMMNI), or the system wide maximum number of "
@@ -136,13 +138,17 @@ IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value)
semun.val = value;
if (semctl(semId, semNum, SETVAL, semun) < 0)
+ {
+ int saved_errno = errno;
+
ereport(FATAL,
(errmsg_internal("semctl(%d, %d, SETVAL, %d) failed: %m",
semId, semNum, value),
- (errno == ERANGE) ?
+ (saved_errno == ERANGE) ?
errhint("You possibly need to raise your kernel's SEMVMX value to be at least "
"%d. Look into the PostgreSQL documentation for details.",
value) : 0));
+ }
}
/*