From 43bf3a6bc658d634e073dcb4ea3580dd9053a3b1 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 23 Aug 2005 21:02:05 +0000 Subject: [PATCH] The attached patch updates the thread test program to run stand-alone on Windows. The test itself is bypassed in configure as discussed, and libpq has been updated appropriately to allow it to build in thread-safe mode. Dave Page --- configure | 15 ++++ configure.in | 15 +++- src/interfaces/libpq/Makefile | 11 +-- src/interfaces/libpq/fe-connect.c | 6 +- src/interfaces/libpq/fe-exec.c | 23 ++--- src/interfaces/libpq/fe-misc.c | 8 +- src/interfaces/libpq/fe-print.c | 17 ++-- src/interfaces/libpq/fe-secure.c | 31 ++++--- src/interfaces/libpq/libpq-int.h | 8 +- src/interfaces/libpq/pthread-win32.c | 4 +- src/tools/thread/README | 33 ++++++++ src/tools/thread/thread_test.c | 122 ++++++++++++++++++++++++--- 12 files changed, 227 insertions(+), 66 deletions(-) diff --git a/configure b/configure index 95db270830..3d4284002a 100755 --- a/configure +++ b/configure @@ -20908,6 +20908,8 @@ fi +if test x"$template" != x"win32" +then echo "$as_me:$LINENO: checking for POSIX signal interface" >&5 echo $ECHO_N "checking for POSIX signal interface... $ECHO_C" >&6 if test "${pgac_cv_func_posix_signals+set}" = set; then @@ -20986,6 +20988,7 @@ echo "$as_me: error: " >&2;} { (exit 1); exit 1; }; } fi +fi if test $ac_cv_func_fseeko = yes; then # Check whether --enable-largefile or --disable-largefile was given. @@ -22432,6 +22435,8 @@ done # defined. Cross compiling throws a warning. # if test "$enable_thread_safety_force" = yes; then +if test x"$template" != x"win32" +then { echo "$as_me:$LINENO: WARNING: *** Skipping thread test program. --enable-thread-safety-force was used. *** Run the program in src/tools/thread on the your machine and add @@ -22444,7 +22449,13 @@ echo "$as_me: WARNING: proper locking function calls to your applications to guarantee thread safety. " >&2;} +else +{ echo "$as_me:$LINENO: WARNING: *** Skipping thread test on Win32" >&5 +echo "$as_me: WARNING: *** Skipping thread test on Win32" >&2;} +fi elif test "$enable_thread_safety" = yes; then +if test x"$template" != x"win32" +then echo "$as_me:$LINENO: checking thread safety of required library functions" >&5 echo $ECHO_N "checking thread safety of required library functions... $ECHO_C" >&6 @@ -22517,6 +22528,10 @@ rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftes fi CFLAGS="$_CFLAGS" LIBS="$_LIBS" +else +{ echo "$as_me:$LINENO: WARNING: *** Skipping thread test on Win32" >&5 +echo "$as_me: WARNING: *** Skipping thread test on Win32" >&2;} +fi fi # prepare build tree if outside source tree diff --git a/configure.in b/configure.in index c24b1cd4c1..8b8962f9b0 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $PostgreSQL: pgsql/configure.in,v 1.422 2005/08/23 20:48:44 momjian Exp $ +dnl $PostgreSQL: pgsql/configure.in,v 1.423 2005/08/23 21:01:59 momjian Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -1172,6 +1172,8 @@ AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [], AC_CHECK_TYPES(sig_atomic_t, [], [], [#include ]) +if test x"$template" != x"win32" +then PGAC_FUNC_POSIX_SIGNALS if test "$pgac_cv_func_posix_signals" != yes -a "$enable_thread_safety" = yes; then AC_MSG_ERROR([ @@ -1179,6 +1181,7 @@ if test "$pgac_cv_func_posix_signals" != yes -a "$enable_thread_safety" = yes; t *** operating system. ]) fi +fi if test $ac_cv_func_fseeko = yes; then AC_SYS_LARGEFILE @@ -1241,13 +1244,20 @@ AC_CHECK_PROGS(SGMLSPL, sgmlspl) # defined. Cross compiling throws a warning. # if test "$enable_thread_safety_force" = yes; then +if test x"$template" != x"win32" +then AC_MSG_WARN([ *** Skipping thread test program. --enable-thread-safety-force was used. *** Run the program in src/tools/thread on the your machine and add proper locking function calls to your applications to guarantee thread safety. ]) +else +AC_MSG_WARN([*** Skipping thread test on Win32]) +fi elif test "$enable_thread_safety" = yes; then +if test x"$template" != x"win32" +then AC_MSG_CHECKING([thread safety of required library functions]) _CFLAGS="$CFLAGS" @@ -1273,6 +1283,9 @@ AC_TRY_RUN([#include "$srcdir/src/tools/thread/thread_test.c"], ])]) CFLAGS="$_CFLAGS" LIBS="$_LIBS" +else +AC_MSG_WARN([*** Skipping thread test on Win32]) +fi fi # prepare build tree if outside source tree diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile index f496d595ec..9a61803cce 100644 --- a/src/interfaces/libpq/Makefile +++ b/src/interfaces/libpq/Makefile @@ -5,7 +5,7 @@ # Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.136 2005/08/23 20:48:46 momjian Exp $ +# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.137 2005/08/23 21:02:03 momjian Exp $ # #------------------------------------------------------------------------- @@ -43,9 +43,7 @@ libpqrc.o: libpq.rc windres -i libpq.rc -o libpqrc.o ifeq ($(enable_thread_safety), yes) -# This doesn't work yet because configure test fails. 2004-06-19 OBJS += pthread-win32.o -PTHREAD_H_WIN32 = pthread.h endif endif @@ -59,7 +57,7 @@ SHLIB_LINK += -lshfolder -lwsock32 -lws2_32 $(filter -leay32 -lssleay32 -lcomerr endif -all: $(PTHREAD_H_WIN32) def-files $(srcdir)/libpq.rc all-lib +all: def-files $(srcdir)/libpq.rc all-lib # Shared library stuff include $(top_srcdir)/src/Makefile.shlib @@ -122,11 +120,6 @@ $(srcdir)/blibpqdll.def: exports.txt $(srcdir)/libpq.rc: libpq.rc.in $(top_builddir)/src/Makefile.global sed -e 's/\(VERSION.*\),0 *$$/\1,'`date '+%y%j' | sed 's/^0*//'`'/' < $< > $@ -ifneq ($(PTHREAD_H_WIN32), "") -pthread.h: $(top_srcdir)/src/interfaces/libpq/pthread.h.win - rm -f $@ && $(LN_S) $< . -endif - fe-connect.o: fe-connect.c $(top_builddir)/src/port/pg_config_paths.h $(top_builddir)/src/port/pg_config_paths.h: diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index ff4f4285d0..bdeeb02a22 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.319 2005/08/23 20:48:46 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.320 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -55,8 +55,12 @@ #endif #ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#include "pthread-win32.h" +#else #include #endif +#endif #include "libpq/ip.h" #include "mb/pg_wchar.h" diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index eeb4819fb0..288cfe56cc 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.173 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.174 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -2156,25 +2156,16 @@ PQoidValue(const PGresult *res) char *endptr = NULL; unsigned long result; - if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0) + if (!res || + !res->cmdStatus || + strncmp(res->cmdStatus, "INSERT ", 7) != 0 || + res->cmdStatus[7] < '0' || + res->cmdStatus[7] > '9') return InvalidOid; -#ifdef WIN32 - SetLastError(0); -#else - errno = 0; -#endif result = strtoul(res->cmdStatus + 7, &endptr, 10); - if (!endptr || (*endptr != ' ' && *endptr != '\0') -#ifndef WIN32 - /* - * On WIN32, errno is not thread-safe and GetLastError() isn't set by - * strtoul(), so we can't check on this platform. - */ - || errno == ERANGE -#endif - ) + if (!endptr || (*endptr != ' ' && *endptr != '\0')) return InvalidOid; else return (Oid) result; diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index f4ae2ca2d9..b31c3a9613 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -23,7 +23,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.118 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.119 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1133,7 +1133,11 @@ libpq_gettext(const char *msgid) if (!already_bound) { /* dgettext() preserves errno, but bindtextdomain() doesn't */ - int save_errno = errno; +#ifdef WIN32 + int save_errno = GetLastError(); +#else + int save_errno = errno; +#endif const char *ldir; already_bound = true; diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c index 38bc1ceee6..a83004328c 100644 --- a/src/interfaces/libpq/fe-print.c +++ b/src/interfaces/libpq/fe-print.c @@ -10,7 +10,7 @@ * didn't really belong there. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-print.c,v 1.62 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-print.c,v 1.63 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -88,7 +88,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po) int total_line_length = 0; int usePipe = 0; char *pagerenv; -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) sigset_t osigset; bool sigpipe_masked = false; bool sigpipe_pending; @@ -189,14 +189,14 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po) if (fout) { usePipe = 1; +#ifndef WIN32 #ifdef ENABLE_THREAD_SAFETY if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0) sigpipe_masked = true; #else -#ifndef WIN32 oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN); -#endif -#endif +#endif /* ENABLE_THREAD_SAFETY */ +#endif /* WIN32 */ } else fout = stdout; @@ -311,16 +311,15 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po) _pclose(fout); #else pclose(fout); -#endif + #ifdef ENABLE_THREAD_SAFETY /* we can't easily verify if EPIPE occurred, so say it did */ if (sigpipe_masked) pq_reset_sigpipe(&osigset, sigpipe_pending, true); #else -#ifndef WIN32 pqsignal(SIGPIPE, oldsigpipehandler); -#endif -#endif +#endif /* ENABLE_THREAD_SAFETY */ +#endif /* WIN32 */ } if (po->html3 && !po->expanded) fputs("\n", fout); diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index 0852047d8d..c3cfe42ff3 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.69 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.70 2005/08/23 21:02:03 momjian Exp $ * * NOTES * [ Most of these notes are wrong/obsolete, but perhaps not all ] @@ -103,8 +103,12 @@ #include #ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#include "pthread-win32.h" +#else #include #endif +#endif #ifndef HAVE_STRDUP #include "strdup.h" @@ -388,20 +392,21 @@ ssize_t pqsecure_write(PGconn *conn, const void *ptr, size_t len) { ssize_t n; - + +#ifndef WIN32 #ifdef ENABLE_THREAD_SAFETY sigset_t osigmask; bool sigpipe_pending; bool got_epipe = false; + if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0) return -1; #else -#ifndef WIN32 pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN); -#endif -#endif - +#endif /* ENABLE_THREAD_SAFETY */ +#endif /* WIN32 */ + #ifdef USE_SSL if (conn->ssl) { @@ -431,7 +436,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len) if (n == -1) { -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) if (SOCK_ERRNO == EPIPE) got_epipe = true; #endif @@ -473,19 +478,19 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len) #endif { n = send(conn->sock, ptr, len, 0); -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) if (n < 0 && SOCK_ERRNO == EPIPE) got_epipe = true; #endif } - + +#ifndef WIN32 #ifdef ENABLE_THREAD_SAFETY pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe); #else -#ifndef WIN32 pqsignal(SIGPIPE, oldsighandler); -#endif -#endif +#endif /* ENABLE_THREAD_SAFETY */ +#endif /* WIN32 */ return n; } @@ -1232,7 +1237,7 @@ PQgetssl(PGconn *conn) #endif /* USE_SSL */ -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) /* * Block SIGPIPE for this thread. This prevents send()/write() from exiting diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index d8687a8a88..3eb66dea2d 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.106 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.107 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -30,7 +30,11 @@ #endif #ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#include "pthread-win32.h" +#else #include +#endif #include #endif @@ -481,7 +485,7 @@ extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); -#ifdef ENABLE_THREAD_SAFETY +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe); diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c index e5be8a9533..eb0862f1fa 100644 --- a/src/interfaces/libpq/pthread-win32.c +++ b/src/interfaces/libpq/pthread-win32.c @@ -5,14 +5,14 @@ * * Copyright (c) 2004-2005, PostgreSQL Global Development Group * IDENTIFICATION -* $PostgreSQL: pgsql/src/interfaces/libpq/pthread-win32.c,v 1.7 2005/08/23 20:48:47 momjian Exp $ +* $PostgreSQL: pgsql/src/interfaces/libpq/pthread-win32.c,v 1.8 2005/08/23 21:02:03 momjian Exp $ * *------------------------------------------------------------------------- */ #include -#include "pthread.h" +#include "pthread-win32.h" HANDLE pthread_self() diff --git a/src/tools/thread/README b/src/tools/thread/README index d5b9dab792..107699610e 100644 --- a/src/tools/thread/README +++ b/src/tools/thread/README @@ -14,3 +14,36 @@ If your platform requires special thread flags that are not tested by /config/acx_pthread.m4, add PTHREAD_CFLAGS and PTHREAD_LIBS defines to your template/${port} file. +Windows Systems +=============== + +Windows systems do not vary in their thread-safeness in the same way that +other systems might, nor do they generally have pthreads installed, hence +on Windows this test is skipped by the configure program (pthreads is +required by the test program, but not PostgreSQL itself). If you do wish +to test your system however, you can do so as follows: + +1) Install pthreads in you Mingw/Msys environment. You can download pthreads + from ftp://sources.redhat.com/pub/pthreads-win32/. + +2) Build the test program: + + gcc -o thread_test.exe \ + -D_REENTRANT \ + -D_THREAD_SAFE \ + -D_POSIX_PTHREAD_SEMANTICS \ + -I../../../src/include/port/win32 \ + thread_test.c \ + -lwsock32 \ + -lpthreadgc2 + +3) Run thread_test.exe. You should see output like: + + dpage@PC30:/cvs/pgsql/src/tools/thread$ ./thread_test + Your GetLastError() is thread-safe. + Your system uses strerror() which is thread-safe. + getpwuid_r()/getpwuid() are not applicable to Win32 platforms. + Your system uses gethostbyname which is thread-safe. + + Your platform is thread-safe. + diff --git a/src/tools/thread/thread_test.c b/src/tools/thread/thread_test.c index 5340376934..70babc09cd 100644 --- a/src/tools/thread/thread_test.c +++ b/src/tools/thread/thread_test.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.39 2005/08/23 20:48:47 momjian Exp $ + * $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.40 2005/08/23 21:02:05 momjian Exp $ * * This program tests to see if your standard libc functions use * pthread_setspecific()/pthread_getspecific() to be thread-safe. @@ -20,7 +20,7 @@ *------------------------------------------------------------------------- */ -#ifndef IN_CONFIGURE +#if !defined(IN_CONFIGURE) && !defined(WIN32) #include "postgres.h" #else /* From src/include/c.h" */ @@ -47,12 +47,43 @@ typedef char bool; #include #include + +/****************************************************************** + * Windows Hacks + *****************************************************************/ + +#ifdef WIN32 +#define MAXHOSTNAMELEN 63 +#include + +int mkstemp(char *template); + +int +mkstemp(char *template) +{ + FILE *foo; + + mktemp(template); + foo = fopen(template, "rw"); + if (!foo) + return -1; + else + return (int)foo; +} + +#endif + +/****************************************************************** + * End Windows Hacks + *****************************************************************/ + + /* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */ #include int sigwait(const sigset_t *set, int *sig); -#if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) +#if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) && !(defined(WIN32)) int main(int argc, char *argv[]) { @@ -69,8 +100,13 @@ main(int argc, char *argv[]) static void func_call_1(void); static void func_call_2(void); +#ifdef WIN32 +#define TEMP_FILENAME_1 "thread_test.1.XXXXXX" +#define TEMP_FILENAME_2 "thread_test.2.XXXXXX" +#else #define TEMP_FILENAME_1 "/tmp/thread_test.1.XXXXXX" #define TEMP_FILENAME_2 "/tmp/thread_test.2.XXXXXX" +#endif static char *temp_filename_1; static char *temp_filename_2; @@ -89,11 +125,13 @@ static char *strerror_p2; static bool strerror_threadsafe = false; #endif +#ifndef WIN32 #ifndef HAVE_GETPWUID_R static struct passwd *passwd_p1; static struct passwd *passwd_p2; static bool getpwuid_threadsafe = false; #endif +#endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) static struct hostent *hostent_p1; @@ -108,8 +146,12 @@ int main(int argc, char *argv[]) { pthread_t thread1, - thread2; - int fd; + thread2; + int fd; +#ifdef WIN32 + WSADATA wsaData; + int err; +#endif if (argc > 1) { @@ -123,6 +165,14 @@ main(int argc, char *argv[]) dup(5); #endif +#ifdef WIN32 + err = WSAStartup(MAKEWORD(1, 1), &wsaData); + if (err != 0) { + fprintf(stderr, "Cannot start the network subsystem - %d**\nexiting\n", err); + exit(1); + } +#endif + /* Make temp filenames, might not have strdup() */ temp_filename_1 = malloc(strlen(TEMP_FILENAME_1) + 1); strcpy(temp_filename_1, TEMP_FILENAME_1); @@ -151,18 +201,23 @@ main(int argc, char *argv[]) while (thread1_done == 0 || thread2_done == 0) sched_yield(); /* if this is a portability problem, * remove it */ - +#ifdef WIN32 + printf("Your GetLastError() is thread-safe.\n"); +#else printf("Your errno is thread-safe.\n"); +#endif #ifndef HAVE_STRERROR_R if (strerror_p1 != strerror_p2) strerror_threadsafe = true; #endif +#ifndef WIN32 #ifndef HAVE_GETPWUID_R if (passwd_p1 != passwd_p2) getpwuid_threadsafe = true; #endif +#endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) if (hostent_p1 != hostent_p2) @@ -187,6 +242,7 @@ main(int argc, char *argv[]) } #endif +#ifndef WIN32 #ifdef HAVE_GETPWUID_R printf("Your system has getpwuid_r(); it does not need getpwuid().\n"); #else @@ -199,6 +255,9 @@ main(int argc, char *argv[]) platform_is_threadsafe = false; } #endif +#else + printf("getpwuid_r()/getpwuid() are not applicable to Win32 platforms.\n"); +#endif #ifdef HAVE_GETADDRINFO printf("Your system has getaddrinfo(); it does not need gethostbyname()\n" @@ -238,14 +297,30 @@ func_call_1(void) !defined(HAVE_GETHOSTBYNAME_R)) void *p; #endif - +#ifdef WIN32 + HANDLE h1; + HANDLE h2; +#endif unlink(temp_filename_1); + + /* create, then try to fail on exclusive create open */ +#ifdef WIN32 + h1 = CreateFile(temp_filename_1, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); + h2 = CreateFile(temp_filename_1, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); + if (h1 == INVALID_HANDLE_VALUE || GetLastError() != ERROR_FILE_EXISTS) +#else if (open(temp_filename_1, O_RDWR | O_CREAT, 0600) < 0 || open(temp_filename_1, O_RDWR | O_CREAT | O_EXCL, 0600) >= 0) +#endif { +#ifdef WIN32 + fprintf(stderr, "Could not create file in current directory or\n"); + fprintf(stderr, "Could not generate failure for create file in current directory **\nexiting\n"); +#else fprintf(stderr, "Could not create file in /tmp or\n"); fprintf(stderr, "Could not generate failure for create file in /tmp **\nexiting\n"); +#endif exit(1); } @@ -256,9 +331,17 @@ func_call_1(void) errno1_set = 1; while (errno2_set == 0) sched_yield(); - if (errno != EEXIST) +#ifdef WIN32 + if (GetLastError() != ERROR_FILE_EXISTS) +#else + if (errno != EEXIST) +#endif { - fprintf(stderr, "errno not thread-safe **\nexiting\n"); +#ifdef WIN32 + fprintf(stderr, "GetLastError() not thread-safe **\nexiting\n"); +#else + fprintf(stderr, "errno not thread-safe **\nexiting\n"); +#endif unlink(temp_filename_1); exit(1); } @@ -274,6 +357,7 @@ func_call_1(void) */ #endif +#ifndef WIN32 #ifndef HAVE_GETPWUID_R passwd_p1 = getpwuid(0); p = getpwuid(1); @@ -283,6 +367,7 @@ func_call_1(void) passwd_p1 = NULL; /* force thread-safe failure report */ } #endif +#endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) /* threads do this in opposite order */ @@ -312,7 +397,12 @@ func_call_2(void) unlink(temp_filename_2); /* open non-existant file */ +#ifdef WIN32 + CreateFile(temp_filename_2, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (GetLastError() != ERROR_FILE_NOT_FOUND) +#else if (open(temp_filename_2, O_RDONLY, 0600) >= 0) +#endif { fprintf(stderr, "Read-only open succeeded without create **\nexiting\n"); exit(1); @@ -325,9 +415,17 @@ func_call_2(void) errno2_set = 1; while (errno1_set == 0) sched_yield(); - if (errno != ENOENT) +#ifdef WIN32 + if (GetLastError() != ENOENT) +#else + if (errno != ENOENT) +#endif { - fprintf(stderr, "errno not thread-safe **\nexiting\n"); +#ifdef WIN32 + fprintf(stderr, "GetLastError() not thread-safe **\nexiting\n"); +#else + fprintf(stderr, "errno not thread-safe **\nexiting\n"); +#endif unlink(temp_filename_2); exit(1); } @@ -343,6 +441,7 @@ func_call_2(void) */ #endif +#ifndef WIN32 #ifndef HAVE_GETPWUID_R passwd_p2 = getpwuid(2); p = getpwuid(3); @@ -352,6 +451,7 @@ func_call_2(void) passwd_p2 = NULL; /* force thread-safe failure report */ } #endif +#endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) /* threads do this in opposite order */