Tom Lane wrote: > Alex Soto <aps...@gmail.com> writes: > > Here's the section in the config.log in case it makes a difference > > > configure:28808: ./conftest > > Could not create file in /tmp or > > Could not generate failure for create file in /tmp ** > > exiting > > configure:28812: $? = 1 > > configure: program exited with status 1 > > [ greps... ] Oh, that error is coming from src/test/thread/thread_test.c. > > I wonder why we have that trying to write to /tmp at all, when all the > other transient junk generated by configure is in the current directory. > Bruce, do you have a good reason for doing it that way?
I have modified the code to use the current directory instead of /tmp. I also cleaned up the #if defines and added some C comments. > (The error message seems to be suffering from a bad case of copy-and- > paste-itis, too.) Actually, it is accurate. The code is: #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 { 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"); exit(1); } This code generates an errno == EEXIST in one thread, while another thread generates errno == ENOENT, and this is how we test for errno being thread-safe. If you have a cleaner way to do this, please let me know. mkdir()? -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
diff --git a/src/test/thread/thread_test.c b/src/test/thread/thread_test.c new file mode 100644 index 6a81829..2271ba6 *** a/src/test/thread/thread_test.c --- b/src/test/thread/thread_test.c *************** typedef char bool; *** 52,92 **** #include <sys/param.h> #endif - /****************************************************************** - * Windows Hacks - *****************************************************************/ - #ifdef WIN32 #define MAXHOSTNAMELEN 63 #include <winsock2.h> - - 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 <signal.h> int sigwait(const sigset_t *set, int *sig); ! #if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) && !(defined(WIN32)) int main(int argc, char *argv[]) { --- 52,69 ---- #include <sys/param.h> #endif #ifdef WIN32 #define MAXHOSTNAMELEN 63 #include <winsock2.h> #endif /* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */ #include <signal.h> int sigwait(const sigset_t *set, int *sig); ! #if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) && !defined(WIN32) int main(int argc, char *argv[]) { *************** main(int argc, char *argv[]) *** 99,118 **** /* This must be down here because this is the code that uses threads. */ #include <pthread.h> 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; - static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; static volatile int thread1_done = 0; --- 76,87 ---- /* This must be down here because this is the code that uses threads. */ #include <pthread.h> + #define TEMP_FILENAME_1 "thread_test.1" + #define TEMP_FILENAME_2 "thread_test.2" + static void func_call_1(void); static void func_call_2(void); static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; static volatile int thread1_done = 0; *************** static char *strerror_p2; *** 127,139 **** 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; --- 96,106 ---- static bool strerror_threadsafe = false; #endif ! #if !defined(WIN32) && !defined(HAVE_GETPWUID_R) static struct passwd *passwd_p1; static struct passwd *passwd_p2; static bool getpwuid_threadsafe = false; #endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) static struct hostent *hostent_p1; *************** static bool platform_is_threadsafe = tru *** 147,157 **** int main(int argc, char *argv[]) { ! pthread_t thread1, ! thread2; ! int fd; int rc; - #ifdef WIN32 WSADATA wsaData; int err; --- 114,121 ---- int main(int argc, char *argv[]) { ! pthread_t thread1, thread2; int rc; #ifdef WIN32 WSADATA wsaData; int err; *************** main(int argc, char *argv[]) *** 178,194 **** } #endif - /* Make temp filenames, might not have strdup() */ - temp_filename_1 = malloc(strlen(TEMP_FILENAME_1) + 1); - strcpy(temp_filename_1, TEMP_FILENAME_1); - fd = mkstemp(temp_filename_1); - close(fd); - - temp_filename_2 = malloc(strlen(TEMP_FILENAME_2) + 1); - strcpy(temp_filename_2, TEMP_FILENAME_2); - fd = mkstemp(temp_filename_2); - close(fd); - #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) if (gethostname(myhostname, MAXHOSTNAMELEN) != 0) { --- 142,147 ---- *************** main(int argc, char *argv[]) *** 212,218 **** { /* * strerror() might not be thread-safe, and we already spawned thread ! * 1 that uses it */ fprintf(stderr, "Failed to create thread 2 **\nexiting\n"); exit(1); --- 165,171 ---- { /* * strerror() might not be thread-safe, and we already spawned thread ! * 1 that uses it, so avoid using it. */ fprintf(stderr, "Failed to create thread 2 **\nexiting\n"); exit(1); *************** main(int argc, char *argv[]) *** 220,225 **** --- 173,182 ---- while (thread1_done == 0 || thread2_done == 0) sched_yield(); /* if this is a portability problem, remove it */ + + /* Test things while we have thread-local storage */ + + /* If we got here, we didn't exit() from a thread */ #ifdef WIN32 printf("Your GetLastError() is thread-safe.\n"); #else *************** main(int argc, char *argv[]) *** 231,253 **** 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) gethostbyname_threadsafe = true; #endif pthread_mutex_unlock(&init_mutex); /* let children exit */ pthread_join(thread1, NULL); /* clean up children */ pthread_join(thread2, NULL); #ifdef HAVE_STRERROR_R printf("Your system has sterror_r(); it does not need strerror().\n"); #else --- 188,212 ---- strerror_threadsafe = true; #endif ! #if !defined(WIN32) && !defined(HAVE_GETPWUID_R) if (passwd_p1 != passwd_p2) getpwuid_threadsafe = true; #endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) if (hostent_p1 != hostent_p2) gethostbyname_threadsafe = true; #endif + /* close down threads */ + pthread_mutex_unlock(&init_mutex); /* let children exit */ pthread_join(thread1, NULL); /* clean up children */ pthread_join(thread2, NULL); + /* report results */ + #ifdef HAVE_STRERROR_R printf("Your system has sterror_r(); it does not need strerror().\n"); #else *************** main(int argc, char *argv[]) *** 261,268 **** } #endif ! #ifndef WIN32 ! #ifdef HAVE_GETPWUID_R printf("Your system has getpwuid_r(); it does not need getpwuid().\n"); #else printf("Your system uses getpwuid() which is "); --- 220,228 ---- } #endif ! #ifdef WIN32 ! printf("getpwuid_r()/getpwuid() are not applicable to Win32 platforms.\n"); ! #elif defined(HAVE_GETPWUID_R) printf("Your system has getpwuid_r(); it does not need getpwuid().\n"); #else printf("Your system uses getpwuid() which is "); *************** main(int argc, char *argv[]) *** 274,288 **** 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" " or gethostbyname_r().\n"); ! #else ! #ifdef HAVE_GETHOSTBYNAME_R printf("Your system has gethostbyname_r(); it does not need gethostbyname().\n"); #else printf("Your system uses gethostbyname which is "); --- 234,244 ---- platform_is_threadsafe = false; } #endif #ifdef HAVE_GETADDRINFO printf("Your system has getaddrinfo(); it does not need gethostbyname()\n" " or gethostbyname_r().\n"); ! #elif defined(HAVE_GETHOSTBYNAME_R) printf("Your system has gethostbyname_r(); it does not need gethostbyname().\n"); #else printf("Your system uses gethostbyname which is "); *************** main(int argc, char *argv[]) *** 294,300 **** platform_is_threadsafe = false; } #endif - #endif if (platform_is_threadsafe) { --- 250,255 ---- *************** func_call_1(void) *** 317,345 **** 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); } --- 272,294 ---- void *p; #endif #ifdef WIN32 ! HANDLE h1, 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 { 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"); exit(1); } *************** func_call_1(void) *** 350,355 **** --- 299,305 ---- errno1_set = 1; while (errno2_set == 0) sched_yield(); + #ifdef WIN32 if (GetLastError() != ERROR_FILE_EXISTS) #else *************** func_call_1(void) *** 361,382 **** #else fprintf(stderr, "errno not thread-safe **\nexiting\n"); #endif ! unlink(temp_filename_1); exit(1); } - unlink(temp_filename_1); ! #ifndef HAVE_STRERROR_R ! strerror_p1 = strerror(EACCES); /* * If strerror() uses sys_errlist, the pointer might change for different * errno values, so we don't check to see if it varies within the thread. */ #endif ! #ifndef WIN32 ! #ifndef HAVE_GETPWUID_R passwd_p1 = getpwuid(0); p = getpwuid(1); if (passwd_p1 != p) --- 311,331 ---- #else fprintf(stderr, "errno not thread-safe **\nexiting\n"); #endif ! unlink(TEMP_FILENAME_1); exit(1); } ! unlink(TEMP_FILENAME_1); + #ifndef HAVE_STRERROR_R /* * If strerror() uses sys_errlist, the pointer might change for different * errno values, so we don't check to see if it varies within the thread. */ + strerror_p1 = strerror(EACCES); #endif ! #if !defined(WIN32) && !defined(HAVE_GETPWUID_R) passwd_p1 = getpwuid(0); p = getpwuid(1); if (passwd_p1 != p) *************** func_call_1(void) *** 385,391 **** passwd_p1 = NULL; /* force thread-safe failure report */ } #endif - #endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) /* threads do this in opposite order */ --- 334,339 ---- *************** func_call_2(void) *** 413,425 **** void *p; #endif ! 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"); --- 361,374 ---- void *p; #endif ! 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"); *************** func_call_2(void) *** 433,438 **** --- 382,388 ---- errno2_set = 1; while (errno1_set == 0) sched_yield(); + #ifdef WIN32 if (GetLastError() != ENOENT) #else *************** func_call_2(void) *** 444,465 **** #else fprintf(stderr, "errno not thread-safe **\nexiting\n"); #endif ! unlink(temp_filename_2); exit(1); } - unlink(temp_filename_2); ! #ifndef HAVE_STRERROR_R ! strerror_p2 = strerror(EINVAL); /* * If strerror() uses sys_errlist, the pointer might change for different * errno values, so we don't check to see if it varies within the thread. */ #endif ! #ifndef WIN32 ! #ifndef HAVE_GETPWUID_R passwd_p2 = getpwuid(2); p = getpwuid(3); if (passwd_p2 != p) --- 394,414 ---- #else fprintf(stderr, "errno not thread-safe **\nexiting\n"); #endif ! unlink(TEMP_FILENAME_2); exit(1); } ! unlink(TEMP_FILENAME_2); + #ifndef HAVE_STRERROR_R /* * If strerror() uses sys_errlist, the pointer might change for different * errno values, so we don't check to see if it varies within the thread. */ + strerror_p2 = strerror(EINVAL); #endif ! #if !defined(WIN32) && !defined(HAVE_GETPWUID_R) passwd_p2 = getpwuid(2); p = getpwuid(3); if (passwd_p2 != p) *************** func_call_2(void) *** 468,474 **** passwd_p2 = NULL; /* force thread-safe failure report */ } #endif - #endif #if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) /* threads do this in opposite order */ --- 417,422 ----
-- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs