You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
Fix for asynchronous (reconnect)
Fixed memory leak after reconnect/change user
This commit is contained in:
@@ -165,40 +165,45 @@ INCLUDE(${CMAKE_SOURCE_DIR}/cmake/CheckFunctions.cmake)
|
|||||||
# check for various types
|
# check for various types
|
||||||
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/CheckTypes.cmake)
|
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/CheckTypes.cmake)
|
||||||
|
|
||||||
IF(WITH_SSL STREQUAL "OPENSSL")
|
IF(NOT WITH_SSL)
|
||||||
FIND_PACKAGE(OpenSSL)
|
IF(WIN32)
|
||||||
IF(OPENSSL_FOUND)
|
SET(WITH_SSL "SCHANNEL")
|
||||||
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_SSL)
|
|
||||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/openssl.c")
|
|
||||||
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(FATAL "OpenSSL not found")
|
SET(WITH_SSL "OPENSSL")
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
IF(WITH_SSL STREQUAL "GNUTLS")
|
|
||||||
FIND_PACKAGE(GnuTLS)
|
|
||||||
IF(GNUTLS_FOUND)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_SSL)
|
|
||||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/gnutls.c")
|
|
||||||
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL "GnuTLS not found")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
IF(WIN32)
|
|
||||||
IF(WITH_SSL STREQUAL "SCHANNEL")
|
|
||||||
MESSAGE(STATUS "SSL_TYPE ${SSL_TYPE}")
|
|
||||||
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_SSL)
|
|
||||||
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/schannel.c" "${CMAKE_SOURCE_DIR}/libmariadb/secure/ma_schannel.c")
|
|
||||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/plugins/pvio/")
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
MARK_AS_ADVANCED(SSL_SOURCES)
|
IF(NOT WITH_SSL STREQUAL "OFF")
|
||||||
|
IF(WITH_SSL STREQUAL "OPENSSL")
|
||||||
|
FIND_PACKAGE(OpenSSL)
|
||||||
|
IF(OPENSSL_FOUND)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_SSL)
|
||||||
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/openssl.c")
|
||||||
|
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL "OpenSSL not found")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
IF(WITH_SSL STREQUAL "GNUTLS")
|
||||||
|
FIND_PACKAGE(GnuTLS)
|
||||||
|
IF(GNUTLS_FOUND)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_SSL)
|
||||||
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/gnutls.c")
|
||||||
|
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL "GnuTLS not found")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
IF(WIN32)
|
||||||
|
IF(WITH_SSL STREQUAL "SCHANNEL")
|
||||||
|
MESSAGE(STATUS "SSL_TYPE ${SSL_TYPE}")
|
||||||
|
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_SSL)
|
||||||
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/libmariadb/secure/schannel.c" "${CMAKE_SOURCE_DIR}/libmariadb/secure/ma_schannel.c")
|
||||||
|
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/plugins/pvio/")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(SSL_SOURCES)
|
||||||
IF(WITH_SQLITE)
|
|
||||||
ADD_DEFINITIONS(-DHAVE_SQLITE)
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(NOT WIN32)
|
IF(NOT WIN32)
|
||||||
|
@@ -76,6 +76,7 @@ extern const char *mariadb_client_errors[]; /* Error messages */
|
|||||||
#define CR_NO_STMT_METADATA 2052
|
#define CR_NO_STMT_METADATA 2052
|
||||||
#define CR_NOT_IMPLEMENTED 2054
|
#define CR_NOT_IMPLEMENTED 2054
|
||||||
#define CR_SERVER_LOST_EXTENDED 2055
|
#define CR_SERVER_LOST_EXTENDED 2055
|
||||||
|
#define CR_STMT_CLOSED 2056
|
||||||
#define CR_NEW_STMT_METADATA 2057
|
#define CR_NEW_STMT_METADATA 2057
|
||||||
#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058
|
#define CR_AUTH_PLUGIN_CANNOT_LOAD 2058
|
||||||
#define CR_ALREADY_CONNECTED 2059
|
#define CR_ALREADY_CONNECTED 2059
|
||||||
|
@@ -16,9 +16,17 @@
|
|||||||
struct st_ma_pvio_methods;
|
struct st_ma_pvio_methods;
|
||||||
typedef struct st_ma_pvio_methods PVIO_METHODS;
|
typedef struct st_ma_pvio_methods PVIO_METHODS;
|
||||||
|
|
||||||
#define IS_ASYNC_ACTIVE(a) \
|
#define IS_PVIO_ASYNC(a) \
|
||||||
((a)->mysql->options.extension && (a)->mysql->options.extension->async_context && \
|
((a)->mysql && (a)->mysql->options.extension && (a)->mysql->options.extension->async_context)
|
||||||
(a)->mysql->options.extension->async_context->active)
|
|
||||||
|
#define IS_PVIO_ASYNC_ACTIVE(a) \
|
||||||
|
(IS_PVIO_ASYNC(a)&& (a)->mysql->options.extension->async_context->active)
|
||||||
|
|
||||||
|
#define IS_MYSQL_ASYNC(a) \
|
||||||
|
((a)->options.extension && (a)->options.extension->async_context)
|
||||||
|
|
||||||
|
#define IS_MYSQL_ASYNC_ACTIVE(a) \
|
||||||
|
(IS_MYSQL_ASYNC(a)&& (a)->options.extension->async_context->active)
|
||||||
|
|
||||||
#ifndef ssl_defined
|
#ifndef ssl_defined
|
||||||
#define ssl_defined
|
#define ssl_defined
|
||||||
@@ -101,6 +109,7 @@ struct st_ma_pvio_methods
|
|||||||
my_bool (*get_handle)(MARIADB_PVIO *pvio, void *handle);
|
my_bool (*get_handle)(MARIADB_PVIO *pvio, void *handle);
|
||||||
my_bool (*is_blocking)(MARIADB_PVIO *pvio);
|
my_bool (*is_blocking)(MARIADB_PVIO *pvio);
|
||||||
my_bool (*is_alive)(MARIADB_PVIO *pvio);
|
my_bool (*is_alive)(MARIADB_PVIO *pvio);
|
||||||
|
my_bool (*has_data)(MARIADB_PVIO *pvio, ssize_t *data_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
@@ -121,5 +130,6 @@ int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout)
|
|||||||
my_bool ma_pvio_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
|
my_bool ma_pvio_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
|
||||||
my_bool ma_pvio_is_alive(MARIADB_PVIO *pvio);
|
my_bool ma_pvio_is_alive(MARIADB_PVIO *pvio);
|
||||||
my_bool ma_pvio_get_handle(MARIADB_PVIO *pvio, void *handle);
|
my_bool ma_pvio_get_handle(MARIADB_PVIO *pvio, void *handle);
|
||||||
|
my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *length);
|
||||||
|
|
||||||
#endif /* _ma_pvio_h_ */
|
#endif /* _ma_pvio_h_ */
|
||||||
|
@@ -136,7 +136,7 @@ const char *client_errors[]=
|
|||||||
/* 2053 */ "",
|
/* 2053 */ "",
|
||||||
/* 2054 */ "This feature is not implemented or disabled",
|
/* 2054 */ "This feature is not implemented or disabled",
|
||||||
/* 2055 */ "Lost connection to MySQL server at '%s', system error: %d",
|
/* 2055 */ "Lost connection to MySQL server at '%s', system error: %d",
|
||||||
/* 2056 */ "",
|
/* 2056 */ "Server closed statement due to a prior %s function call",
|
||||||
/* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset",
|
/* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset",
|
||||||
/* 2058 */ "Plugin %s could not be loaded: %s",
|
/* 2058 */ "Plugin %s could not be loaded: %s",
|
||||||
/* 2059 */ "Can't connect twice. Already connected",
|
/* 2059 */ "Can't connect twice. Already connected",
|
||||||
|
@@ -384,6 +384,13 @@ mthd_my_send_cmd(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
|||||||
if (!arg)
|
if (!arg)
|
||||||
arg="";
|
arg="";
|
||||||
|
|
||||||
|
/* check if connection kills itself */
|
||||||
|
if (command == COM_PROCESS_KILL)
|
||||||
|
{
|
||||||
|
unsigned long thread_id= uint4korr(arg);
|
||||||
|
if (thread_id == mysql->thread_id)
|
||||||
|
skipp_check= 1;
|
||||||
|
}
|
||||||
if (net_write_command(net,(uchar) command,arg,
|
if (net_write_command(net,(uchar) command,arg,
|
||||||
length ? length : (ulong) strlen(arg)))
|
length ? length : (ulong) strlen(arg)))
|
||||||
{
|
{
|
||||||
@@ -1684,10 +1691,36 @@ error:
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct my_hook_data {
|
||||||
|
MYSQL *orig_mysql;
|
||||||
|
MYSQL *new_mysql;
|
||||||
|
/* This is always NULL currently, but restoring does not hurt just in case. */
|
||||||
|
MARIADB_PVIO *orig_pvio;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Callback hook to make the new VIO accessible via the old MYSQL to calling
|
||||||
|
application when suspending a non-blocking call during automatic reconnect.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
my_suspend_hook(my_bool suspend, void *data)
|
||||||
|
{
|
||||||
|
struct my_hook_data *hook_data= (struct my_hook_data *)data;
|
||||||
|
if (suspend)
|
||||||
|
{
|
||||||
|
hook_data->orig_pvio= hook_data->orig_mysql->net.pvio;
|
||||||
|
hook_data->orig_mysql->net.pvio= hook_data->new_mysql->net.pvio;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hook_data->orig_mysql->net.pvio= hook_data->orig_pvio;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static my_bool mysql_reconnect(MYSQL *mysql)
|
static my_bool mysql_reconnect(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL tmp_mysql;
|
MYSQL tmp_mysql;
|
||||||
LIST *li_stmt= mysql->stmts;
|
struct my_hook_data hook_data;
|
||||||
|
struct mysql_async_context *ctxt= NULL;
|
||||||
|
|
||||||
DBUG_ENTER("mysql_reconnect");
|
DBUG_ENTER("mysql_reconnect");
|
||||||
|
|
||||||
if (!mysql->reconnect ||
|
if (!mysql->reconnect ||
|
||||||
@@ -1705,19 +1738,21 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
/* don't reread options from configuration files */
|
/* don't reread options from configuration files */
|
||||||
tmp_mysql.options.my_cnf_group= tmp_mysql.options.my_cnf_file= NULL;
|
tmp_mysql.options.my_cnf_group= tmp_mysql.options.my_cnf_file= NULL;
|
||||||
|
|
||||||
/* make sure that we reconnect with the same character set */
|
if (IS_MYSQL_ASYNC_ACTIVE(mysql))
|
||||||
if (!tmp_mysql.options.charset_name ||
|
|
||||||
strcmp(tmp_mysql.options.charset_name, mysql->charset->csname))
|
|
||||||
{
|
{
|
||||||
my_free(tmp_mysql.options.charset_name);
|
hook_data.orig_mysql= mysql;
|
||||||
tmp_mysql.options.charset_name= my_strdup(mysql->charset->csname, MYF(MY_WME));
|
hook_data.new_mysql= &tmp_mysql;
|
||||||
|
hook_data.orig_pvio= mysql->net.pvio;
|
||||||
|
my_context_install_suspend_resume_hook(ctxt, my_suspend_hook, &hook_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_mysql.reconnect= mysql->reconnect;
|
|
||||||
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
|
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
|
||||||
mysql->db, mysql->port, mysql->unix_socket,
|
mysql->db, mysql->port, mysql->unix_socket,
|
||||||
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
|
mysql->client_flag | CLIENT_REMEMBER_OPTIONS) ||
|
||||||
|
mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
|
||||||
{
|
{
|
||||||
|
if (ctxt)
|
||||||
|
my_context_install_suspend_resume_hook(ctxt, NULL, NULL);
|
||||||
/* don't free options (CONC-118) */
|
/* don't free options (CONC-118) */
|
||||||
memset(&tmp_mysql.options, 0, sizeof(struct st_mysql_options));
|
memset(&tmp_mysql.options, 0, sizeof(struct st_mysql_options));
|
||||||
my_set_error(mysql, tmp_mysql.net.last_errno,
|
my_set_error(mysql, tmp_mysql.net.last_errno,
|
||||||
@@ -1727,19 +1762,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset the connection in all active statements
|
tmp_mysql.reconnect= mysql->reconnect;
|
||||||
todo: check stmt->mysql in mysql_stmt* functions ! */
|
|
||||||
for (;li_stmt;li_stmt= li_stmt->next)
|
|
||||||
{
|
|
||||||
MYSQL_STMT *stmt= (MYSQL_STMT *)li_stmt->data;
|
|
||||||
|
|
||||||
if (stmt->state != MYSQL_STMT_INITTED)
|
|
||||||
{
|
|
||||||
stmt->state= MYSQL_STMT_INITTED;
|
|
||||||
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_mysql.free_me= mysql->free_me;
|
tmp_mysql.free_me= mysql->free_me;
|
||||||
tmp_mysql.stmts= mysql->stmts;
|
tmp_mysql.stmts= mysql->stmts;
|
||||||
mysql->stmts= NULL;
|
mysql->stmts= NULL;
|
||||||
@@ -1747,16 +1770,31 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
/* Don't free options, we moved them to tmp_mysql */
|
/* Don't free options, we moved them to tmp_mysql */
|
||||||
memset(&mysql->options, 0, sizeof(mysql->options));
|
memset(&mysql->options, 0, sizeof(mysql->options));
|
||||||
mysql->free_me=0;
|
mysql->free_me=0;
|
||||||
mysql->stmts= NULL;
|
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
*mysql=tmp_mysql;
|
*mysql=tmp_mysql;
|
||||||
mysql->reconnect= 1;
|
mysql->net.pvio->mysql= mysql;
|
||||||
net_clear(&mysql->net);
|
net_clear(&mysql->net);
|
||||||
mysql->affected_rows= ~(my_ulonglong) 0;
|
mysql->affected_rows= ~(my_ulonglong) 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ma_invalidate_stmts(MYSQL *mysql, const char *function_name)
|
||||||
|
{
|
||||||
|
if (mysql->stmts)
|
||||||
|
{
|
||||||
|
LIST *li_stmt= mysql->stmts;
|
||||||
|
|
||||||
|
for (; li_stmt; li_stmt= li_stmt->next)
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt= (MYSQL_STMT *)li_stmt->data;
|
||||||
|
stmt->mysql= NULL;
|
||||||
|
SET_CLIENT_STMT_ERROR(stmt, CR_STMT_CLOSED, SQLSTATE_UNKNOWN, function_name);
|
||||||
|
}
|
||||||
|
mysql->stmts= NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
** Change user and database
|
** Change user and database
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -1786,36 +1824,33 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
else
|
else
|
||||||
mysql->charset=default_charset_info;
|
mysql->charset=default_charset_info;
|
||||||
|
|
||||||
mysql->user= (char *)user;
|
mysql->user= my_strdup(user ? user : "", MYF(MY_WME));
|
||||||
mysql->passwd= (char *)passwd;
|
mysql->passwd= my_strdup(passwd ? passwd : "", MYF(MY_WME));
|
||||||
mysql->db= (char *)db;
|
|
||||||
|
/* db will be set in run_plugin_auth */
|
||||||
|
mysql->db= 0;
|
||||||
rc= run_plugin_auth(mysql, 0, 0, 0, db);
|
rc= run_plugin_auth(mysql, 0, 0, 0, db);
|
||||||
|
|
||||||
|
/* COM_CHANGE_USER always releases prepared statements, so we need to invalidate them */
|
||||||
|
ma_invalidate_stmts(mysql, "mysql_change_user()");
|
||||||
|
|
||||||
if (rc==0)
|
if (rc==0)
|
||||||
{
|
{
|
||||||
LIST *li_stmt= mysql->stmts;
|
|
||||||
my_free(s_user);
|
my_free(s_user);
|
||||||
my_free(s_passwd);
|
my_free(s_passwd);
|
||||||
my_free(s_db);
|
my_free(s_db);
|
||||||
|
|
||||||
if (!(mysql->user= my_strdup(user,MYF(MY_WME))) ||
|
if (db && !(mysql->db= my_strdup(db,MYF(MY_WME))))
|
||||||
!(mysql->passwd=my_strdup(passwd,MYF(MY_WME))) ||
|
|
||||||
!(mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0))
|
|
||||||
{
|
{
|
||||||
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
||||||
rc= 1;
|
rc= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;li_stmt;li_stmt= li_stmt->next)
|
|
||||||
{
|
|
||||||
MYSQL_STMT *stmt= (MYSQL_STMT *)li_stmt->data;
|
|
||||||
stmt->mysql= NULL;
|
|
||||||
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
|
|
||||||
}/* detach stmts */
|
|
||||||
mysql->stmts= NULL;
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
my_free(mysql->user);
|
||||||
|
my_free(mysql->passwd);
|
||||||
|
my_free(mysql->db);
|
||||||
|
|
||||||
mysql->user= s_user;
|
mysql->user= s_user;
|
||||||
mysql->passwd= s_passwd;
|
mysql->passwd= s_passwd;
|
||||||
mysql->db= s_db;
|
mysql->db= s_db;
|
||||||
@@ -1870,6 +1905,7 @@ static void mysql_close_options(MYSQL *mysql)
|
|||||||
my_free(mysql->options.my_cnf_group);
|
my_free(mysql->options.my_cnf_group);
|
||||||
my_free(mysql->options.charset_dir);
|
my_free(mysql->options.charset_dir);
|
||||||
my_free(mysql->options.charset_name);
|
my_free(mysql->options.charset_name);
|
||||||
|
my_free(mysql->options.bind_address);
|
||||||
my_free(mysql->options.ssl_key);
|
my_free(mysql->options.ssl_key);
|
||||||
my_free(mysql->options.ssl_cert);
|
my_free(mysql->options.ssl_cert);
|
||||||
my_free(mysql->options.ssl_ca);
|
my_free(mysql->options.ssl_ca);
|
||||||
@@ -1946,12 +1982,9 @@ void mysql_close_slow_part(MYSQL *mysql)
|
|||||||
void STDCALL
|
void STDCALL
|
||||||
mysql_close(MYSQL *mysql)
|
mysql_close(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL_STMT *stmt;
|
|
||||||
DBUG_ENTER("mysql_close");
|
DBUG_ENTER("mysql_close");
|
||||||
if (mysql) /* Some simple safety */
|
if (mysql) /* Some simple safety */
|
||||||
{
|
{
|
||||||
LIST *li_stmt= mysql->stmts;
|
|
||||||
|
|
||||||
if (mysql->net.conn_hdlr && mysql->net.conn_hdlr->data)
|
if (mysql->net.conn_hdlr && mysql->net.conn_hdlr->data)
|
||||||
{
|
{
|
||||||
void *p= (void *)mysql->net.conn_hdlr;
|
void *p= (void *)mysql->net.conn_hdlr;
|
||||||
@@ -1963,14 +1996,8 @@ mysql_close(MYSQL *mysql)
|
|||||||
if (mysql->methods)
|
if (mysql->methods)
|
||||||
mysql->methods->db_close(mysql);
|
mysql->methods->db_close(mysql);
|
||||||
|
|
||||||
/* reset the connection in all active statements
|
/* reset the connection in all active statements */
|
||||||
todo: check stmt->mysql in mysql_stmt* functions ! */
|
ma_invalidate_stmts(mysql, "mysql_close()");
|
||||||
for (;li_stmt;li_stmt= li_stmt->next)
|
|
||||||
{
|
|
||||||
stmt= (MYSQL_STMT *)li_stmt->data;
|
|
||||||
stmt->mysql= NULL;
|
|
||||||
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
|
|
||||||
}
|
|
||||||
mysql_close_memory(mysql);
|
mysql_close_memory(mysql);
|
||||||
mysql_close_options(mysql);
|
mysql_close_options(mysql);
|
||||||
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
|
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
|
||||||
|
@@ -185,7 +185,7 @@ static size_t ma_pvio_read_async(MARIADB_PVIO *pvio, uchar *buffer, size_t lengt
|
|||||||
/* todo: async */
|
/* todo: async */
|
||||||
if (pvio->methods->async_read)
|
if (pvio->methods->async_read)
|
||||||
res= pvio->methods->async_read(pvio, buffer, length);
|
res= pvio->methods->async_read(pvio, buffer, length);
|
||||||
if (res >= 0 /* || IS_BLOCKING_ERROR()*/)
|
if (res >= 0 || IS_BLOCKING_ERROR())
|
||||||
return res;
|
return res;
|
||||||
b->events_to_wait_for= MYSQL_WAIT_READ;
|
b->events_to_wait_for= MYSQL_WAIT_READ;
|
||||||
if (timeout >= 0)
|
if (timeout >= 0)
|
||||||
@@ -211,14 +211,14 @@ size_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
|
|||||||
if (!pvio)
|
if (!pvio)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pvio && pvio->async_context && pvio->async_context->active)
|
if (IS_PVIO_ASYNC_ACTIVE(pvio))
|
||||||
{
|
{
|
||||||
r= ma_pvio_read_async(pvio, buffer, length);
|
r= ma_pvio_read_async(pvio, buffer, length);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pvio->async_context)
|
if (IS_PVIO_ASYNC(pvio))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If switching from non-blocking to blocking API usage, set the socket
|
If switching from non-blocking to blocking API usage, set the socket
|
||||||
@@ -232,8 +232,10 @@ size_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
|
|||||||
/* secure connection */
|
/* secure connection */
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
if (pvio->cssl)
|
if (pvio->cssl)
|
||||||
|
{
|
||||||
r= ma_pvio_ssl_read(pvio->cssl, buffer, length);
|
r= ma_pvio_ssl_read(pvio->cssl, buffer, length);
|
||||||
else
|
goto end;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (pvio->methods->read)
|
if (pvio->methods->read)
|
||||||
r= pvio->methods->read(pvio, buffer, length);
|
r= pvio->methods->read(pvio, buffer, length);
|
||||||
@@ -330,32 +332,24 @@ size_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
|
|||||||
if (!pvio)
|
if (!pvio)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pvio_callback)
|
|
||||||
{
|
|
||||||
void (*callback)(int mode, MYSQL *mysql, const uchar *buffer, size_t length);
|
|
||||||
LIST *p= pvio_callback;
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
callback= p->data;
|
|
||||||
callback(1, pvio->mysql, buffer, length);
|
|
||||||
p= p->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* secure connection */
|
/* secure connection */
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
if (pvio->cssl)
|
if (pvio->cssl)
|
||||||
|
{
|
||||||
r= ma_pvio_ssl_write(pvio->cssl, buffer, length);
|
r= ma_pvio_ssl_write(pvio->cssl, buffer, length);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (IS_ASYNC_ACTIVE(pvio))
|
// printf("No ssl (write): %x\n", pvio->cssl);
|
||||||
|
if (IS_PVIO_ASYNC_ACTIVE(pvio))
|
||||||
{
|
{
|
||||||
r= ma_pvio_write_async(pvio, buffer, length);
|
r= ma_pvio_write_async(pvio, buffer, length);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pvio->async_context)
|
if (IS_PVIO_ASYNC(pvio))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If switching from non-blocking to blocking API usage, set the socket
|
If switching from non-blocking to blocking API usage, set the socket
|
||||||
@@ -408,13 +402,45 @@ my_bool ma_pvio_get_handle(MARIADB_PVIO *pvio, void *handle)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ ma_pvio_wait_async */
|
||||||
|
static my_bool
|
||||||
|
ma_pvio_wait_async(struct mysql_async_context *b, enum enum_pvio_io_event event,
|
||||||
|
int timeout)
|
||||||
|
{
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case VIO_IO_EVENT_READ:
|
||||||
|
b->events_to_wait_for = MYSQL_WAIT_READ;
|
||||||
|
break;
|
||||||
|
case VIO_IO_EVENT_WRITE:
|
||||||
|
b->events_to_wait_for = MYSQL_WAIT_WRITE;
|
||||||
|
break;
|
||||||
|
case VIO_IO_EVENT_CONNECT:
|
||||||
|
b->events_to_wait_for = MYSQL_WAIT_WRITE | IF_WIN(0, MYSQL_WAIT_EXCEPT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout >= 0)
|
||||||
|
{
|
||||||
|
b->events_to_wait_for |= MYSQL_WAIT_TIMEOUT;
|
||||||
|
b->timeout_value= timeout;
|
||||||
|
}
|
||||||
|
if (b->suspend_resume_hook)
|
||||||
|
(*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
|
||||||
|
my_context_yield(&b->async_context);
|
||||||
|
if (b->suspend_resume_hook)
|
||||||
|
(*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
|
||||||
|
return (b->events_occured & MYSQL_WAIT_TIMEOUT) ? 0 : 1;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ ma_pvio_wait_io_or_timeout */
|
/* {{{ ma_pvio_wait_io_or_timeout */
|
||||||
int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout)
|
int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout)
|
||||||
{
|
{
|
||||||
if (pvio && pvio->async_context && pvio->async_context->active)
|
if (IS_PVIO_ASYNC_ACTIVE(pvio))
|
||||||
return my_io_wait_async(pvio->async_context,
|
return ma_pvio_wait_async(pvio->mysql->options.extension->async_context,
|
||||||
(is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE,
|
(is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE,
|
||||||
timeout);
|
timeout);
|
||||||
|
|
||||||
|
|
||||||
if (pvio && pvio->methods->wait_io_or_timeout)
|
if (pvio && pvio->methods->wait_io_or_timeout)
|
||||||
@@ -450,6 +476,19 @@ my_bool ma_pvio_is_blocking(MARIADB_PVIO *pvio)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ ma_pvio_has_data */
|
||||||
|
my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
|
||||||
|
{
|
||||||
|
/* check if we still have unread data in cache */
|
||||||
|
if (pvio->cache)
|
||||||
|
if (pvio->cache_pos > pvio->cache)
|
||||||
|
return pvio->cache_pos - pvio->cache;
|
||||||
|
if (pvio && pvio->methods->has_data)
|
||||||
|
return pvio->methods->has_data(pvio, data_len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
/* {{{ my_bool ma_pvio_start_ssl */
|
/* {{{ my_bool ma_pvio_start_ssl */
|
||||||
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
||||||
@@ -463,7 +502,7 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
|||||||
}
|
}
|
||||||
if (ma_pvio_ssl_connect(pvio->cssl))
|
if (ma_pvio_ssl_connect(pvio->cssl))
|
||||||
{
|
{
|
||||||
my_free((gptr)pvio->cssl);
|
my_free(pvio->cssl);
|
||||||
pvio->cssl= NULL;
|
pvio->cssl= NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -415,7 +415,8 @@ unsigned char *mysql_net_store_length(unsigned char *packet, size_t length)
|
|||||||
int store_param(MYSQL_STMT *stmt, int column, unsigned char **p)
|
int store_param(MYSQL_STMT *stmt, int column, unsigned char **p)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("store_param");
|
DBUG_ENTER("store_param");
|
||||||
DBUG_PRINT("info", ("column: %d type: x%x", column, stmt->params[column].buffer_type));
|
DBUG_PRINT("info", ("column: %d type: %d", column, stmt->params[column].buffer_type));
|
||||||
|
printf("type: %d\n", column, stmt->params[column].buffer_type);
|
||||||
switch (stmt->params[column].buffer_type) {
|
switch (stmt->params[column].buffer_type) {
|
||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
int1store(*p, *(uchar *)stmt->params[column].buffer);
|
int1store(*p, *(uchar *)stmt->params[column].buffer);
|
||||||
|
@@ -134,37 +134,6 @@ my_connect_async(MARIADB_PVIO *pvio,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
my_bool
|
|
||||||
my_io_wait_async(struct mysql_async_context *b, enum enum_pvio_io_event event,
|
|
||||||
int timeout)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case VIO_IO_EVENT_READ:
|
|
||||||
b->events_to_wait_for = MYSQL_WAIT_READ;
|
|
||||||
break;
|
|
||||||
case VIO_IO_EVENT_WRITE:
|
|
||||||
b->events_to_wait_for = MYSQL_WAIT_WRITE;
|
|
||||||
break;
|
|
||||||
case VIO_IO_EVENT_CONNECT:
|
|
||||||
b->events_to_wait_for = MYSQL_WAIT_WRITE | IF_WIN(0, MYSQL_WAIT_EXCEPT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeout >= 0)
|
|
||||||
{
|
|
||||||
b->events_to_wait_for |= MYSQL_WAIT_TIMEOUT;
|
|
||||||
b->timeout_value= timeout;
|
|
||||||
}
|
|
||||||
if (b->suspend_resume_hook)
|
|
||||||
(*b->suspend_resume_hook)(TRUE, b->suspend_resume_hook_user_data);
|
|
||||||
my_context_yield(&b->async_context);
|
|
||||||
if (b->suspend_resume_hook)
|
|
||||||
(*b->suspend_resume_hook)(FALSE, b->suspend_resume_hook_user_data);
|
|
||||||
return (b->events_occured & MYSQL_WAIT_TIMEOUT) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SSL_FIXME
|
#ifdef HAVE_SSL_FIXME
|
||||||
static my_bool
|
static my_bool
|
||||||
my_ssl_async_check_result(int res, struct mysql_async_context *b, MARIADB_SSL *cssl)
|
my_ssl_async_check_result(int res, struct mysql_async_context *b, MARIADB_SSL *cssl)
|
||||||
|
@@ -179,67 +179,11 @@ static my_bool net_realloc(NET *net, size_t length)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove unwanted characters from connection */
|
||||||
/* check if the socket is still alive */
|
|
||||||
static my_bool net_check_socket_status(my_socket sock)
|
|
||||||
{
|
|
||||||
#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((int)sock + 1, &sfds, NULL, NULL, &tv);
|
|
||||||
if (res > 0 && FD_ISSET(sock, &sfds))
|
|
||||||
return TRUE;
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove unwanted characters from connection */
|
|
||||||
|
|
||||||
void net_clear(NET *net)
|
void net_clear(NET *net)
|
||||||
{
|
{
|
||||||
my_socket sock;
|
|
||||||
DBUG_ENTER("net_clear");
|
DBUG_ENTER("net_clear");
|
||||||
|
|
||||||
ma_pvio_get_handle(net->pvio, &sock);
|
|
||||||
|
|
||||||
/* 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(sock))
|
|
||||||
{
|
|
||||||
if ((ssize_t)ma_pvio_cache_read(net->pvio, (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->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
|
||||||
net->write_pos=net->buff;
|
net->write_pos=net->buff;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@@ -235,6 +235,12 @@ ssize_t ma_ssl_pull(gnutls_transport_ptr_t ptr, void* data, size_t len)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ma_ssl_pull_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
|
||||||
|
{
|
||||||
|
MARIADB_PVIO *pvio= (MARIADB_PVIO *)ptr;
|
||||||
|
return pvio->methods->wait_io_or_timeout(pvio, 0, ms);
|
||||||
|
}
|
||||||
|
|
||||||
my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
||||||
{
|
{
|
||||||
gnutls_session_t ssl = (gnutls_session_t)cssl->ssl;
|
gnutls_session_t ssl = (gnutls_session_t)cssl->ssl;
|
||||||
@@ -257,7 +263,8 @@ my_bool ma_ssl_connect(MARIADB_SSL *cssl)
|
|||||||
gnutls_transport_set_ptr(ssl, pvio);
|
gnutls_transport_set_ptr(ssl, pvio);
|
||||||
gnutls_transport_set_push_function(ssl, ma_ssl_push);
|
gnutls_transport_set_push_function(ssl, ma_ssl_push);
|
||||||
gnutls_transport_set_pull_function(ssl, ma_ssl_pull);
|
gnutls_transport_set_pull_function(ssl, ma_ssl_pull);
|
||||||
gnutls_handshake_set_timeout(ssl, mysql->options.connect_timeout);
|
gnutls_transport_set_pull_timeout_function(ssl, ma_ssl_pull_timeout);
|
||||||
|
gnutls_handshake_set_timeout(ssl, pvio->timeout[PVIO_CONNECT_TIMEOUT]);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = gnutls_handshake(ssl);
|
ret = gnutls_handshake(ssl);
|
||||||
@@ -417,3 +424,4 @@ unsigned int ma_ssl_get_finger_print(MARIADB_SSL *cssl, unsigned char *fp, unsig
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_GNUTLS */
|
#endif /* HAVE_GNUTLS */
|
||||||
|
|
||||||
|
@@ -76,6 +76,7 @@ int pvio_socket_keepalive(MARIADB_PVIO *pvio);
|
|||||||
my_bool pvio_socket_get_handle(MARIADB_PVIO *pvio, void *handle);
|
my_bool pvio_socket_get_handle(MARIADB_PVIO *pvio, void *handle);
|
||||||
my_bool pvio_socket_is_blocking(MARIADB_PVIO *pvio);
|
my_bool pvio_socket_is_blocking(MARIADB_PVIO *pvio);
|
||||||
my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio);
|
my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio);
|
||||||
|
my_bool pvio_socket_has_data(MARIADB_PVIO *pvio, ssize_t *data_len);
|
||||||
|
|
||||||
static int pvio_socket_init(char *unused1,
|
static int pvio_socket_init(char *unused1,
|
||||||
size_t unused2,
|
size_t unused2,
|
||||||
@@ -98,7 +99,8 @@ struct st_ma_pvio_methods pvio_socket_methods= {
|
|||||||
pvio_socket_keepalive,
|
pvio_socket_keepalive,
|
||||||
pvio_socket_get_handle,
|
pvio_socket_get_handle,
|
||||||
pvio_socket_is_blocking,
|
pvio_socket_is_blocking,
|
||||||
pvio_socket_is_alive
|
pvio_socket_is_alive,
|
||||||
|
pvio_socket_has_data
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef HAVE_SOCKET_DYNAMIC
|
#ifndef HAVE_SOCKET_DYNAMIC
|
||||||
@@ -913,11 +915,14 @@ my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio)
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
memset(&poll_fd, 0, sizeof(struct pollfd));
|
memset(&poll_fd, 0, sizeof(struct pollfd));
|
||||||
poll_fd.events= POLLPRI | POLLIN;
|
poll_fd.events= POLLPRI | POLLIN;
|
||||||
|
poll_fd.revents= POLLERR;
|
||||||
poll_fd.fd= csock->socket;
|
poll_fd.fd= csock->socket;
|
||||||
|
|
||||||
res= poll(&poll_fd, 1, 0);
|
res= poll(&poll_fd, 1, 0);
|
||||||
if (res <= 0) /* timeout or error */
|
if (res <= 0) /* timeout or error */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (!(poll_fd.revents & POLLERR))
|
||||||
|
return FALSE;
|
||||||
if (!(poll_fd.revents & (POLLIN | POLLPRI)))
|
if (!(poll_fd.revents & (POLLIN | POLLPRI)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -931,10 +936,35 @@ my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio)
|
|||||||
FD_ZERO(&sfds);
|
FD_ZERO(&sfds);
|
||||||
FD_SET(csock->socket, &sfds);
|
FD_SET(csock->socket, &sfds);
|
||||||
|
|
||||||
res= select((int)+csock->socket + 1, &sfds, NULL, NULL, &tv);
|
res= select((int)csock->socket + 1, &sfds, NULL, NULL, &tv);
|
||||||
if (res > 0 && FD_ISSET(csock->socket, &sfds))
|
if (res > 0 && FD_ISSET(csock->socket, &sfds))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ my_boool pvio_socket_has_data */
|
||||||
|
my_bool pvio_socket_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
|
||||||
|
{
|
||||||
|
struct st_pvio_socket *csock= NULL;
|
||||||
|
char tmp_buf[1024];
|
||||||
|
ssize_t len;
|
||||||
|
my_bool mode;
|
||||||
|
|
||||||
|
if (!pvio || !pvio->data)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
csock= (struct st_pvio_socket *)pvio->data;
|
||||||
|
/* MSG_PEEK: Peeks at the incoming data. The data is copied into the buffer,
|
||||||
|
but is not removed from the input queue.
|
||||||
|
*/
|
||||||
|
pvio_socket_blocking(pvio, 0, &mode);
|
||||||
|
len= recv(csock->socket, &tmp_buf, sizeof(tmp_buf), MSG_PEEK);
|
||||||
|
pvio_socket_blocking(pvio, mode, 0);
|
||||||
|
if (len < 0)
|
||||||
|
return 1;
|
||||||
|
*data_len= len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
@@ -39,8 +39,7 @@ static int test_conc75(MYSQL *my)
|
|||||||
mysql= mysql_init(NULL);
|
mysql= mysql_init(NULL);
|
||||||
|
|
||||||
|
|
||||||
mysql_options(mysql, MYSQL_OPT_RECONNECT,(const char *)"true");
|
mysql->reconnect= 1;
|
||||||
|
|
||||||
mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
|
mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0| CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS);
|
||||||
|
|
||||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS a");
|
||||||
|
@@ -487,6 +487,7 @@ static int bug30472_retrieve_charset_info(MYSQL *con,
|
|||||||
row= mysql_fetch_row(rs);
|
row= mysql_fetch_row(rs);
|
||||||
FAIL_IF(!row, "Couldn't fetch row");
|
FAIL_IF(!row, "Couldn't fetch row");
|
||||||
strcpy(character_set_client, row[1]);
|
strcpy(character_set_client, row[1]);
|
||||||
|
diag("cs: %s", row[1]);
|
||||||
mysql_free_result(rs);
|
mysql_free_result(rs);
|
||||||
|
|
||||||
rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'");
|
rc= mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'");
|
||||||
|
@@ -964,7 +964,6 @@ static int test_conc117(MYSQL *mysql)
|
|||||||
mysql_kill(my, mysql_thread_id(my));
|
mysql_kill(my, mysql_thread_id(my));
|
||||||
sleep(5);
|
sleep(5);
|
||||||
|
|
||||||
strcpy(my->host, "A");
|
|
||||||
my->reconnect= 1;
|
my->reconnect= 1;
|
||||||
|
|
||||||
mysql_query(my, "SET @a:=1");
|
mysql_query(my, "SET @a:=1");
|
||||||
|
@@ -374,7 +374,7 @@ MYSQL *test_connect(struct my_tests_st *test) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, "1");
|
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &i);
|
||||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&i);
|
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&i);
|
||||||
|
|
||||||
/* option handling */
|
/* option handling */
|
||||||
|
@@ -523,10 +523,12 @@ static int test_bug12744(MYSQL *mysql)
|
|||||||
check_stmt_rc(rc, stmt);
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
/* set reconnect, kill and ping to reconnect */
|
/* set reconnect, kill and ping to reconnect */
|
||||||
|
rc= mysql_query(mysql, "SET @a:=1");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, "1");
|
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, "1");
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
rc= mysql_kill(mysql, mysql_thread_id(mysql));
|
rc= mysql_kill(mysql, mysql_thread_id(mysql));
|
||||||
//check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
sleep(2);
|
sleep(2);
|
||||||
rc= mysql_ping(mysql);
|
rc= mysql_ping(mysql);
|
||||||
@@ -542,10 +544,10 @@ static int test_bug1500(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
MYSQL_STMT *stmt;
|
MYSQL_STMT *stmt;
|
||||||
MYSQL_BIND my_bind[3];
|
MYSQL_BIND my_bind[3];
|
||||||
int rc;
|
int rc= 0;
|
||||||
int32 int_data[3]= {2, 3, 4};
|
int32 int_data[3]= {2, 3, 4};
|
||||||
const char *data;
|
char *data;
|
||||||
const char *query;
|
char *query;
|
||||||
|
|
||||||
|
|
||||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
|
||||||
@@ -1084,6 +1086,8 @@ static int test_bug20152(MYSQL *mysql)
|
|||||||
my_bind[0].buffer_type= MYSQL_TYPE_DATE;
|
my_bind[0].buffer_type= MYSQL_TYPE_DATE;
|
||||||
my_bind[0].buffer= (void*)&tm;
|
my_bind[0].buffer= (void*)&tm;
|
||||||
|
|
||||||
|
memset(&tm, 0, sizeof(MYSQL_TIME));
|
||||||
|
|
||||||
tm.year = 2006;
|
tm.year = 2006;
|
||||||
tm.month = 6;
|
tm.month = 6;
|
||||||
tm.day = 18;
|
tm.day = 18;
|
||||||
@@ -2180,11 +2184,11 @@ static int test_bug4026(MYSQL *mysql)
|
|||||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||||
check_stmt_rc(rc, stmt);
|
check_stmt_rc(rc, stmt);
|
||||||
/* Bind input buffers */
|
/* Bind input buffers */
|
||||||
memset(my_bind, '\0', sizeof(my_bind));
|
memset(my_bind, '\0', sizeof(MYSQL_BIND) * 2);
|
||||||
memset(&time_in, '\0', sizeof(time_in));
|
memset(&time_in, '\0', sizeof(MYSQL_TIME));
|
||||||
memset(&time_out, '\0', sizeof(time_out));
|
memset(&time_out, '\0', sizeof(MYSQL_TIME));
|
||||||
memset(&datetime_in, '\0', sizeof(datetime_in));
|
memset(&datetime_in, '\0', sizeof(MYSQL_TIME));
|
||||||
memset(&datetime_out, '\0', sizeof(datetime_out));
|
memset(&datetime_out, '\0', sizeof(MYSQL_TIME));
|
||||||
my_bind[0].buffer_type= MYSQL_TYPE_TIME;
|
my_bind[0].buffer_type= MYSQL_TYPE_TIME;
|
||||||
my_bind[0].buffer= (void *) &time_in;
|
my_bind[0].buffer= (void *) &time_in;
|
||||||
my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
|
my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
|
||||||
|
@@ -680,6 +680,9 @@ const char *ssl_cert_finger_print= "@SSL_CERT_FINGER_PRINT@";
|
|||||||
static int test_ssl_fp(MYSQL *unused)
|
static int test_ssl_fp(MYSQL *unused)
|
||||||
{
|
{
|
||||||
MYSQL *my;
|
MYSQL *my;
|
||||||
|
MYSQL_RES *res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (check_skip_ssl())
|
if (check_skip_ssl())
|
||||||
return SKIP;
|
return SKIP;
|
||||||
@@ -695,6 +698,20 @@ static int test_ssl_fp(MYSQL *unused)
|
|||||||
port, socketname, 0), mysql_error(my));
|
port, socketname, 0), mysql_error(my));
|
||||||
|
|
||||||
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
|
FAIL_IF(check_cipher(my) != 0, "Invalid cipher");
|
||||||
|
|
||||||
|
mysql_query(my, "SET @a:=1");
|
||||||
|
check_mysql_rc(rc, my);
|
||||||
|
|
||||||
|
mysql_query(my, "SELECT @a");
|
||||||
|
check_mysql_rc(rc, my);
|
||||||
|
|
||||||
|
if ((res= mysql_store_result(my)))
|
||||||
|
{
|
||||||
|
row= mysql_fetch_row(res);
|
||||||
|
diag("@a:=%s", row[0]);
|
||||||
|
mysql_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
mysql_close(my);
|
mysql_close(my);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user