diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f73245d..eba539fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,12 +21,16 @@ IF(NOT WIN32) OPTION(WITH_OPENSSL "enables SSL support" ON) ELSE() OPTION(WITH_OPENSSL "enables SSL support" OFF) + OPTION(WITH_RTC "enables run time checks for debug builds" OFF) ENDIF() OPTION(WITH_SQLITE "Enables Sqlite support" OFF) OPTION(WITH_EXTERNAL_ZLIB "Enables use of external zlib" OFF) ############### +IF(WITH_RTC) + SET(RTC_OPTIONS "/RTC1 /RTCc") +ENDIF() IF(MSVC) # Speedup system tests @@ -39,7 +43,7 @@ IF(MSVC) IF (NOT COMPILER_FLAGS STREQUAL "") STRING(REPLACE "/MD" "/MT" COMPILER_FLAGS ${COMPILER_FLAGS}) IF (CMAKE_BUILD_TYPE STREQUAL "Debug") - SET(COMPILER_FLAGS "${COMPILER_FLAGS} /RTC1 /RTCc") + SET(COMPILER_FLAGS "${COMPILER_FLAGS} ${RTC_OPTIONS}") STRING(REPLACE "/Zi" "/ZI" COMPILER_FLAGS ${COMPILER_FLAGS}) ENDIF() MESSAGE (STATUS "CMAKE_${COMPILER}_FLAGS_${BUILD_TYPE}= ${COMPILER_FLAGS}") diff --git a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt index 6f7c1b55..660714cb 100644 --- a/libmariadb/CMakeLists.txt +++ b/libmariadb/CMakeLists.txt @@ -127,7 +127,6 @@ ELSE() ../zlib/compress.c ../zlib/crc32.c ../zlib/deflate.c - ../zlib/example.c ../zlib/gzclose.c ../zlib/gzlib.c ../zlib/gzread.c diff --git a/libmariadb/net.c b/libmariadb/net.c index b393ff29..32e0ff83 100644 --- a/libmariadb/net.c +++ b/libmariadb/net.c @@ -31,8 +31,8 @@ #include #include #include -#ifdef MYSQL_SERVER -#include +#ifndef _WIN32 +#include #endif #define MAX_PACKET_LENGTH (256L*256L*256L-1) @@ -114,8 +114,6 @@ int my_net_init(NET *net, Vio* vio) { if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME | MY_ZEROFILL)))) return 1; -// if (net_buffer_length > max_allowed_packet) -// max_allowed_packet=net_buffer_length; max_allowed_packet= net->max_packet_size= MAX(net_buffer_length, max_allowed_packet); net->buff_end=net->buff+(net->max_packet=net_buffer_length); net->vio = vio; @@ -166,13 +164,10 @@ static my_bool net_realloc(NET *net, size_t length) DBUG_RETURN(1); } pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); - if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME)))) + if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length + 1, MYF(MY_WME)))) { DBUG_PRINT("info", ("Out of memory")); net->error=1; -#ifdef MYSQL_SERVER - net->last_errno=ER_OUT_OF_RESOURCES; -#endif DBUG_RETURN(1); } net->buff=net->write_pos=buff; @@ -180,21 +175,45 @@ static my_bool net_realloc(NET *net, size_t length) DBUG_RETURN(0); } -#ifdef DEBUG_SOCKET -static ssize_t net_check_if_data_available(Vio *vio) + +/* check if the socket is still alive */ +static my_bool net_check_socket_status(my_socket sock) { - ssize_t length= 0; - - if (vio->type != VIO_TYPE_SOCKET && - vio->type != VIO_TYPE_TCPIP) - return 0; - - if (vio_read_peek(vio, (size_t *)&length)) - return -1; - - return length; -} +#ifndef _WIN32 + struct pollfd poll_fd; +#else + FD_SET sfds; + struct timeval tv= {0,0}; #endif + int res; +#ifndef _WIN32 + memset(&poll_fd, 0, sizeof(struct pollfd)); + poll_fd.events= POLLPRI | POLLIN; + poll_fd.fd= sock; + + res= poll(&poll_fd, 1, 0); + if (res <= 0) /* timeout or error */ + return FALSE; + if (!(poll_fd.revents & (POLLIN | POLLPRI))) + return FALSE; + return TRUE; +#else + /* We can't use the WSAPoll function, it's broken :-( + (see Windows 8 Bugs 309411 - WSAPoll does not report failed connections) + Instead we need to use select function: + If TIMEVAL is initialized to {0, 0}, select will return immediately; + this is used to poll the state of the selected sockets. + */ + FD_ZERO(&sfds); + FD_SET(sock, &sfds); + + res= select(sock + 1, &sfds, NULL, NULL, &tv); + if (res > 0 && FD_ISSET(sock, &sfds)) + return TRUE; + return FALSE; +#endif + +} /* Remove unwanted characters from connection */ @@ -202,10 +221,19 @@ void net_clear(NET *net) { DBUG_ENTER("net_clear"); -#ifdef DEBUG_SOCKET - DBUG_ASSERT(net_check_if_data_available(net->vio) < 2); -#endif - + /* see conc-71: we need to check the socket status first: + if the socket is dead we set net->error, so net_flush + will report an error */ + while (net_check_socket_status(net->vio->sd)) + { + /* vio_read returns size_t. so casting to long is required to check for -1 */ + if ((long)vio_read(net->vio, (gptr)net->buff, (size_t) net->max_packet) <= 0) + { + net->error= 2; + DBUG_PRINT("info", ("socket disconnected")); + DBUG_VOID_RETURN; + } + } net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */ net->write_pos=net->buff; DBUG_VOID_RETURN; @@ -810,13 +838,14 @@ ulong my_net_read(NET *net) net->where_b=buffer_length; if ((packet_length = my_real_read(net,(size_t *)&complen)) == packet_error) - break; + return packet_error; if (my_uncompress((unsigned char*) net->buff + net->where_b, &packet_length, &complen)) { len= packet_error; net->error=2; /* caller will close socket */ net->last_errno=ER_NET_UNCOMPRESS_ERROR; break; + return packet_error; } buffer_length+= complen; } @@ -827,11 +856,8 @@ ulong my_net_read(NET *net) len= current - start - 4; if (is_multi_packet) len-= 4; - if (len != packet_error) - { - net->save_char= net->read_pos[len]; /* Must be saved */ - net->read_pos[len]=0; /* Safeguard for mysql_use_result */ - } + net->save_char= net->read_pos[len]; /* Must be saved */ + net->read_pos[len]=0; /* Safeguard for mysql_use_result */ } #endif return (ulong)len; diff --git a/unittest/libmariadb/basic-t.c b/unittest/libmariadb/basic-t.c index a27ab9d0..9c58d412 100644 --- a/unittest/libmariadb/basic-t.c +++ b/unittest/libmariadb/basic-t.c @@ -30,6 +30,38 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "my_test.h" #include "ma_common.h" +static int test_conc71(MYSQL *my) +{ + int rc; + MYSQL_RES *res; + MYSQL_ROW row; + char *query; + MYSQL *mysql; + + /* uncomment if you want to test manually */ + return SKIP; + + mysql= mysql_init(NULL); + + + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8"); + mysql_options(mysql, MYSQL_OPT_COMPRESS, 0); + mysql_options(mysql, MYSQL_INIT_COMMAND, "/*!40101 SET SQL_MODE='' */"); + mysql_options(mysql, MYSQL_INIT_COMMAND, "/*!40101 set @@session.wait_timeout=28800 */"); + + FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema, + port, socketname, 0), mysql_error(my)); + + diag("kill server"); + sleep(20); + + rc= mysql_query(mysql, "SELECT 'foo' FROM DUAL"); + check_mysql_rc(rc, mysql); + + mysql_close(mysql); + return OK; +} + static int test_conc70(MYSQL *my) { int rc; @@ -37,7 +69,7 @@ static int test_conc70(MYSQL *my) MYSQL_ROW row; MYSQL *mysql= mysql_init(NULL); - mysql_query(my, "SET @a:=@@max_allowed_packet"); + rc= mysql_query(my, "SET @a:=@@max_allowed_packet"); check_mysql_rc(rc, my); mysql_query(my, "SET global max_allowed_packet=1024*1024*22"); @@ -84,7 +116,7 @@ static int test_conc68(MYSQL *my) MYSQL_ROW row; MYSQL *mysql= mysql_init(NULL); - mysql_query(my, "SET @a:=@@max_allowed_packet"); + rc= mysql_query(my, "SET @a:=@@max_allowed_packet"); check_mysql_rc(rc, my); mysql_query(my, "SET global max_allowed_packet=1024*1024*22"); @@ -648,6 +680,7 @@ static int test_compressed(MYSQL *my) } struct my_tests_st my_tests[] = { + {"test_conc71", test_conc71, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc70", test_conc70, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc68", test_conc68, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_compressed", test_compressed, TEST_CONNECTION_NONE, 0, NULL, NULL}, diff --git a/unittest/libmariadb/logs.c b/unittest/libmariadb/logs.c index 982c0c40..30eb6859 100644 --- a/unittest/libmariadb/logs.c +++ b/unittest/libmariadb/logs.c @@ -65,6 +65,9 @@ static int test_logs(MYSQL *mysql) int rc; short id; + rc= mysql_query(mysql, "SET session sql_mode=''"); + check_mysql_rc(rc, mysql); + rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs"); check_mysql_rc(rc, mysql); diff --git a/unittest/libmariadb/my.cnf b/unittest/libmariadb/my.cnf new file mode 100644 index 00000000..0fec8728 --- /dev/null +++ b/unittest/libmariadb/my.cnf @@ -0,0 +1,3 @@ +[conc-66] +user=conc66 +password='test;#test' diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt index 5efab879..a7a58c95 100644 --- a/zlib/CMakeLists.txt +++ b/zlib/CMakeLists.txt @@ -1,13 +1,13 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib) -SET(SOURCE_FILES adler32.c compress.c crc32.c deflate.c example.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c minigzip.c trees.c uncompr.c zutil.c) +SET(SOURCE_FILES adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c minigzip.c trees.c uncompr.c zutil.c) ADD_LIBRARY(zlib ${SOURCE_FILES}) SET_TARGET_PROPERTIES(zlib PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") - INSTALL(TARGETS - zlib - RUNTIME DESTINATION "lib" - LIBRARY DESTINATION "lib" - ARCHIVE DESTINATION "lib") \ No newline at end of file +INSTALL(TARGETS + zlib + RUNTIME DESTINATION "lib" + LIBRARY DESTINATION "lib" + ARCHIVE DESTINATION "lib")