============================================================================
POSTGRESQL BUG REPORT TEMPLATE
============================================================================
Your name : Pete Forman
Your email address : pete.forman@westgeo.com
System Configuration
---------------------
Architecture (example: Intel Pentium) : Intel Pentium II
Operating System (example: Linux 2.0.26 ELF) : Cygwin B20.1 and others
PostgreSQL version (example: PostgreSQL-7.1): PostgreSQL-7.1
Compiler used (example: gcc 2.8.0) : egcs-2.91.57
Please enter a FULL description of your problem:
------------------------------------------------
Files backend/utils/error/elog.c and exc.c had errors building on
Cygwin B20.1 (and BeOS so I'm told). The current source (elog.c,v
1.64, exc.c,v 1.31) is fixed for Cygwin 1.1 and BeOS but not very
robustly. This patch works on the systems and versions I've tested.
Others were tested by subscribers to PORTS.
The changes made are:
1) Remove declarations of "extern int errno;".
- errno does not have to be an int, it may be a macro. In
threaded code it almost certainly will be the latter.
<errno.h> will already have the correct declaration.
2) Remove sys_nerr and _sys_nerr.
- These are not portable, e.g. older Cygwin and BeOS.
In any case the test errno < sys_nerr assumes that valid
errnos are contiguous. strerror() may go wrong on holes.
3) Test both errno and the return of strerror() to see if it fails.
- This works an all(?) OSs except HPUX and QNX. These then have
a minor limitation that if the elog() is called with an out of
range errno then its number will not be printed. I would
expect that it would be called with a valid errno.
In exc.c both the errno and its message, if available, are now
printed.
I leave it to the user to call elog(..., "%d: %m", errno, ...)
if they want to guarantee a number.
Anything more complicated will need to involve configure. I
am loathe to do so because this sort of error code is called
infrequently and will only be tested lightly. Keep it
simple.
4) Remove any OS specific clauses: ifdef __CYGWIN__ or __BEOS__.
I have posted an equivalent patch to PORTS for 7.0.2.
Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------
If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------
*** src/backend/utils/error/elog.c.orig Sun Oct 8 08:00:18 2000
--- src/backend/utils/error/elog.c Wed Oct 25 16:55:50 2000
***************
*** 37,49 ****
#include "tcop/tcopprot.h"
#include "commands/copy.h"
- extern int errno;
-
- #ifdef __CYGWIN__
- # define sys_nerr _sys_nerr
- #endif
- extern int sys_nerr;
-
extern CommandDest whereToSendOutput;
#ifdef ENABLE_SYSLOG
--- 37,42 ----
***************
*** 130,152 ****
int len;
/* size of the prefix needed for timestamp and pid, if enabled */
size_t timestamp_size;
if (lev <= DEBUG && Debugfile < 0)
return; /* ignore debug msgs if noplace to send */
! /* BeOS doesn't have sys_nerr and should be able to use strerror()... */
! #ifndef __BEOS__
! /* save errno string for %m */
! if (errno < sys_nerr && errno >= 0)
! errorstr = strerror(errno);
! else
{
! sprintf(errorstr_buf, "error %d", errno);
errorstr = errorstr_buf;
}
- #else
- errorstr = strerror(errno);
- #endif /* __BEOS__ */
if (lev == ERROR || lev == FATAL)
{
--- 123,151 ----
int len;
/* size of the prefix needed for timestamp and pid, if enabled */
size_t timestamp_size;
+ int errno_copy = errno;
if (lev <= DEBUG && Debugfile < 0)
return; /* ignore debug msgs if noplace to send */
! /*
! * save errno string for %m
! * Standard UNIX (XPG4v2/UNIX95 and later) says that errno will be set
! * (to EINVAL) if the argument to strerror() is out of range.
! * IRIX and Solaris actually return NULL without setting errno.
! * Others such as AIX, Cygwin and Linux return a string for all values.
! * This string contains a number for out of range values.
! * HPUX and QNX return the same string for all out of range values.
! * Those will not be well served by this code. However it is highly
! * unlikely that this code will be called with an out of range errno.
! */
! errno = 0;
! errorstr = strerror(errno_copy);
! if (errno != 0 || errorstr == NULL)
{
! sprintf(errorstr_buf, "error %d", errno_copy);
errorstr = errorstr_buf;
}
if (lev == ERROR || lev == FATAL)
{
*** src/backend/utils/error/exc.c.orig Tue Oct 3 08:00:18 2000
--- src/backend/utils/error/exc.c Wed Oct 25 16:37:39 2000
***************
*** 94,106 ****
ExceptionHandlingEnabled = on;
}
-
- extern int errno;
- #ifdef __CYGWIN__
- # define sys_nerr _sys_nerr
- #endif
- extern int sys_nerr;
-
static void
ExcPrint(Exception *excP,
ExcDetail detail,
--- 94,99 ----
***************
*** 107,112 ****
--- 100,108 ----
ExcData data,
ExcMessage message)
{
+ int errno_copy = errno;
+ const char *errorstr;
+
#ifdef lint
data = data;
#endif
***************
*** 131,144 ****
fprintf(stderr, " (%ld)", detail);
! #ifndef __BEOS__
! 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, "\n");
--- 127,140 ----
fprintf(stderr, " (%ld)", detail);
! if (errno_copy != 0) {
! errno = 0;
! errorstr = strerror(errno_copy);
! if (errno == 0 && errorstr != NULL)
! fprintf(stderr, " [Error %d: %s]", errno_copy, errorstr);
! else if (errno_copy != 0)
! fprintf(stderr, " [Error %d]", errno_copy);
! }
fprintf(stderr, "\n");
--
Pete Forman -./\.- Disclaimer: This post is originated
Western Geophysical -./\.- by myself and does not represent
pete.forman@westgeo.com -./\.- the opinion of Baker Hughes or
http://www.crosswinds.net/~petef -./\.- its divisions.