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

Reply via email to