diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 2bb6cd976cffd79ffcee43ac37bf551dcb9644ec..6a842bd469fa428335433dedc785a214d9612e69 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -8,11 +8,10 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.77 2001/01/19 22:08:47 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.78 2001/01/21 00:59:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
 #include "postgres.h"
 
 #include <time.h>
@@ -44,6 +43,10 @@
 
 extern int	errno;
 
+#ifdef HAVE_SYS_NERR
+extern int sys_nerr;
+#endif
+
 extern CommandDest whereToSendOutput;
 
 #ifdef ENABLE_SYSLOG
@@ -120,10 +123,8 @@ elog(int lev, const char *fmt, ...)
 	char	   *msg_buf = msg_fixedbuf;
 	/* this buffer is only used for strange values of lev: */
 	char		prefix_buf[32];
-#ifdef HAVE_SYS_NERR
 	/* this buffer is only used if errno has a bogus value: */
 	char		errorstr_buf[32];
-#endif
 	const char *errorstr;
 	const char *prefix;
 	const char *cp;
@@ -137,19 +138,24 @@ elog(int lev, const char *fmt, ...)
 	if (lev <= DEBUG && Debugfile < 0)
 		return;					/* ignore debug msgs if noplace to send */
 
+	/* Save error str before calling any function that might change errno */
+	if (errno >= 0
 #ifdef HAVE_SYS_NERR
-	/* save errno string for %m */
-	if (errno < sys_nerr && errno >= 0)
+		&& errno <= sys_nerr
+#endif
+		)
 		errorstr = strerror(errno);
 	else
+		errorstr = NULL;
+	/*
+	 * Some strerror()s return an empty string for out-of-range errno.
+	 * This is ANSI C spec compliant, but not exactly useful.
+	 */
+	if (errorstr == NULL || *errorstr == '\0')
 	{
 		sprintf(errorstr_buf, "error %d", errno);
 		errorstr = errorstr_buf;
 	}
-#else
-	/* assume strerror() will cope gracefully with bogus errno values */
-	errorstr = strerror(errno);
-#endif
 
 	if (lev == ERROR || lev == FATAL)
 	{
diff --git a/src/backend/utils/error/exc.c b/src/backend/utils/error/exc.c
index 16faf93530b455ad889d12ebbd35bd95cf606c43..6f5420712e45cffd12885e97bc8a29b3ab8808fb 100644
--- a/src/backend/utils/error/exc.c
+++ b/src/backend/utils/error/exc.c
@@ -8,11 +8,12 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.33 2001/01/09 18:40:14 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.34 2001/01/21 00:59:26 tgl Exp $
  *
  * NOTE
  *	  XXX this code needs improvement--check for state violations and
  *	  XXX reset after handling an exception.
+ *	  XXX Probably should be merged with elog.c.
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +24,13 @@
 #include "storage/ipc.h"
 #include "utils/exc.h"
 
+extern int	errno;
+
+#ifdef HAVE_SYS_NERR
+extern int sys_nerr;
+#endif
+
+
 static void ExcUnCaught(Exception *excP, ExcDetail detail, ExcData data,
 			ExcMessage message);
 static void ExcPrint(Exception *excP, ExcDetail detail, ExcData data,
@@ -40,8 +48,6 @@ ExcFrame   *ExcCurFrameP = NULL;
 
 static ExcProc *ExcUnCaughtP = NULL;
 
-extern char *ProgramName;
-
 /*
  * Exported Functions
  */
@@ -94,49 +100,49 @@ EnableExceptionHandling(bool on)
 	ExceptionHandlingEnabled = on;
 }
 
-
-extern int	errno;
-
 static void
 ExcPrint(Exception *excP,
 		 ExcDetail detail,
 		 ExcData data,
 		 ExcMessage message)
 {
+	/* this buffer is only used if errno has a bogus value: */
+	char		errorstr_buf[32];
+	const char *errorstr;
+
 #ifdef	lint
 	data = data;
 #endif
 
-	fflush(stdout);				/* In case stderr is buffered */
-
-#if		0
-	if (ProgramName != NULL && *ProgramName != '\0')
-		fprintf(stderr, "%s: ", ProgramName);
+	/* Save error str before calling any function that might change errno */
+	if (errno >= 0
+#ifdef HAVE_SYS_NERR
+		&& errno <= sys_nerr
 #endif
+		)
+		errorstr = strerror(errno);
+	else
+		errorstr = NULL;
+	/*
+	 * Some strerror()s return an empty string for out-of-range errno.
+	 * This is ANSI C spec compliant, but not exactly useful.
+	 */
+	if (errorstr == NULL || *errorstr == '\0')
+	{
+		sprintf(errorstr_buf, "error %d", errno);
+		errorstr = errorstr_buf;
+	}
+
+	fflush(stdout);				/* In case stderr is buffered */
 
 	if (message != NULL)
 		fprintf(stderr, "%s", message);
 	else if (excP->message != NULL)
 		fprintf(stderr, "%s", excP->message);
 	else
-#ifdef	lint
-		fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", excP);
-#else
-		fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", (long) excP);
-#endif
-
-	fprintf(stderr, " (%ld)", detail);
-
-#ifdef HAVE_SYS_NERR
-	if (errno > 0 && errno < sys_nerr)
-#else
-    if (errno > 0)
-#endif
-		fprintf(stderr, " [%s]", strerror(errno));
-	else if (errno != 0)
-		fprintf(stderr, " [Error %d]", errno);
+		fprintf(stderr, "UNNAMED EXCEPTION %p", excP);
 
-	fprintf(stderr, "\n");
+	fprintf(stderr, " (%ld) [%s]\n", detail, errorstr);
 
 	fflush(stderr);
 }
diff --git a/src/include/c.h b/src/include/c.h
index 4e5c7ff95f1282354d4a23a3e2bd1d2714eb74b6..73b5c5d579fb94c9fa84645f0d7c4ab1dc64db21 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: c.h,v 1.87 2001/01/09 18:40:15 petere Exp $
+ * $Id: c.h,v 1.88 2001/01/21 00:59:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -993,10 +993,6 @@ extern int	vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 #include <regex/utils.h>
 #endif
 
-#ifdef HAVE_SYS_NERR
-extern int sys_nerr;
-#endif
-
 /* ----------------
  *		end of c.h
  * ----------------