Tom Lane <tgl@sss.pgh.pa.us> writes:
> Mikhail Terekhov <terekhov@emc.com> writes:
> > One can't just #undef errno on windows because it is defined as
> > follows:
>
> I was wondering if Windows might play any games with errno. However,
> we've had at least one instance of "errno = 0;" in the libpq sources
> since 7.0 or before, and no one has complained that it doesn't build
> on Windows ... if errno is defined as a function call, that should
> yield a compile error, no?
ANSI C requires that errno be a modifiable l-value. I don't know of
any system which breaks that rule. In other words `errno = 0' is
always OK on any system, assuming you have done `#include <errno.h>'.
The statement may involve a function call, as in Mikhail's example:extern int * __cdecl _errno(void);#define errno
(*_errno())
I took a quick look at the current sources, and I have to admit that
the `#undef errno' looks very dubious to me. I see what the code is
trying to do: win32.h #defines errno to simplify matters, but the
simplification doesn't really work, so you have to #undef errno in a
couple of places. But this procedure can not work when errno is a
macro already, as it is when compiling multi-threaded code on Windows.
You wind up with the wrong value of errno after doing the #undef.
So I think the current code is broken. However, while I've done
Windows development in the past, I don't have a Windows system now,
and I haven't actually tested anything.
I think the clean way to handle this is something along the lines of
what the CVS client does. On Unix, do this: #define SOCK_ERRNO errno #define SOCK_STRERROR strerror
On Windows, do this: #define SOCK_ERRNO (WSAGetLastError ()) #define SOCK_STRERROR sock_strerror
(Then you have to write sock_strerror.)
Then change any reference to errno after a socket call to use
SOCK_ERRNO instead.
Note that the current Postgres code appears broken in another way, as
it passes WSAGetLastError() to strerror(), which doesn't work.
However, I again have not tested anything here.
Ian