diff --git a/src/odbc/unittests/CMakeLists.txt b/src/odbc/unittests/CMakeLists.txt index c36a39cc3..74101b1b1 100644 --- a/src/odbc/unittests/CMakeLists.txt +++ b/src/odbc/unittests/CMakeLists.txt @@ -39,7 +39,8 @@ else() set(libs tdsodbc ${lib_ODBCINST}) endif() -add_library(o_common STATIC common.c common.h c2string.c parser.c parser.h) +add_library(o_common STATIC common.c common.h c2string.c parser.c parser.h + fake_thread.c fake_thread.h) set(static_tests all_types utf8_4 connection_string_parse) set(unicode_tests utf8 oldpwd) diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am index b516cfe92..761b925c1 100644 --- a/src/odbc/unittests/Makefile.am +++ b/src/odbc/unittests/Makefile.am @@ -182,7 +182,8 @@ connection_string_parse_CPPFLAGS = $(GLOBAL_CPPFLAGS) connection_string_parse_LDFLAGS = -static ../libtdsodbc.la ../../tds/unittests/libcommon.a -shared $(GLOBAL_LD_ADD) noinst_LIBRARIES = libcommon.a -libcommon_a_SOURCES = common.c common.h c2string.c parser.c parser.h +libcommon_a_SOURCES = common.c common.h c2string.c parser.c parser.h \ + fake_thread.c fake_thread.h GLOBAL_CPPFLAGS = -I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_TOPDIR=\"$(top_srcdir)\" GLOBAL_LD_ADD = $(NETWORK_LIBS) $(ODBCINST_LDFLAGS) diff --git a/src/odbc/unittests/fake_thread.c b/src/odbc/unittests/fake_thread.c new file mode 100644 index 000000000..a9ccdfc4d --- /dev/null +++ b/src/odbc/unittests/fake_thread.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "common.h" + +#if HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ + +#include + +#if HAVE_SYS_SOCKET_H +#include +#endif /* HAVE_SYS_SOCKET_H */ + +#if HAVE_NETINET_IN_H +#include +#endif /* HAVE_NETINET_IN_H */ + +#include "fake_thread.h" + +tds_thread fake_thread; + +/* build a listening socket to connect to */ +bool +init_fake_server(int ip_port) +{ + struct sockaddr_in sin; + TDS_SYS_SOCKET s; + + memset(&sin, 0, sizeof(sin)); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sin.sin_port = htons((short) ip_port); + sin.sin_family = AF_INET; + + if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) { + perror("socket"); + exit(1); + } + if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + perror("bind"); + CLOSESOCKET(s); + return false; + } + if (listen(s, 5) < 0) { + perror("listen"); + CLOSESOCKET(s); + return false; + } + if (tds_thread_create(&fake_thread, fake_thread_proc, TDS_INT2PTR(s)) != 0) { + perror("tds_thread_create"); + exit(1); + } + return true; +} diff --git a/src/odbc/unittests/fake_thread.h b/src/odbc/unittests/fake_thread.h new file mode 100644 index 000000000..1daa71d0d --- /dev/null +++ b/src/odbc/unittests/fake_thread.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include + +#include + +extern tds_thread fake_thread; + +/* function to be provided to use init_fake_server() */ +TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg); + +/** + * Initialize fake server and thread with specified TCP port. + * The server will listen on local address. + */ +bool init_fake_server(int ip_port); + +#include diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c index f66c02cea..ea9a1b211 100644 --- a/src/odbc/unittests/freeclose.c +++ b/src/odbc/unittests/freeclose.c @@ -37,6 +37,8 @@ #include #include +#include "fake_thread.h" + /* this crazy test tests that we do not send too much prepare ... */ static tds_mutex mtx; @@ -50,43 +52,9 @@ typedef union { static long_sockaddr remote_addr; static socklen_t remote_addr_len; -static tds_thread fake_thread; #ifdef _WIN32 #define alarm(n) do { ; } while(0) #endif -static TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg); - -static int -init_fake_server(int ip_port) -{ - struct sockaddr_in sin; - TDS_SYS_SOCKET s; - - memset(&sin, 0, sizeof(sin)); - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - sin.sin_port = htons((short) ip_port); - sin.sin_family = AF_INET; - - if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) { - perror("socket"); - exit(1); - } - if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { - perror("bind"); - CLOSESOCKET(s); - return 1; - } - if (listen(s, 5) < 0) { - perror("listen"); - CLOSESOCKET(s); - return 1; - } - if (tds_thread_create(&fake_thread, fake_thread_proc, TDS_INT2PTR(s)) != 0) { - perror("tds_thread_create"); - exit(1); - } - return 0; -} static void write_all(TDS_SYS_SOCKET s, const void *buf, size_t len) @@ -157,7 +125,7 @@ count_insert(const char* buf, size_t len) static unsigned int round_trips = 0; static enum { sending, receiving } flow = sending; -static TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg) +TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg) { TDS_SYS_SOCKET s = TDS_PTR2INT(arg), server_sock; socklen_t sock_len; @@ -314,7 +282,7 @@ main(void) /* init fake server, behave like a proxy */ for (port = 12340; port < 12350; ++port) - if (!init_fake_server(port)) + if (init_fake_server(port)) break; if (port == 12350) { fprintf(stderr, "Cannot bind to a port\n"); diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c index 3d225346e..62d0834c7 100644 --- a/src/odbc/unittests/timeout3.c +++ b/src/odbc/unittests/timeout3.c @@ -26,6 +26,8 @@ #include #include +#include "fake_thread.h" + #if TDS_HAVE_MUTEX static void init_connect(void); @@ -38,47 +40,11 @@ init_connect(void) CHKAllocConnect(&odbc_conn, "S"); } -static tds_thread fake_thread; static tds_mutex mtx; static TDS_SYS_SOCKET fake_sock; -static TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg); - -/* build a listening socket to connect to */ -static int -init_fake_server(int ip_port) -{ - struct sockaddr_in sin; - TDS_SYS_SOCKET s; - - memset(&sin, 0, sizeof(sin)); - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons((short) ip_port); - sin.sin_family = AF_INET; - - if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_STREAM, 0))) { - perror("socket"); - exit(1); - } - if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { - perror("bind"); - CLOSESOCKET(s); - return 1; - } - if (listen(s, 5) < 0) { - perror("listen"); - CLOSESOCKET(s); - return 1; - } - if (tds_thread_create(&fake_thread, fake_thread_proc, TDS_INT2PTR(s)) != 0) { - perror("tds_thread_create"); - exit(1); - } - return 0; -} - /* accept a socket and read data as much as you can */ -static TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg) +TDS_THREAD_PROC_DECLARE(fake_thread_proc, arg) { TDS_SYS_SOCKET s = TDS_PTR2INT(arg), sock; socklen_t len; @@ -169,7 +135,7 @@ main(void) unsetenv("TDSPORT"); for (port = 12340; port < 12350; ++port) - if (!init_fake_server(port)) + if (init_fake_server(port)) break; if (port == 12350) { fprintf(stderr, "Cannot bind to a port\n");