diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/port/thread.c | 3 | ||||
-rw-r--r-- | src/test/Makefile | 2 | ||||
-rw-r--r-- | src/test/README | 11 | ||||
-rw-r--r-- | src/test/thread/.gitignore | 1 | ||||
-rw-r--r-- | src/test/thread/Makefile | 24 | ||||
-rw-r--r-- | src/test/thread/README | 54 | ||||
-rw-r--r-- | src/test/thread/thread_test.c | 459 |
8 files changed, 8 insertions, 548 deletions
diff --git a/src/Makefile b/src/Makefile index bcdbd9588aa..79e274a4769 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,13 +66,11 @@ clean: $(MAKE) -C test $@ $(MAKE) -C tutorial NO_PGXS=1 $@ $(MAKE) -C test/isolation $@ - $(MAKE) -C test/thread $@ distclean maintainer-clean: $(MAKE) -C test $@ $(MAKE) -C tutorial NO_PGXS=1 $@ $(MAKE) -C test/isolation $@ - $(MAKE) -C test/thread $@ rm -f Makefile.port Makefile.global diff --git a/src/port/thread.c b/src/port/thread.c index 171df0f9e38..0941cb6a88f 100644 --- a/src/port/thread.c +++ b/src/port/thread.c @@ -47,9 +47,6 @@ * use non-*_r functions if they are thread-safe * * One thread-safe solution for gethostbyname() might be to use getaddrinfo(). - * - * Run src/test/thread to test if your operating system has thread-safe - * non-*_r functions. */ diff --git a/src/test/Makefile b/src/test/Makefile index efb206aa750..9774f534d93 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -37,7 +37,7 @@ endif # clean" etc to recurse into them. (We must filter out those that we # have conditionally included into SUBDIRS above, else there will be # make confusion.) -ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos ldap locale thread ssl) +ALWAYS_SUBDIRS = $(filter-out $(SUBDIRS),examples kerberos ldap locale ssl) # We want to recurse to all subdirs for all standard targets, except that # installcheck and install should not recurse into the subdirectory "modules". diff --git a/src/test/README b/src/test/README index b5ccfc0cf67..afdc7676519 100644 --- a/src/test/README +++ b/src/test/README @@ -9,7 +9,7 @@ Not all these tests get run by "make check". Check src/test/Makefile to see which tests get run automatically. authentication/ - Tests for authentication + Tests for authentication (but see also below) examples/ Demonstration programs for libpq that double as regression tests via @@ -18,6 +18,12 @@ examples/ isolation/ Tests for concurrent behavior at the SQL level +kerberos/ + Tests for Kerberos/GSSAPI authentication and encryption + +ldap/ + Tests for LDAP-based authentication + locale/ Sanity checks for locale data, encodings, etc @@ -42,6 +48,3 @@ ssl/ subscription/ Tests for logical replication - -thread/ - A thread-safety-testing utility used by configure diff --git a/src/test/thread/.gitignore b/src/test/thread/.gitignore deleted file mode 100644 index 1d54d546a8c..00000000000 --- a/src/test/thread/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/thread_test diff --git a/src/test/thread/Makefile b/src/test/thread/Makefile deleted file mode 100644 index a13c0c6cf53..00000000000 --- a/src/test/thread/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile for tools/thread -# -# Copyright (c) 2003-2020, PostgreSQL Global Development Group -# -# src/test/thread/Makefile -# -#------------------------------------------------------------------------- - -subdir = src/tools/thread -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global - -override CFLAGS += $(PTHREAD_CFLAGS) - -all: thread_test - -thread_test: thread_test.o -# no need for $LIBS, might not be compiled yet - $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(PTHREAD_LIBS) -o $@$(X) - -clean distclean maintainer-clean: - rm -f thread_test$(X) thread_test.o diff --git a/src/test/thread/README b/src/test/thread/README deleted file mode 100644 index 4da23440f6b..00000000000 --- a/src/test/thread/README +++ /dev/null @@ -1,54 +0,0 @@ -src/test/thread/README - -Threading -========= - -This program is run by configure to determine if threading is -properly supported on the platform. - -You can run the program manually to see details, which shows if your -native libc functions are thread-safe, or if we use *_r functions or -thread locking. - -To use this program manually, you must: - - o run "configure" - o compile the main source tree - o compile and run this program - -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 \ - -lws2_32 \ - -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/test/thread/thread_test.c b/src/test/thread/thread_test.c deleted file mode 100644 index 09603c95dd6..00000000000 --- a/src/test/thread/thread_test.c +++ /dev/null @@ -1,459 +0,0 @@ -/*------------------------------------------------------------------------- - * - * thread_test.c - * libc thread test program - * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/test/thread/thread_test.c - * - * This program tests to see if your standard libc functions use - * pthread_setspecific()/pthread_getspecific() to be thread-safe. - * See src/port/thread.c for more details. - * - * This program first tests to see if each function returns a constant - * memory pointer within the same thread, then, assuming it does, tests - * to see if the pointers are different for different threads. If they - * are, the function is thread-safe. - * - *------------------------------------------------------------------------- - */ - -#if !defined(IN_CONFIGURE) && !defined(WIN32) -#include "postgres.h" - -/* we want to know what the native strerror does, not pg_strerror */ -#undef strerror -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <netdb.h> -#include <sys/types.h> -#include <pwd.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> - -/* CYGWIN requires this for MAXHOSTNAMELEN */ -#ifdef __CYGWIN__ -#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[]) -{ - fprintf(stderr, "This PostgreSQL build does not support threads.\n"); - fprintf(stderr, "Perhaps rerun 'configure' using '--enable-thread-safety'.\n"); - return 1; -} -#else - -/* 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 volatile int thread2_done = 0; - -static volatile int errno1_set = 0; -static volatile int errno2_set = 0; - -#ifndef HAVE_STRERROR_R -static char *strerror_p1; -static char *strerror_p2; -static int strerror_threadsafe = 0; -#endif - -#if !defined(WIN32) && !defined(HAVE_GETPWUID_R) -static struct passwd *passwd_p1; -static struct passwd *passwd_p2; -static int getpwuid_threadsafe = 0; -#endif - -#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) -static struct hostent *hostent_p1; -static struct hostent *hostent_p2; -static char myhostname[MAXHOSTNAMELEN]; -static int gethostbyname_threadsafe = 0; -#endif - -static int platform_is_threadsafe = 1; - -int -main(int argc, char *argv[]) -{ - pthread_t thread1, - thread2; - int rc; - -#ifdef WIN32 - WSADATA wsaData; - int err; -#endif - - if (argc > 1) - { - fprintf(stderr, "Usage: %s\n", argv[0]); - return 1; - } - -#ifdef IN_CONFIGURE - /* Send stdout to 'config.log' */ - close(1); - dup(5); -#endif - -#ifdef WIN32 - err = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (err != 0) - { - fprintf(stderr, "Cannot start the network subsystem - %d**\nexiting\n", err); - exit(1); - } -#endif - -#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) - if (gethostname(myhostname, MAXHOSTNAMELEN) != 0) - { - fprintf(stderr, "Cannot get local hostname **\nexiting\n"); - exit(1); - } -#endif - - /* Hold lock until we are ready for the child threads to exit. */ - pthread_mutex_lock(&init_mutex); - - rc = pthread_create(&thread1, NULL, (void *(*) (void *)) func_call_1, NULL); - if (rc != 0) - { - fprintf(stderr, "Failed to create thread 1: %s **\nexiting\n", - strerror(errno)); - exit(1); - } - rc = pthread_create(&thread2, NULL, (void *(*) (void *)) func_call_2, NULL); - if (rc != 0) - { - /* - * 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); - } - - 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 - printf("Your errno is thread-safe.\n"); -#endif - -#ifndef HAVE_STRERROR_R - if (strerror_p1 != strerror_p2) - strerror_threadsafe = 1; -#endif - -#if !defined(WIN32) && !defined(HAVE_GETPWUID_R) - if (passwd_p1 != passwd_p2) - getpwuid_threadsafe = 1; -#endif - -#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) - if (hostent_p1 != hostent_p2) - gethostbyname_threadsafe = 1; -#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 strerror_r(); it does not need strerror().\n"); -#else - printf("Your system uses strerror() which is "); - if (strerror_threadsafe) - printf("thread-safe.\n"); - else - { - printf("not thread-safe. **\n"); - platform_is_threadsafe = 0; - } -#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 "); - if (getpwuid_threadsafe) - printf("thread-safe.\n"); - else - { - printf("not thread-safe. **\n"); - platform_is_threadsafe = 0; - } -#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 "); - if (gethostbyname_threadsafe) - printf("thread-safe.\n"); - else - { - printf("not thread-safe. **\n"); - platform_is_threadsafe = 0; - } -#endif - - if (platform_is_threadsafe) - { - printf("\nYour platform is thread-safe.\n"); - return 0; - } - else - { - printf("\n** YOUR PLATFORM IS NOT THREAD-SAFE. **\n"); - return 1; - } -} - -/* - * func_call_1 - */ -static void -func_call_1(void) -{ -#if !defined(HAVE_GETPWUID_R) || \ - (!defined(HAVE_GETADDRINFO) && \ - !defined(HAVE_GETHOSTBYNAME_R)) - void *p; -#endif -#ifdef WIN32 - HANDLE h1; -#else - int fd; -#endif - - unlink(TEMP_FILENAME_1); - - /* Set errno = EEXIST */ - - /* create, then try to fail on exclusive create open */ - - /* - * It would be great to check errno here but if errno is not thread-safe - * we might get a value from the other thread and mis-report the cause of - * the failure. - */ -#ifdef WIN32 - if ((h1 = CreateFile(TEMP_FILENAME_1, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL)) == - INVALID_HANDLE_VALUE) -#else - if ((fd = open(TEMP_FILENAME_1, O_RDWR | O_CREAT, 0600)) < 0) -#endif - { - fprintf(stderr, "Could not create file %s in current directory\n", - TEMP_FILENAME_1); - exit(1); - } - -#ifdef WIN32 - if (CreateFile(TEMP_FILENAME_1, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL) - != INVALID_HANDLE_VALUE) -#else - if (open(TEMP_FILENAME_1, O_RDWR | O_CREAT | O_EXCL, 0600) >= 0) -#endif - { - fprintf(stderr, - "Could not generate failure for exclusive file create of %s in current directory **\nexiting\n", - TEMP_FILENAME_1); - exit(1); - } - - /* - * Wait for other thread to set errno. We can't use thread-specific - * locking here because it might affect errno. - */ - errno1_set = 1; - while (errno2_set == 0) - sched_yield(); - -#ifdef WIN32 - if (GetLastError() != ERROR_FILE_EXISTS) -#else - if (errno != EEXIST) -#endif - { -#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); - } - -#ifdef WIN32 - CloseHandle(h1); -#else - close(fd); -#endif - 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) - { - printf("Your getpwuid() changes the static memory area between calls\n"); - passwd_p1 = NULL; /* force thread-safe failure report */ - } -#endif - -#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) - /* threads do this in opposite order */ - hostent_p1 = gethostbyname(myhostname); - p = gethostbyname("localhost"); - if (hostent_p1 != p) - { - printf("Your gethostbyname() changes the static memory area between calls\n"); - hostent_p1 = NULL; /* force thread-safe failure report */ - } -#endif - - thread1_done = 1; - pthread_mutex_lock(&init_mutex); /* wait for parent to test */ - pthread_mutex_unlock(&init_mutex); -} - - -/* - * func_call_2 - */ -static void -func_call_2(void) -{ -#if !defined(HAVE_GETPWUID_R) || \ - (!defined(HAVE_GETADDRINFO) && \ - !defined(HAVE_GETHOSTBYNAME_R)) - void *p; -#endif - - unlink(TEMP_FILENAME_2); - - /* Set errno = ENOENT */ - - /* This will fail, but we can't check errno yet */ - if (unlink(TEMP_FILENAME_2) != -1) - { - fprintf(stderr, - "Could not generate failure for unlink of %s in current directory **\nexiting\n", - TEMP_FILENAME_2); - exit(1); - } - - /* - * Wait for other thread to set errno. We can't use thread-specific - * locking here because it might affect errno. - */ - errno2_set = 1; - while (errno1_set == 0) - sched_yield(); - -#ifdef WIN32 - if (GetLastError() != ENOENT) -#else - if (errno != ENOENT) -#endif - { -#ifdef WIN32 - fprintf(stderr, "GetLastError() not thread-safe **\nexiting\n"); -#else - fprintf(stderr, "errno not thread-safe **\nexiting\n"); -#endif - exit(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_p2 = strerror(EINVAL); -#endif - -#if !defined(WIN32) && !defined(HAVE_GETPWUID_R) - passwd_p2 = getpwuid(2); - p = getpwuid(3); - if (passwd_p2 != p) - { - printf("Your getpwuid() changes the static memory area between calls\n"); - passwd_p2 = NULL; /* force thread-safe failure report */ - } -#endif - -#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R) - /* threads do this in opposite order */ - hostent_p2 = gethostbyname("localhost"); - p = gethostbyname(myhostname); - if (hostent_p2 != p) - { - printf("Your gethostbyname() changes the static memory area between calls\n"); - hostent_p2 = NULL; /* force thread-safe failure report */ - } -#endif - - thread2_done = 1; - pthread_mutex_lock(&init_mutex); /* wait for parent to test */ - pthread_mutex_unlock(&init_mutex); -} - -#endif /* !ENABLE_THREAD_SAFETY && !IN_CONFIGURE */ |