From e86f2a0529b60d2a977597f1bd6266e580e9a175 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 23 Nov 2013 18:24:26 -0500
Subject: [PATCH] Ensure _dosmaperr() actually sets errno correctly.

If logging is enabled, either ereport() or fprintf() might stomp on errno
internally, causing this function to return the wrong result.  That might
only end in a misleading error report, but in any code that's examining
errno to decide what to do next, the consequences could be far graver.

This has been broken since the very first version of this file in 2006
... it's a bit astonishing that we didn't identify this long ago.

Reported by Amit Kapila, though this isn't his proposed fix.
---
 src/port/win32error.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/port/win32error.c b/src/port/win32error.c
index 41e8cd8bf35..91386dd8af8 100644
--- a/src/port/win32error.c
+++ b/src/port/win32error.c
@@ -179,14 +179,16 @@ _dosmaperr(unsigned long e)
 	{
 		if (doserrors[i].winerr == e)
 		{
-			errno = doserrors[i].doserr;
+			int			doserr = doserrors[i].doserr;
+
 #ifndef FRONTEND
 			ereport(DEBUG5,
 					(errmsg_internal("mapped win32 error code %lu to %d",
-									 e, errno)));
+									 e, doserr)));
 #elif FRONTEND_DEBUG
-			fprintf(stderr, _("mapped win32 error code %lu to %d"), e, errno);
+			fprintf(stderr, _("mapped win32 error code %lu to %d"), e, doserr);
 #endif
+			errno = doserr;
 			return;
 		}
 	}
-- 
GitLab