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
Initial cio implementation
This commit is contained in:
@@ -21,9 +21,7 @@ ENDIF()
|
|||||||
### Options ###
|
### Options ###
|
||||||
IF(NOT WIN32)
|
IF(NOT WIN32)
|
||||||
OPTION(WITH_MYSQLCOMPAT "creates libmysql* symbolic links" ON)
|
OPTION(WITH_MYSQLCOMPAT "creates libmysql* symbolic links" ON)
|
||||||
OPTION(WITH_OPENSSL "enables SSL support" ON)
|
|
||||||
ELSE()
|
ELSE()
|
||||||
OPTION(WITH_OPENSSL "enables SSL support" OFF)
|
|
||||||
OPTION(WITH_SIGNCODE "digitally sign files" OFF)
|
OPTION(WITH_SIGNCODE "digitally sign files" OFF)
|
||||||
OPTION(WITH_RTC "enables run time checks for debug builds" OFF)
|
OPTION(WITH_RTC "enables run time checks for debug builds" OFF)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
@@ -112,9 +110,9 @@ ENDIF()
|
|||||||
|
|
||||||
IF(UNIX)
|
IF(UNIX)
|
||||||
SEARCH_LIBRARY(DEFAULT_LIB inet_ntoa "c")
|
SEARCH_LIBRARY(DEFAULT_LIB inet_ntoa "c")
|
||||||
IF(NOT DEFAULT_LIB)
|
# IF(NOT DEFAULT_LIB)
|
||||||
SEARCH_LIBRARY(LIBNSL inet_ntoa "nsl_r;nsl")
|
SEARCH_LIBRARY(LIBNSL inet_ntoa "nsl_r;nsl")
|
||||||
ENDIF()
|
# ENDIF()
|
||||||
SEARCH_LIBRARY(DEFAULT_LIB bind "c")
|
SEARCH_LIBRARY(DEFAULT_LIB bind "c")
|
||||||
IF(NOT DEFAULT_LIB)
|
IF(NOT DEFAULT_LIB)
|
||||||
SEARCH_LIBRARY(LIBBIND bind "bind;socket")
|
SEARCH_LIBRARY(LIBBIND bind "bind;socket")
|
||||||
@@ -159,18 +157,35 @@ 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)
|
||||||
|
|
||||||
# Check for OpenSSL
|
IF(WITH_SSL STREQUAL "OPENSSL")
|
||||||
IF(WITH_OPENSSL)
|
|
||||||
FIND_PACKAGE(OpenSSL)
|
FIND_PACKAGE(OpenSSL)
|
||||||
IF(OPENSSL_FOUND)
|
IF(OPENSSL_FOUND)
|
||||||
ADD_DEFINITIONS(-DHAVE_OPENSSL)
|
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_SSL)
|
||||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_openssl_plugin)
|
||||||
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_openssl.c")
|
||||||
IF(OPENSSL_CRYPTO_LIBRARIES)
|
SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
SET(SSL_LIBRARIES ${SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES})
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(FATAL_ERROR "OpenSSL not found. Please install OpenSSL or disable SSL support via option -DWITH_OPENSSL=Off")
|
MESSAGE(FATAL "OpenSSL not found")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
IF(WITH_SSL STREQUAL "GNUTLS")
|
||||||
|
FIND_PACKAGE(GnuTLS)
|
||||||
|
IF(GNUTLS_FOUND)
|
||||||
|
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_gnutls_plugin)
|
||||||
|
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_SSL)
|
||||||
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_gnutls.c")
|
||||||
|
SET(SSL_LIBRARIES ${GNUTLS_LIBRARIES})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL "GnuTLS not found")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
IF(WIN32)
|
||||||
|
IF(WITH_SSL STREQUAL "SCHANNEL")
|
||||||
|
ADD_DEFINITIONS(-DSSL_PLUGIN=cio_schannel_plugin)
|
||||||
|
MESSAGE(STATUS "SSL_TYPE ${SSL_TYPE}")
|
||||||
|
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_SSL)
|
||||||
|
SET(SSL_SOURCES "${CMAKE_SOURCE_DIR}/plugins/builtin/cio_schannel.c" "${CMAKE_SOURCE_DIR}/plugins/builtin/ma_schannel.c")
|
||||||
|
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/plugins/cio/")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
@@ -283,7 +298,7 @@ MESSAGE(STATUS "CPack generation: ${CPACK_GENERATOR}")
|
|||||||
IF(CLIENT_DOCS)
|
IF(CLIENT_DOCS)
|
||||||
MESSAGE(STATUS "Documentation included from ${CLIENT_DOCS}")
|
MESSAGE(STATUS "Documentation included from ${CLIENT_DOCS}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
MESSAGE(STATUS "SSL support: ${WITH_OPENSSL}")
|
MESSAGE(STATUS "SSL support: ${WITH_SSL} Sources: ${SSL_SOURCES}")
|
||||||
MESSAGE(STATUS "Experimental Sqlite support: ${WITH_SQLITE}")
|
MESSAGE(STATUS "Experimental Sqlite support: ${WITH_SQLITE}")
|
||||||
IF(WITH_EXTERNAL_ZLIB)
|
IF(WITH_EXTERNAL_ZLIB)
|
||||||
MESSAGE(STATUS "Zlib support: ${WITH_EXTERNAL_ZLIB}")
|
MESSAGE(STATUS "Zlib support: ${WITH_EXTERNAL_ZLIB}")
|
||||||
|
@@ -25,6 +25,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
void init_client_errs(void);
|
void init_client_errs(void);
|
||||||
extern const char *client_errors[]; /* Error messages */
|
extern const char *client_errors[]; /* Error messages */
|
||||||
|
extern const char *mariadb_client_errors[]; /* Error messages */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -32,11 +33,10 @@ extern const char *client_errors[]; /* Error messages */
|
|||||||
|
|
||||||
#define CR_MIN_ERROR 2000 /* For easier client code */
|
#define CR_MIN_ERROR 2000 /* For easier client code */
|
||||||
#define CR_MAX_ERROR 2999
|
#define CR_MAX_ERROR 2999
|
||||||
#if defined(OS2) && defined( MYSQL_SERVER)
|
#define CER_MIN_ERROR 5000
|
||||||
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
|
#define CER_MAX_ERROR 5999
|
||||||
#else
|
#define CER(X) mariadb_client_errors[(X)-CER_MIN_ERROR]
|
||||||
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
||||||
#endif
|
|
||||||
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
||||||
|
|
||||||
#define CR_UNKNOWN_ERROR 2000
|
#define CR_UNKNOWN_ERROR 2000
|
||||||
@@ -66,6 +66,11 @@ extern const char *client_errors[]; /* Error messages */
|
|||||||
#define CR_PARAMS_NOT_BOUND 2031
|
#define CR_PARAMS_NOT_BOUND 2031
|
||||||
#define CR_INVALID_PARAMETER_NO 2034
|
#define CR_INVALID_PARAMETER_NO 2034
|
||||||
#define CR_UNSUPPORTED_PARAM_TYPE 2036
|
#define CR_UNSUPPORTED_PARAM_TYPE 2036
|
||||||
|
|
||||||
|
#define CR_SHARED_MEMORY_CONNECTION 2037
|
||||||
|
#define CR_SHARED_MEMORY_CONNECT_ERROR 2038
|
||||||
|
|
||||||
|
|
||||||
#define CR_SECURE_AUTH 2049
|
#define CR_SECURE_AUTH 2049
|
||||||
#define CR_NO_DATA 2051
|
#define CR_NO_DATA 2051
|
||||||
#define CR_NO_STMT_METADATA 2052
|
#define CR_NO_STMT_METADATA 2052
|
||||||
@@ -76,6 +81,9 @@ extern const char *client_errors[]; /* Error messages */
|
|||||||
#define CR_ALREADY_CONNECTED 2059
|
#define CR_ALREADY_CONNECTED 2059
|
||||||
#define CR_PLUGIN_FUNCTION_NOT_SUPPORTED 2060
|
#define CR_PLUGIN_FUNCTION_NOT_SUPPORTED 2060
|
||||||
|
|
||||||
|
#define CR_EVENT_CREATE_FAILED 5000
|
||||||
|
#define CR_BIND_ADDR_FAILED 5001
|
||||||
|
|
||||||
#define SQLSTATE_UNKNOWN "HY000"
|
#define SQLSTATE_UNKNOWN "HY000"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -251,7 +251,7 @@ struct st_mysql_options {
|
|||||||
my_bool compress,named_pipe;
|
my_bool compress,named_pipe;
|
||||||
my_bool unused_1, unused_2, unused_3, unused_4;
|
my_bool unused_1, unused_2, unused_3, unused_4;
|
||||||
enum mysql_option methods_to_use;
|
enum mysql_option methods_to_use;
|
||||||
char *client_ip;
|
char *bind_address;
|
||||||
my_bool secure_auth;
|
my_bool secure_auth;
|
||||||
my_bool report_data_truncation;
|
my_bool report_data_truncation;
|
||||||
/* function pointers for local infile support */
|
/* function pointers for local infile support */
|
||||||
|
@@ -36,14 +36,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* known plugin types */
|
/* known plugin types */
|
||||||
#define MYSQL_CLIENT_DB_PLUGIN 0
|
#define MYSQL_CLIENT_GENERIC_PLUGIN 0
|
||||||
#define MYSQL_CLIENT_reserved 1
|
#define MYSQL_CLIENT_CIO_PLUGIN 1 /* communication IO */
|
||||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2
|
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 /* authentication */
|
||||||
#define MYSQL_CLIENT_reserved22 3
|
#define MYSQL_CLIENT_TRACE_PLUGIN 3 /* cio trace */
|
||||||
#define MYSQL_CLIENT_REMOTEIO_PLUGIN 4
|
#define MYSQL_CLIENT_REMOTEIO_PLUGIN 4
|
||||||
|
|
||||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
|
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
|
||||||
#define MYSQL_CLIENT_DB_PLUGIN_INTERFACE_VERSION 0x0100
|
#define MYSQL_CLIENT_DB_PLUGIN_INTERFACE_VERSION 0x0100
|
||||||
|
#define MYSQL_CLIENT_CIO_PLUGIN_INTERFACE_VERSION 0x0100
|
||||||
|
#define MYSQL_CLIENT_SSL_INTERFACE_VERSION 0x0100
|
||||||
|
#define MYSQL_CLIENT_TRACE_PLUGIN_INTERFACE_VERSION 0x01000
|
||||||
#define MYSQL_CLIENT_REMOTEIO_PLUGIN_INTERFACE_VERSION 0x0100
|
#define MYSQL_CLIENT_REMOTEIO_PLUGIN_INTERFACE_VERSION 0x0100
|
||||||
|
|
||||||
#define MYSQL_CLIENT_MAX_PLUGINS 5
|
#define MYSQL_CLIENT_MAX_PLUGINS 5
|
||||||
@@ -63,9 +66,9 @@
|
|||||||
const char *author; \
|
const char *author; \
|
||||||
const char *desc; \
|
const char *desc; \
|
||||||
unsigned int version[3]; \
|
unsigned int version[3]; \
|
||||||
|
const char *license; \
|
||||||
int (*init)(char *, size_t, int, va_list); \
|
int (*init)(char *, size_t, int, va_list); \
|
||||||
int (*deinit)(void);
|
int (*deinit)();
|
||||||
|
|
||||||
struct st_mysql_client_plugin
|
struct st_mysql_client_plugin
|
||||||
{
|
{
|
||||||
MYSQL_CLIENT_PLUGIN_HEADER
|
MYSQL_CLIENT_PLUGIN_HEADER
|
||||||
@@ -83,6 +86,18 @@ typedef struct st_mariadb_client_plugin_DB
|
|||||||
|
|
||||||
#define MARIADB_DB_DRIVER(a) ((a)->ext_db)
|
#define MARIADB_DB_DRIVER(a) ((a)->ext_db)
|
||||||
|
|
||||||
|
/******************* Communication IO plugin *****************/
|
||||||
|
#include <ma_cio.h>
|
||||||
|
#include <ma_ssl.h>
|
||||||
|
|
||||||
|
typedef struct st_mariadb_client_plugin_CIO
|
||||||
|
{
|
||||||
|
MYSQL_CLIENT_PLUGIN_HEADER
|
||||||
|
struct st_ma_cio_methods *methods;
|
||||||
|
struct st_ma_cio_ssl_methods *ssl_methods;
|
||||||
|
void *compress_methods;
|
||||||
|
} MARIADB_CIO_PLUGIN;
|
||||||
|
|
||||||
/******** authentication plugin specific declarations *********/
|
/******** authentication plugin specific declarations *********/
|
||||||
#include <mysql/plugin_auth_common.h>
|
#include <mysql/plugin_auth_common.h>
|
||||||
|
|
||||||
@@ -92,6 +107,11 @@ struct st_mysql_client_plugin_AUTHENTICATION
|
|||||||
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
|
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/******** trace plugin *******/
|
||||||
|
struct st_mysql_client_plugin_TRACE
|
||||||
|
{
|
||||||
|
MYSQL_CLIENT_PLUGIN_HEADER
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
type of the mysql_authentication_dialog_ask function
|
type of the mysql_authentication_dialog_ask function
|
||||||
|
@@ -1,40 +1,37 @@
|
|||||||
/* Copyright (C) 2012 MariaDB Services and Kristian Nielsen
|
/* Copyright (C) 2012 MariaDB Services and Kristian Nielsen
|
||||||
2015 MariaDB Corporation
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or modify
|
||||||
modify it under the terms of the GNU Library General Public
|
it under the terms of the GNU General Public License as published by
|
||||||
License as published by the Free Software Foundation; either
|
the Free Software Foundation; version 2 of the License.
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
Library General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
You should have received a copy of the GNU General Public License
|
||||||
License along with this library; if not, write to the Free
|
along with this program; if not, write to the Free Software
|
||||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
MA 02111-1307, USA */
|
|
||||||
|
|
||||||
/* Common definitions for MariaDB non-blocking client library. */
|
/* Common definitions for MariaDB non-blocking client library. */
|
||||||
|
|
||||||
#ifndef MYSQL_ASYNC_H
|
#ifndef MYSQL_ASYNC_H
|
||||||
#define MYSQL_ASYNC_H
|
#define MYSQL_ASYNC_H
|
||||||
|
|
||||||
extern int my_connect_async(struct mysql_async_context *b, my_socket fd,
|
extern int my_connect_async(MARIADB_CIO *cio,
|
||||||
const struct sockaddr *name, uint namelen,
|
const struct sockaddr *name, uint namelen,
|
||||||
int vio_timeout);
|
int vio_timeout);
|
||||||
extern ssize_t my_recv_async(struct mysql_async_context *b, int fd,
|
extern ssize_t my_recv_async(MARIADB_CIO *cio,
|
||||||
unsigned char *buf, size_t size, int timeout);
|
const unsigned char *buf, size_t size, int timeout);
|
||||||
extern ssize_t my_send_async(struct mysql_async_context *b, int fd,
|
extern ssize_t my_send_async(MARIADB_CIO *cio,
|
||||||
const unsigned char *buf, size_t size,
|
const unsigned char *buf, size_t size,
|
||||||
int timeout);
|
int timeout);
|
||||||
extern my_bool my_io_wait_async(struct mysql_async_context *b,
|
extern my_bool my_io_wait_async(struct mysql_async_context *b,
|
||||||
enum enum_vio_io_event event, int timeout);
|
enum enum_cio_io_event event, int timeout);
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_SSL
|
||||||
extern int my_ssl_read_async(struct mysql_async_context *b, SSL *ssl,
|
extern int my_ssl_read_async(struct mysql_async_context *b, MARIADB_SSL *ssl,
|
||||||
void *buf, int size);
|
void *buf, int size);
|
||||||
extern int my_ssl_write_async(struct mysql_async_context *b, SSL *ssl,
|
extern int my_ssl_write_async(struct mysql_async_context *b, MARIADB_SSL *ssl,
|
||||||
const void *buf, int size);
|
const void *buf, int size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -216,6 +216,8 @@ class Vio; /* Fill Vio class in C++ */
|
|||||||
#else
|
#else
|
||||||
struct st_vio; /* Only C */
|
struct st_vio; /* Only C */
|
||||||
typedef struct st_vio Vio;
|
typedef struct st_vio Vio;
|
||||||
|
struct st_ma_cio;
|
||||||
|
typedef struct st_ma_cio MARIADB_CIO;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -233,7 +235,7 @@ typedef struct st_vio Vio;
|
|||||||
|
|
||||||
|
|
||||||
typedef struct st_net {
|
typedef struct st_net {
|
||||||
Vio *vio;
|
MARIADB_CIO *cio;
|
||||||
unsigned char *buff;
|
unsigned char *buff;
|
||||||
unsigned char *buff_end,*write_pos,*read_pos;
|
unsigned char *buff_end,*write_pos,*read_pos;
|
||||||
my_socket fd; /* For Perl DBI/dbd */
|
my_socket fd; /* For Perl DBI/dbd */
|
||||||
@@ -324,7 +326,7 @@ extern unsigned long net_buffer_length;
|
|||||||
|
|
||||||
#define net_new_transaction(net) ((net)->pkt_nr=0)
|
#define net_new_transaction(net) ((net)->pkt_nr=0)
|
||||||
|
|
||||||
int my_net_init(NET *net, Vio *vio);
|
int my_net_init(NET *net, MARIADB_CIO *cio);
|
||||||
void net_end(NET *net);
|
void net_end(NET *net);
|
||||||
void net_clear(NET *net);
|
void net_clear(NET *net);
|
||||||
int net_flush(NET *net);
|
int net_flush(NET *net);
|
||||||
|
@@ -1,167 +0,0 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
MA 02111-1307, USA */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Vio Lite.
|
|
||||||
* Purpose: include file for Vio that will work with C and C++
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef vio_violite_h_
|
|
||||||
#define vio_violite_h_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "my_net.h" /* needed because of struct in_addr */
|
|
||||||
|
|
||||||
#ifdef HAVE_VIO
|
|
||||||
#include <Vio.h> /* Full VIO interface */
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum enum_vio_io_event
|
|
||||||
{
|
|
||||||
VIO_IO_EVENT_READ,
|
|
||||||
VIO_IO_EVENT_WRITE,
|
|
||||||
VIO_IO_EVENT_CONNECT
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Simple vio interface in C; The functions are implemented in violite.c */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#ifndef Vio_defined
|
|
||||||
#define Vio_defined
|
|
||||||
struct st_vio; /* Only C */
|
|
||||||
typedef struct st_vio Vio;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#define HANDLE void *
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* vio read-ahead cachine */
|
|
||||||
#define VIO_CACHE_SIZE 16384
|
|
||||||
#define VIO_CACHE_MIN_SIZE 2048
|
|
||||||
|
|
||||||
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
|
|
||||||
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
|
|
||||||
|
|
||||||
Vio* vio_new(my_socket sd,
|
|
||||||
enum enum_vio_type type,
|
|
||||||
my_bool localhost);
|
|
||||||
#ifdef _WIN32
|
|
||||||
Vio* vio_new_win32pipe(HANDLE hPipe);
|
|
||||||
#endif
|
|
||||||
void vio_delete(Vio* vio);
|
|
||||||
void vio_reset(Vio* vio, enum enum_vio_type type,
|
|
||||||
my_socket sd, HANDLE hPipe,
|
|
||||||
my_bool localhost);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* vio_read and vio_write should have the same semantics
|
|
||||||
* as read(2) and write(2).
|
|
||||||
*/
|
|
||||||
size_t vio_read(Vio* vio, gptr buf, size_t size);
|
|
||||||
my_bool vio_read_peek(Vio *vio, size_t *bytes);
|
|
||||||
size_t vio_write(Vio* vio, const gptr buf, size_t size);
|
|
||||||
/*
|
|
||||||
* Whenever the socket is set to blocking mode or not.
|
|
||||||
*/
|
|
||||||
int vio_blocking( Vio* vio,
|
|
||||||
my_bool onoff,
|
|
||||||
my_bool *prevmode);
|
|
||||||
my_bool vio_is_blocking( Vio* vio);
|
|
||||||
/*
|
|
||||||
* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
|
|
||||||
*/
|
|
||||||
int vio_fastsend( Vio* vio);
|
|
||||||
/*
|
|
||||||
* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
|
|
||||||
*/
|
|
||||||
int vio_keepalive( Vio* vio,
|
|
||||||
my_bool onoff);
|
|
||||||
/*
|
|
||||||
* Whenever we should retry the last read/write operation.
|
|
||||||
*/
|
|
||||||
my_bool vio_should_retry( Vio* vio);
|
|
||||||
/*
|
|
||||||
* When the workday is over...
|
|
||||||
*/
|
|
||||||
int vio_close( Vio* vio);
|
|
||||||
/*
|
|
||||||
* Short text description of the socket for those, who are curious..
|
|
||||||
*/
|
|
||||||
const char* vio_description( Vio* vio);
|
|
||||||
|
|
||||||
/* Return the type of the connection */
|
|
||||||
enum enum_vio_type vio_type(Vio* vio);
|
|
||||||
|
|
||||||
/* set timeout */
|
|
||||||
void vio_read_timeout(Vio *vio, uint seconds);
|
|
||||||
void vio_write_timeout(Vio *vio, uint seconds);
|
|
||||||
|
|
||||||
/* Return last error number */
|
|
||||||
int vio_errno(Vio *vio);
|
|
||||||
|
|
||||||
/* Get socket number */
|
|
||||||
my_socket vio_fd(Vio *vio);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remote peer's address and name in text form.
|
|
||||||
*/
|
|
||||||
my_bool vio_peer_addr(Vio * vio, char *buf);
|
|
||||||
|
|
||||||
/* Remotes in_addr */
|
|
||||||
|
|
||||||
void vio_in_addr(Vio *vio, struct in_addr *in);
|
|
||||||
|
|
||||||
/* Return 1 if there is data to be read */
|
|
||||||
my_bool vio_poll_read(Vio *vio,uint timeout);
|
|
||||||
int vio_wait_or_timeout(Vio *vio, my_bool is_read, int timeout);
|
|
||||||
|
|
||||||
|
|
||||||
struct st_vio
|
|
||||||
{
|
|
||||||
my_socket sd; /* my_socket - real or imaginary */
|
|
||||||
HANDLE hPipe;
|
|
||||||
my_bool localhost; /* Are we from localhost? */
|
|
||||||
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
|
|
||||||
struct sockaddr_in local; /* Local internet address */
|
|
||||||
struct sockaddr_in remote; /* Remote internet address */
|
|
||||||
struct mysql_async_context *async_context; /* For non-blocking API */
|
|
||||||
int write_timeout;
|
|
||||||
int read_timeout;
|
|
||||||
enum enum_vio_type type; /* Type of connection */
|
|
||||||
char desc[30]; /* String description */
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
SSL *ssl;
|
|
||||||
#endif
|
|
||||||
uchar *cache; /* read-ahead cache to reduce reads (see CONC-79) */
|
|
||||||
uchar *cache_pos; /* position of read-ahead cached data */
|
|
||||||
size_t cache_size; /* <= VIO_CACHE_SIZE */
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_VIO */
|
|
||||||
#endif /* vio_violite_h_ */
|
|
@@ -8,7 +8,9 @@ ADD_DEFINITIONS(-D LIBMARIADB)
|
|||||||
ADD_DEFINITIONS(-D THREAD)
|
ADD_DEFINITIONS(-D THREAD)
|
||||||
|
|
||||||
SET(EXPORT_SYMBOLS
|
SET(EXPORT_SYMBOLS
|
||||||
|
client_errors
|
||||||
load_defaults
|
load_defaults
|
||||||
|
ma_cio_register_callback
|
||||||
mariadb_connection
|
mariadb_connection
|
||||||
mariadb_convert_string
|
mariadb_convert_string
|
||||||
mariadb_deinitialize_ssl
|
mariadb_deinitialize_ssl
|
||||||
@@ -247,7 +249,8 @@ bmove.c
|
|||||||
bmove_upp.c
|
bmove_upp.c
|
||||||
my_charset.c
|
my_charset.c
|
||||||
hash.c
|
hash.c
|
||||||
violite.c
|
ma_cio.c
|
||||||
|
ma_ssl.c
|
||||||
net.c
|
net.c
|
||||||
charset.c
|
charset.c
|
||||||
ma_time.c
|
ma_time.c
|
||||||
@@ -321,10 +324,15 @@ my_stmt.c
|
|||||||
my_loaddata.c
|
my_loaddata.c
|
||||||
my_stmt_codec.c
|
my_stmt_codec.c
|
||||||
client_plugin.c
|
client_plugin.c
|
||||||
my_auth.c
|
# built in plugins
|
||||||
ma_secure.c
|
${CMAKE_SOURCE_DIR}/plugins/builtin/my_auth.c
|
||||||
|
${CMAKE_SOURCE_DIR}/plugins/builtin/cio_socket.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF(SSL_SOURCES)
|
||||||
|
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES} ${SSL_SOURCES})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/win-iconv)
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/win-iconv)
|
||||||
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES}
|
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES}
|
||||||
|
@@ -61,28 +61,12 @@ static MEM_ROOT mem_root;
|
|||||||
static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
|
static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
|
||||||
{
|
{
|
||||||
MYSQL_CLIENT_DB_PLUGIN_INTERFACE_VERSION, /* these two are taken by Connector/C */
|
MYSQL_CLIENT_DB_PLUGIN_INTERFACE_VERSION, /* these two are taken by Connector/C */
|
||||||
0, /* these two are taken by Connector/C */
|
MYSQL_CLIENT_CIO_PLUGIN_INTERFACE_VERSION, /* these two are taken by Connector/C */
|
||||||
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
|
MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
|
||||||
0,
|
MYSQL_CLIENT_TRACE_PLUGIN_INTERFACE_VERSION,
|
||||||
MYSQL_CLIENT_REMOTEIO_PLUGIN_INTERFACE_VERSION
|
MYSQL_CLIENT_REMOTEIO_PLUGIN_INTERFACE_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
|
|
||||||
extern auth_plugin_t old_password_client_plugin;
|
|
||||||
extern auth_plugin_t native_password_client_plugin;
|
|
||||||
|
|
||||||
/* built in plugins:
|
|
||||||
These plugins are part of Connector/C, so no need to
|
|
||||||
load them
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct st_mysql_client_plugin *mysql_client_builtins[]=
|
|
||||||
{
|
|
||||||
(struct st_mysql_client_plugin *)&old_password_client_plugin,
|
|
||||||
(struct st_mysql_client_plugin *)&native_password_client_plugin,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Loaded plugins are stored in a linked list.
|
Loaded plugins are stored in a linked list.
|
||||||
The list is append-only, the elements are added to the head (like in a stack).
|
The list is append-only, the elements are added to the head (like in a stack).
|
||||||
@@ -96,6 +80,26 @@ struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS];
|
|||||||
static pthread_mutex_t LOCK_load_client_plugin;
|
static pthread_mutex_t LOCK_load_client_plugin;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern struct st_mysql_client_plugin old_password_client_plugin;
|
||||||
|
extern struct st_mysql_client_plugin native_password_client_plugin;
|
||||||
|
|
||||||
|
extern MARIADB_CIO_PLUGIN cio_socket_plugin;
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
extern MARIADB_CIO_PLUGIN SSL_PLUGIN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct st_mysql_client_plugin *mysql_client_builtins[]=
|
||||||
|
{
|
||||||
|
(struct st_mysql_client_plugin *)&old_password_client_plugin,
|
||||||
|
(struct st_mysql_client_plugin *)&native_password_client_plugin,
|
||||||
|
(struct st_mysql_client_plugin *)&cio_socket_plugin,
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
(struct st_mysql_client_plugin *)&SSL_PLUGIN,
|
||||||
|
#endif
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int is_not_initialized(MYSQL *mysql, const char *name)
|
static int is_not_initialized(MYSQL *mysql, const char *name)
|
||||||
{
|
{
|
||||||
if (initialized)
|
if (initialized)
|
||||||
@@ -103,7 +107,7 @@ static int is_not_initialized(MYSQL *mysql, const char *name)
|
|||||||
|
|
||||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
|
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
|
||||||
SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
|
SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
|
||||||
name ? name : "unknown" , "not initialized");
|
name, "not initialized");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +134,12 @@ static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
|
|||||||
|
|
||||||
for (p= plugin_list[type]; p; p= p->next)
|
for (p= plugin_list[type]; p; p= p->next)
|
||||||
{
|
{
|
||||||
if (!name)
|
if (name)
|
||||||
return p->plugin;
|
{
|
||||||
if (strcmp(p->plugin->name, name) == 0)
|
if (strcmp(p->plugin->name, name) == 0)
|
||||||
|
return p->plugin;
|
||||||
|
}
|
||||||
|
else if (p->plugin->type == type)
|
||||||
return p->plugin;
|
return p->plugin;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -207,10 +214,10 @@ err2:
|
|||||||
if (plugin->deinit)
|
if (plugin->deinit)
|
||||||
plugin->deinit();
|
plugin->deinit();
|
||||||
err1:
|
err1:
|
||||||
if (dlhandle)
|
|
||||||
(void)dlclose(dlhandle);
|
|
||||||
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
|
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
|
||||||
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name, errmsg);
|
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name, errmsg);
|
||||||
|
if (dlhandle)
|
||||||
|
(void)dlclose(dlhandle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +289,6 @@ int mysql_client_plugin_init()
|
|||||||
initialized= 1;
|
initialized= 1;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_load_client_plugin);
|
pthread_mutex_lock(&LOCK_load_client_plugin);
|
||||||
|
|
||||||
for (builtin= mysql_client_builtins; *builtin; builtin++)
|
for (builtin= mysql_client_builtins; *builtin; builtin++)
|
||||||
add_plugin(&mysql, *builtin, 0, 0, unused);
|
add_plugin(&mysql, *builtin, 0, 0, unused);
|
||||||
|
|
||||||
@@ -386,7 +392,7 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
|
|||||||
mysql->options.extension->plugin_dir : (env_plugin_dir) ? env_plugin_dir :
|
mysql->options.extension->plugin_dir : (env_plugin_dir) ? env_plugin_dir :
|
||||||
PLUGINDIR, "/",
|
PLUGINDIR, "/",
|
||||||
name, SO_EXT, NullS);
|
name, SO_EXT, NullS);
|
||||||
|
|
||||||
/* Open new dll handle */
|
/* Open new dll handle */
|
||||||
if (!(dlhandle= dlopen((const char *)dlpath, RTLD_NOW)))
|
if (!(dlhandle= dlopen((const char *)dlpath, RTLD_NOW)))
|
||||||
{
|
{
|
||||||
@@ -403,7 +409,8 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
|
|
||||||
|
if (!(sym= (int *)dlsym(dlhandle, plugin_declarations_sym)))
|
||||||
{
|
{
|
||||||
errmsg= "not a plugin";
|
errmsg= "not a plugin";
|
||||||
(void)dlclose(dlhandle);
|
(void)dlclose(dlhandle);
|
||||||
|
@@ -55,25 +55,25 @@ const char *client_errors[]=
|
|||||||
const char *client_errors[]=
|
const char *client_errors[]=
|
||||||
{
|
{
|
||||||
"Erro desconhecido do MySQL",
|
"Erro desconhecido do MySQL",
|
||||||
"N<EFBFBD>o pode criar 'UNIX socket' (%d)",
|
"N<EFBFBD>o pode criar 'UNIX socket' (%d)",
|
||||||
"N<EFBFBD>o pode se conectar ao servidor MySQL local atrav<61>s do 'socket' '%-.64s' (%d)",
|
"N<EFBFBD>o pode se conectar ao servidor MySQL local atrav<61>s do 'socket' '%-.64s' (%d)",
|
||||||
"N<EFBFBD>o pode se conectar ao servidor MySQL em '%-.64s' (%d)",
|
"N<EFBFBD>o pode se conectar ao servidor MySQL em '%-.64s' (%d)",
|
||||||
"N<EFBFBD>o pode criar 'socket TCP/IP' (%d)",
|
"N<EFBFBD>o pode criar 'socket TCP/IP' (%d)",
|
||||||
"'Host' servidor MySQL '%-.64s' (%d) desconhecido",
|
"'Host' servidor MySQL '%-.64s' (%d) desconhecido",
|
||||||
"Servidor MySQL desapareceu",
|
"Servidor MySQL desapareceu",
|
||||||
"Incompatibilidade de protocolos. Vers<72>o do Servidor: %d - Vers<72>o do Cliente: %d",
|
"Incompatibilidade de protocolos. Vers<72>o do Servidor: %d - Vers<72>o do Cliente: %d",
|
||||||
"Cliente do MySQL com falta de mem<65>ria",
|
"Cliente do MySQL com falta de mem<65>ria",
|
||||||
"Informa<EFBFBD><EFBFBD>o inv<6E>lida de 'host'",
|
"Informa<EFBFBD><EFBFBD>o inv<6E>lida de 'host'",
|
||||||
"Localhost via 'UNIX socket'",
|
"Localhost via 'UNIX socket'",
|
||||||
"%-.64s via 'TCP/IP'",
|
"%-.64s via 'TCP/IP'",
|
||||||
"Erro na negocia<69><61>o de acesso ao servidor",
|
"Erro na negocia<69><61>o de acesso ao servidor",
|
||||||
"Conex<EFBFBD>o perdida com servidor MySQL durante 'query'",
|
"Conex<EFBFBD>o perdida com servidor MySQL durante 'query'",
|
||||||
"Comandos fora de sincronismo. Voc<6F> n<>o pode executar este comando agora",
|
"Comandos fora de sincronismo. Voc<6F> n<>o pode executar este comando agora",
|
||||||
"%-.64s via 'named pipe'",
|
"%-.64s via 'named pipe'",
|
||||||
"N<EFBFBD>o pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
"N<EFBFBD>o pode esperar pelo 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
"N<EFBFBD>o pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
"N<EFBFBD>o pode abrir 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
"N<EFBFBD>o pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
"N<EFBFBD>o pode estabelecer o estado do 'named pipe' para o 'host' %-.64s - 'pipe' %-.32s (%lu)",
|
||||||
"N<EFBFBD>o pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
|
"N<EFBFBD>o pode inicializar conjunto de caracteres %-.64s (caminho %-.64s)",
|
||||||
"Obteve pacote maior do que 'max_allowed_packet'"
|
"Obteve pacote maior do que 'max_allowed_packet'"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ const char *client_errors[]=
|
|||||||
/* 2034 */ "",
|
/* 2034 */ "",
|
||||||
/* 2035 */ "",
|
/* 2035 */ "",
|
||||||
/* 2036 */ "Buffer type is not supported",
|
/* 2036 */ "Buffer type is not supported",
|
||||||
/* 2037 */ "",
|
/* 2037 */ "Shared memory: %-.64s",
|
||||||
/* 2038 */ "",
|
/* 2038 */ "Shared memory connection failed during %s. (%lu)",
|
||||||
/* 2039 */ "",
|
/* 2039 */ "",
|
||||||
/* 2040 */ "",
|
/* 2040 */ "",
|
||||||
/* 2041 */ "",
|
/* 2041 */ "",
|
||||||
@@ -145,6 +145,12 @@ const char *client_errors[]=
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char *mariadb_client_errors[] =
|
||||||
|
{
|
||||||
|
/* 5000 */ "Creating an event failed (Errorcode: %d)",
|
||||||
|
/* 5001 */ "Bind to local interface '-.%64s' failed (Errorcode: %d)",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
void init_client_errs(void)
|
void init_client_errs(void)
|
||||||
{
|
{
|
||||||
|
@@ -62,15 +62,11 @@
|
|||||||
#define INADDR_NONE -1
|
#define INADDR_NONE -1
|
||||||
#endif
|
#endif
|
||||||
#include <sha1.h>
|
#include <sha1.h>
|
||||||
#include <violite.h>
|
#include <ma_cio.h>
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
#include <ma_secure.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <ma_dyncol.h>
|
#include <ma_dyncol.h>
|
||||||
#include <mysql_async.h>
|
|
||||||
|
|
||||||
#define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (4096*15)
|
#define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (4096*15)
|
||||||
|
|
||||||
@@ -91,6 +87,8 @@ extern const CHARSET_INFO * mysql_find_charset_name(const char * const name);
|
|||||||
extern int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
|
extern int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
|
||||||
const char *data_plugin, const char *db);
|
const char *data_plugin, const char *db);
|
||||||
|
|
||||||
|
extern LIST *cio_callback;
|
||||||
|
|
||||||
/* prepare statement methods from my_stmt.c */
|
/* prepare statement methods from my_stmt.c */
|
||||||
extern my_bool mthd_supported_buffer_type(enum enum_field_types type);
|
extern my_bool mthd_supported_buffer_type(enum enum_field_types type);
|
||||||
extern my_bool mthd_stmt_read_prepare_response(MYSQL_STMT *stmt);
|
extern my_bool mthd_stmt_read_prepare_response(MYSQL_STMT *stmt);
|
||||||
@@ -130,216 +128,11 @@ static void mysql_close_memory(MYSQL *mysql);
|
|||||||
void read_user_name(char *name);
|
void read_user_name(char *name);
|
||||||
static void append_wild(char *to,char *end,const char *wild);
|
static void append_wild(char *to,char *end,const char *wild);
|
||||||
static my_bool mysql_reconnect(MYSQL *mysql);
|
static my_bool mysql_reconnect(MYSQL *mysql);
|
||||||
static sig_handler pipe_sig_handler(int sig);
|
|
||||||
static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
|
static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
|
||||||
|
|
||||||
extern int mysql_client_plugin_init();
|
extern int mysql_client_plugin_init();
|
||||||
extern void mysql_client_plugin_deinit();
|
extern void mysql_client_plugin_deinit();
|
||||||
|
|
||||||
/*
|
|
||||||
Let the user specify that we don't want SIGPIPE; This doesn't however work
|
|
||||||
with threaded applications as we can have multiple read in progress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_WIN32) && defined(SIGPIPE) && !defined(THREAD)
|
|
||||||
#define init_sigpipe_variables sig_return old_signal_handler=(sig_return) 0;
|
|
||||||
#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE,pipe_sig_handler)
|
|
||||||
#define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler);
|
|
||||||
#else
|
|
||||||
#define init_sigpipe_variables
|
|
||||||
#define set_sigpipe(mysql)
|
|
||||||
#define reset_sigpipe(mysql)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* A modified version of connect(). connect2() allows you to specify
|
|
||||||
* a timeout value, in seconds, that we should wait until we
|
|
||||||
* derermine we can't connect to a particular host. If timeout is 0,
|
|
||||||
* connect2() will behave exactly like connect().
|
|
||||||
*
|
|
||||||
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
int socket_block(my_socket s,my_bool blocked)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
unsigned long socket_blocked= blocked ? 0 : 1;
|
|
||||||
return ioctlsocket(s, FIONBIO, &socket_blocked);
|
|
||||||
#else
|
|
||||||
int flags= fcntl(s, F_GETFL, 0);
|
|
||||||
if (blocked)
|
|
||||||
flags&= ~O_NONBLOCK;
|
|
||||||
else
|
|
||||||
flags|= O_NONBLOCK;
|
|
||||||
return fcntl(s, F_SETFL, flags);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int connect2(my_socket s, const struct sockaddr *name, size_t namelen,
|
|
||||||
uint timeout)
|
|
||||||
{
|
|
||||||
int res, s_err;
|
|
||||||
socklen_t s_err_size = sizeof(uint);
|
|
||||||
#ifndef _WIN32
|
|
||||||
struct pollfd poll_fd;
|
|
||||||
#else
|
|
||||||
FD_SET sfds, efds;
|
|
||||||
struct timeval tv;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!timeout)
|
|
||||||
return connect(s, (struct sockaddr*) name, (int)namelen);
|
|
||||||
|
|
||||||
/* set socket to non blocking */
|
|
||||||
if (socket_block(s, 0) == SOCKET_ERROR)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
res= connect(s, (struct sockaddr*) name, (int)namelen);
|
|
||||||
if (res == 0)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (GetLastError() != WSAEWOULDBLOCK &&
|
|
||||||
GetLastError() != WSAEINPROGRESS)
|
|
||||||
#else
|
|
||||||
if (errno != EINPROGRESS)
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
#ifndef _WIN32
|
|
||||||
memset(&poll_fd, 0, sizeof(struct pollfd));
|
|
||||||
poll_fd.events= POLLOUT | POLLERR;
|
|
||||||
poll_fd.fd= s;
|
|
||||||
|
|
||||||
/* connection timeout in milliseconds */
|
|
||||||
res= poll(&poll_fd, 1, timeout);
|
|
||||||
|
|
||||||
switch(res)
|
|
||||||
{
|
|
||||||
/* Error= - 1, timeout = 0 */
|
|
||||||
case -1:
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
errno= ETIMEDOUT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
FD_ZERO(&sfds);
|
|
||||||
FD_ZERO(&efds);
|
|
||||||
FD_SET(s, &sfds);
|
|
||||||
FD_SET(s, &efds);
|
|
||||||
|
|
||||||
memset(&tv, 0, sizeof(struct timeval));
|
|
||||||
tv.tv_sec= timeout;
|
|
||||||
|
|
||||||
res= select((int)s+1, NULL, &sfds, &efds, &tv);
|
|
||||||
if (res < 1)
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_err=0;
|
|
||||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
if (s_err)
|
|
||||||
{ /* getsockopt could succeed */
|
|
||||||
errno = s_err;
|
|
||||||
return(-1); /* but return an error... */
|
|
||||||
}
|
|
||||||
return (0); /* ok */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
connect_sync_or_async(MYSQL *mysql, NET *net, my_socket fd,
|
|
||||||
const struct sockaddr *name, uint namelen)
|
|
||||||
{
|
|
||||||
int vio_timeout= (mysql->options.connect_timeout >= 0) ?
|
|
||||||
mysql->options.connect_timeout * 1000 : -1;
|
|
||||||
|
|
||||||
if (mysql->options.extension && mysql->options.extension->async_context &&
|
|
||||||
mysql->options.extension->async_context->active)
|
|
||||||
{
|
|
||||||
my_bool old_mode;
|
|
||||||
vio_blocking(net->vio, FALSE, &old_mode);
|
|
||||||
return my_connect_async(mysql->options.extension->async_context, fd,
|
|
||||||
name, namelen, vio_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return connect2(fd, name, namelen, vio_timeout);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** Create a named pipe connection
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
|
|
||||||
char **arg_unix_socket)
|
|
||||||
{
|
|
||||||
HANDLE hPipe=INVALID_HANDLE_VALUE;
|
|
||||||
char szPipeName [ 257 ];
|
|
||||||
DWORD dwMode;
|
|
||||||
int i;
|
|
||||||
my_bool testing_named_pipes=0;
|
|
||||||
char *host= *arg_host, *unix_socket= *arg_unix_socket;
|
|
||||||
|
|
||||||
if ( ! unix_socket || (unix_socket)[0] == 0x00)
|
|
||||||
unix_socket = mysql_unix_port;
|
|
||||||
if (!host || !strcmp(host,LOCAL_HOST))
|
|
||||||
host=LOCAL_HOST_NAMEDPIPE;
|
|
||||||
|
|
||||||
sprintf( szPipeName, "\\\\%s\\pipe\\%s", host, unix_socket);
|
|
||||||
DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s",
|
|
||||||
host, unix_socket));
|
|
||||||
|
|
||||||
for (i=0 ; i < 100 ; i++) /* Don't retry forever */
|
|
||||||
{
|
|
||||||
if ((hPipe = CreateFile(szPipeName,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
0,
|
|
||||||
NULL )) != INVALID_HANDLE_VALUE)
|
|
||||||
break;
|
|
||||||
if (GetLastError() != ERROR_PIPE_BUSY)
|
|
||||||
{
|
|
||||||
net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
|
|
||||||
sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
|
|
||||||
(ulong) GetLastError());
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
/* wait for for an other instance */
|
|
||||||
if (! WaitNamedPipe(szPipeName, connect_timeout) )
|
|
||||||
{
|
|
||||||
net->last_errno=CR_NAMEDPIPEWAIT_ERROR;
|
|
||||||
sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
|
|
||||||
(ulong) GetLastError());
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
|
|
||||||
sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
|
|
||||||
(ulong) GetLastError());
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
|
|
||||||
if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
|
|
||||||
{
|
|
||||||
CloseHandle( hPipe );
|
|
||||||
net->last_errno=CR_NAMEDPIPESETSTATE_ERROR;
|
|
||||||
sprintf(net->last_error,ER(net->last_errno),host, unix_socket,
|
|
||||||
(ulong) GetLastError());
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
*arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */
|
|
||||||
return (hPipe);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* net_get_error */
|
/* net_get_error */
|
||||||
void net_get_error(char *buf, size_t buf_len,
|
void net_get_error(char *buf, size_t buf_len,
|
||||||
char *error, size_t error_len,
|
char *error, size_t error_len,
|
||||||
@@ -382,14 +175,10 @@ net_safe_read(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
ulong len=0;
|
ulong len=0;
|
||||||
init_sigpipe_variables
|
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
/* Don't give sigpipe errors if the client doesn't want them */
|
if (net->cio != 0)
|
||||||
set_sigpipe(mysql);
|
|
||||||
if (net->vio != 0)
|
|
||||||
len=my_net_read(net);
|
len=my_net_read(net);
|
||||||
reset_sigpipe(mysql);
|
|
||||||
|
|
||||||
if (len == packet_error || len == 0)
|
if (len == packet_error || len == 0)
|
||||||
{
|
{
|
||||||
@@ -560,15 +349,12 @@ mthd_my_send_cmd(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
|||||||
{
|
{
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
int result= -1;
|
int result= -1;
|
||||||
init_sigpipe_variables
|
|
||||||
|
|
||||||
DBUG_ENTER("mthd_my_send_command");
|
DBUG_ENTER("mthd_my_send_command");
|
||||||
|
|
||||||
DBUG_PRINT("info", ("server_command: %d packet_size: %u", command, length));
|
DBUG_PRINT("info", ("server_command: %d packet_size: %u", command, length));
|
||||||
|
|
||||||
/* Don't give sigpipe errors if the client doesn't want them */
|
if (mysql->net.cio == 0)
|
||||||
set_sigpipe(mysql);
|
|
||||||
if (mysql->net.vio == 0)
|
|
||||||
{ /* Do reconnect if possible */
|
{ /* Do reconnect if possible */
|
||||||
if (mysql_reconnect(mysql))
|
if (mysql_reconnect(mysql))
|
||||||
{
|
{
|
||||||
@@ -617,7 +403,6 @@ mthd_my_send_cmd(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
|||||||
DBUG_PRINT("info", ("packet_length=%llu", mysql->packet_length));
|
DBUG_PRINT("info", ("packet_length=%llu", mysql->packet_length));
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
reset_sigpipe(mysql);
|
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,13 +567,10 @@ static void
|
|||||||
end_server(MYSQL *mysql)
|
end_server(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("end_server");
|
DBUG_ENTER("end_server");
|
||||||
if (mysql->net.vio != 0)
|
if (mysql->net.cio != 0)
|
||||||
{
|
{
|
||||||
init_sigpipe_variables
|
ma_cio_close(mysql->net.cio);
|
||||||
set_sigpipe(mysql);
|
mysql->net.cio= 0; /* Marker */
|
||||||
vio_delete(mysql->net.vio);
|
|
||||||
reset_sigpipe(mysql);
|
|
||||||
mysql->net.vio= 0; /* Marker */
|
|
||||||
}
|
}
|
||||||
net_end(&mysql->net);
|
net_end(&mysql->net);
|
||||||
free_old_query(mysql);
|
free_old_query(mysql);
|
||||||
@@ -845,7 +627,7 @@ static const char *default_options[]=
|
|||||||
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
|
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
|
||||||
"multi-results", "multi-statements", "multi-queries", "secure-auth",
|
"multi-results", "multi-statements", "multi-queries", "secure-auth",
|
||||||
"report-data-truncation", "plugin-dir", "default-auth", "database-type",
|
"report-data-truncation", "plugin-dir", "default-auth", "database-type",
|
||||||
"ssl-fp", "ssl-fp-list",
|
"ssl-fp", "ssl-fp-list", "bind-address",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -860,7 +642,7 @@ enum option_val
|
|||||||
OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
|
OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
|
||||||
OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
|
OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
|
||||||
OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, OPT_db_type,
|
OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth, OPT_db_type,
|
||||||
OPT_ssl_fp, OPT_ssl_fp_list
|
OPT_ssl_fp, OPT_ssl_fp_list, OPT_bind_address
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHECK_OPT_EXTENSION_SET(OPTS)\
|
#define CHECK_OPT_EXTENSION_SET(OPTS)\
|
||||||
@@ -869,13 +651,15 @@ enum option_val
|
|||||||
my_malloc(sizeof(struct st_mysql_options_extension), \
|
my_malloc(sizeof(struct st_mysql_options_extension), \
|
||||||
MYF(MY_WME | MY_ZEROFILL)); \
|
MYF(MY_WME | MY_ZEROFILL)); \
|
||||||
|
|
||||||
#define OPT_SET_EXTENDED_VALUE(OPTS, KEY, VAL, IS_STRING) \
|
#define OPT_SET_EXTENDED_VALUE_STR(OPTS, KEY, VAL) \
|
||||||
CHECK_OPT_EXTENSION_SET(OPTS) \
|
CHECK_OPT_EXTENSION_SET(OPTS) \
|
||||||
if (IS_STRING) { \
|
my_free((gptr)(OPTS)->extension->KEY);\
|
||||||
my_free((OPTS)->extension->KEY); \
|
(OPTS)->extension->KEY= my_strdup((char *)(VAL), MYF(MY_WME))
|
||||||
(OPTS)->extension->KEY= my_strdup((char *)(VAL), MYF(MY_WME)); \
|
|
||||||
} else \
|
#define OPT_SET_EXTENDED_VALUE_INT(OPTS, KEY, VAL) \
|
||||||
(OPTS)->extension->KEY= (VAL);
|
CHECK_OPT_EXTENSION_SET(OPTS) \
|
||||||
|
+ (OPTS)->extension->KEY= (VAL)
|
||||||
|
|
||||||
|
|
||||||
static TYPELIB option_types={array_elements(default_options)-1,
|
static TYPELIB option_types={array_elements(default_options)-1,
|
||||||
"options",default_options};
|
"options",default_options};
|
||||||
@@ -993,7 +777,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
case OPT_return_found_rows:
|
case OPT_return_found_rows:
|
||||||
options->client_flag|=CLIENT_FOUND_ROWS;
|
options->client_flag|=CLIENT_FOUND_ROWS;
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_SSL
|
||||||
case OPT_ssl_key:
|
case OPT_ssl_key:
|
||||||
my_free(options->ssl_key);
|
my_free(options->ssl_key);
|
||||||
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
|
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
|
||||||
@@ -1013,10 +797,10 @@ static void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
case OPT_ssl_cipher:
|
case OPT_ssl_cipher:
|
||||||
break;
|
break;
|
||||||
case OPT_ssl_fp:
|
case OPT_ssl_fp:
|
||||||
OPT_SET_EXTENDED_VALUE(options, ssl_fp, opt_arg, 1);
|
OPT_SET_EXTENDED_VALUE_STR(options, ssl_fp, opt_arg);
|
||||||
break;
|
break;
|
||||||
case OPT_ssl_fp_list:
|
case OPT_ssl_fp_list:
|
||||||
OPT_SET_EXTENDED_VALUE(options, ssl_fp_list, opt_arg, 1);
|
OPT_SET_EXTENDED_VALUE_STR(options, ssl_fp_list, opt_arg);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case OPT_ssl_key:
|
case OPT_ssl_key:
|
||||||
@@ -1027,7 +811,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
case OPT_ssl_fp:
|
case OPT_ssl_fp:
|
||||||
case OPT_ssl_fp_list:
|
case OPT_ssl_fp_list:
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_SSL */
|
||||||
case OPT_charset_dir:
|
case OPT_charset_dir:
|
||||||
my_free(options->charset_dir);
|
my_free(options->charset_dir);
|
||||||
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
|
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
|
||||||
@@ -1088,12 +872,16 @@ static void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
if (strlen(opt_arg) >= FN_REFLEN)
|
if (strlen(opt_arg) >= FN_REFLEN)
|
||||||
opt_arg[FN_REFLEN]= 0;
|
opt_arg[FN_REFLEN]= 0;
|
||||||
if (!my_realpath(directory, opt_arg, 0))
|
if (!my_realpath(directory, opt_arg, 0))
|
||||||
OPT_SET_EXTENDED_VALUE(options, plugin_dir, convert_dirname(directory), 1);
|
OPT_SET_EXTENDED_VALUE_STR(options, plugin_dir, convert_dirname(directory));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_default_auth:
|
case OPT_default_auth:
|
||||||
OPT_SET_EXTENDED_VALUE(options, default_auth, opt_arg, 1);
|
OPT_SET_EXTENDED_VALUE_STR(options, default_auth, opt_arg);
|
||||||
break;
|
break;
|
||||||
|
case OPT_bind_address:
|
||||||
|
my_free(options->bind_address);
|
||||||
|
options->bind_address= my_strdup(opt_arg, MYF(MY_WME));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_PRINT("warning",("unknown option: %s",option[0]));
|
DBUG_PRINT("warning",("unknown option: %s",option[0]));
|
||||||
}
|
}
|
||||||
@@ -1346,7 +1134,7 @@ mysql_init(MYSQL *mysql)
|
|||||||
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
|
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
|
||||||
return 0;
|
return 0;
|
||||||
mysql->free_me=1;
|
mysql->free_me=1;
|
||||||
mysql->net.vio= 0;
|
mysql->net.cio= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bzero((char*) (mysql),sizeof(*(mysql)));
|
bzero((char*) (mysql),sizeof(*(mysql)));
|
||||||
@@ -1391,10 +1179,10 @@ mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert,
|
|||||||
const char * STDCALL
|
const char * STDCALL
|
||||||
mysql_get_ssl_cipher(MYSQL *mysql)
|
mysql_get_ssl_cipher(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_SSL
|
||||||
if (mysql->net.vio && mysql->net.vio->ssl)
|
if (mysql->net.cio && mysql->net.cio->cssl)
|
||||||
{
|
{
|
||||||
return SSL_get_cipher_name(mysql->net.vio->ssl);
|
return ma_cio_ssl_cipher(mysql->net.cio->cssl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@@ -1516,18 +1304,12 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
char buff[NAME_LEN+USERNAME_LENGTH+100];
|
char buff[NAME_LEN+USERNAME_LENGTH+100];
|
||||||
char *end, *end_pkt, *host_info,
|
char *end, *end_pkt, *host_info,
|
||||||
*charset_name= NULL;
|
*charset_name= NULL;
|
||||||
my_socket sock;
|
MA_CIO_CINFO cinfo= {NULL, NULL, 0, -1, NULL};
|
||||||
|
MARIADB_CIO *cio= NULL;
|
||||||
char *scramble_data;
|
char *scramble_data;
|
||||||
const char *scramble_plugin;
|
const char *scramble_plugin;
|
||||||
uint pkt_length, scramble_len, pkt_scramble_len= 0;
|
uint pkt_length, scramble_len, pkt_scramble_len= 0;
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE hPipe=INVALID_HANDLE_VALUE;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
|
||||||
struct sockaddr_un UNIXaddr;
|
|
||||||
#endif
|
|
||||||
init_sigpipe_variables
|
|
||||||
DBUG_ENTER("mysql_real_connect");
|
DBUG_ENTER("mysql_real_connect");
|
||||||
|
|
||||||
DBUG_PRINT("enter",("host: %s db: %s user: %s",
|
DBUG_PRINT("enter",("host: %s db: %s user: %s",
|
||||||
@@ -1537,15 +1319,12 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
|
|
||||||
ma_set_connect_attrs(mysql);
|
ma_set_connect_attrs(mysql);
|
||||||
|
|
||||||
if (net->vio) /* check if we are already connected */
|
if (net->cio) /* check if we are already connected */
|
||||||
{
|
{
|
||||||
SET_CLIENT_ERROR(mysql, CR_ALREADY_CONNECTED, SQLSTATE_UNKNOWN, 0);
|
SET_CLIENT_ERROR(mysql, CR_ALREADY_CONNECTED, SQLSTATE_UNKNOWN, 0);
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't give sigpipe errors if the client doesn't want them */
|
|
||||||
set_sigpipe(mysql);
|
|
||||||
|
|
||||||
/* use default options */
|
/* use default options */
|
||||||
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
|
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
|
||||||
{
|
{
|
||||||
@@ -1583,192 +1362,75 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
mysql->reconnect=1; */
|
mysql->reconnect=1; */
|
||||||
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
|
||||||
|
|
||||||
|
/* try to connect via cio_init */
|
||||||
|
cinfo.host= host;
|
||||||
|
cinfo.unix_socket= unix_socket;
|
||||||
|
cinfo.port= port;
|
||||||
|
cinfo.mysql= mysql;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Grab a socket and connect it to the server
|
** Grab a socket and connect it to the server
|
||||||
*/
|
*/
|
||||||
|
#ifndef _WIN32
|
||||||
#if defined(HAVE_SYS_UN_H)
|
#if defined(HAVE_SYS_UN_H)
|
||||||
if ((!host || strcmp(host,LOCAL_HOST) == 0) &&
|
if ((!host || strcmp(host,LOCAL_HOST) == 0) &&
|
||||||
mysql->options.protocol != MYSQL_PROTOCOL_TCP &&
|
mysql->options.protocol != MYSQL_PROTOCOL_TCP &&
|
||||||
(unix_socket || mysql_unix_port))
|
(unix_socket || mysql_unix_port))
|
||||||
{
|
{
|
||||||
host=LOCAL_HOST;
|
cinfo.host= LOCAL_HOST;
|
||||||
if (!unix_socket)
|
cinfo.unix_socket= (unix_socket) ? unix_socket : mysql_unix_port;
|
||||||
unix_socket=mysql_unix_port;
|
cinfo.type= CIO_TYPE_UNIXSOCKET;
|
||||||
host_info=(char*) ER(CR_LOCALHOST_CONNECTION);
|
sprintf(host_info=buff,ER(CR_LOCALHOST_CONNECTION),cinfo.host);
|
||||||
DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
|
|
||||||
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
net->last_errno=CR_SOCKET_CREATE_ERROR;
|
|
||||||
sprintf(net->last_error,ER(net->last_errno),socket_errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE);
|
|
||||||
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
|
|
||||||
UNIXaddr.sun_family = AF_UNIX;
|
|
||||||
strmov(UNIXaddr.sun_path, unix_socket);
|
|
||||||
if (connect_sync_or_async(mysql, net, sock,
|
|
||||||
(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr)))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno));
|
|
||||||
my_set_error(mysql, CR_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_CONNECTION_ERROR),
|
|
||||||
unix_socket, socket_errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (socket_block(sock, 1) == SOCKET_ERROR)
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#elif defined(_WIN32)
|
#endif
|
||||||
|
#else
|
||||||
|
/* named pipe */
|
||||||
|
if ((unix_socket ||
|
||||||
|
(!host && is_NT()) ||
|
||||||
|
(host && strcmp(host,LOCAL_HOST_NAMEDPIPE) == 0) ||
|
||||||
|
mysql->options.named_pipe ||
|
||||||
|
!have_tcpip) &&
|
||||||
|
mysql->options.protocol != MYSQL_PROTOCOL_TCP)
|
||||||
{
|
{
|
||||||
if ((unix_socket ||
|
cinfo.type= CIO_TYPE_NAMEDPIPE;
|
||||||
(!host && is_NT()) ||
|
sprintf(host_info=buff,ER(CR_NAMEDPIPE_CONNECTION),cinfo.host);
|
||||||
(host && strcmp(host,LOCAL_HOST_NAMEDPIPE) == 0) ||
|
|
||||||
mysql->options.named_pipe ||
|
|
||||||
!have_tcpip) &&
|
|
||||||
mysql->options.protocol != MYSQL_PROTOCOL_TCP)
|
|
||||||
{
|
|
||||||
sock=0;
|
|
||||||
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout,
|
|
||||||
(char**) &host, (char**) &unix_socket)) ==
|
|
||||||
INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error",
|
|
||||||
("host: '%s' socket: '%s' named_pipe: %d have_tcpip: %d",
|
|
||||||
host ? host : "<null>",
|
|
||||||
unix_socket ? unix_socket : "<null>",
|
|
||||||
(int) mysql->options.named_pipe,
|
|
||||||
(int) have_tcpip));
|
|
||||||
if (mysql->options.named_pipe ||
|
|
||||||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
|
|
||||||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
|
|
||||||
goto error; /* User only requested named pipes */
|
|
||||||
/* Try also with TCP/IP */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
net->vio=vio_new_win32pipe(hPipe);
|
|
||||||
sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
|
|
||||||
unix_socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (hPipe == INVALID_HANDLE_VALUE)
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
struct addrinfo hints, *save_res= 0, *res= 0;
|
cinfo.unix_socket=0; /* This is not used */
|
||||||
char server_port[NI_MAXSERV];
|
|
||||||
int gai_rc;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
unix_socket=0; /* This is not used */
|
|
||||||
if (!port)
|
if (!port)
|
||||||
port=mysql_port;
|
port=mysql_port;
|
||||||
if (!host)
|
if (!host)
|
||||||
host=LOCAL_HOST;
|
host=LOCAL_HOST;
|
||||||
sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host);
|
cinfo.host= host;
|
||||||
bzero(&server_port, NI_MAXSERV);
|
cinfo.port= port;
|
||||||
|
cinfo.type= CIO_TYPE_SOCKET;
|
||||||
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port));
|
sprintf(host_info=buff,ER(CR_TCP_CONNECTION), cinfo.host);
|
||||||
|
|
||||||
my_snprintf(server_port, NI_MAXSERV, "%d", port);
|
|
||||||
|
|
||||||
/* set hints for getaddrinfo */
|
|
||||||
bzero(&hints, sizeof(hints));
|
|
||||||
hints.ai_protocol= IPPROTO_TCP; /* TCP connections only */
|
|
||||||
hints.ai_family= AF_UNSPEC; /* includes: IPv4, IPv6 or hostname */
|
|
||||||
hints.ai_socktype= SOCK_STREAM;
|
|
||||||
|
|
||||||
/* Get the address information for the server using getaddrinfo() */
|
|
||||||
gai_rc= getaddrinfo(host, server_port, &hints, &res);
|
|
||||||
if (gai_rc != 0)
|
|
||||||
{
|
|
||||||
my_set_error(mysql, CR_UNKNOWN_HOST, SQLSTATE_UNKNOWN,
|
|
||||||
ER(CR_UNKNOWN_HOST), host, gai_rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* res is a linked list of addresses. If connect to an address fails we will not return
|
|
||||||
an error, instead we will try the next address */
|
|
||||||
for (save_res= res; save_res; save_res= save_res->ai_next)
|
|
||||||
{
|
|
||||||
sock= socket(save_res->ai_family, save_res->ai_socktype,
|
|
||||||
save_res->ai_protocol);
|
|
||||||
if (sock == SOCKET_ERROR)
|
|
||||||
/* we do error handling after for loop only for last call */
|
|
||||||
continue;
|
|
||||||
if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, FALSE)))
|
|
||||||
{
|
|
||||||
my_set_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
|
||||||
closesocket(sock);
|
|
||||||
freeaddrinfo(res);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rc= connect_sync_or_async(mysql, net, sock,
|
|
||||||
save_res->ai_addr, save_res->ai_addrlen);
|
|
||||||
if (!rc)
|
|
||||||
{
|
|
||||||
if (mysql->options.extension && mysql->options.extension->async_context &&
|
|
||||||
mysql->options.extension->async_context->active)
|
|
||||||
break;
|
|
||||||
else if (socket_block(sock, 1) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
closesocket(sock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break; /* success! */
|
|
||||||
}
|
|
||||||
vio_delete(mysql->net.vio);
|
|
||||||
mysql->net.vio= NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo(res);
|
|
||||||
|
|
||||||
if (sock == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
my_set_error(mysql, CR_IPSOCK_ERROR, SQLSTATE_UNKNOWN, ER(CR_IPSOCK_ERROR),
|
|
||||||
socket_errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* last call to connect 2 failed */
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
my_set_error(mysql, CR_CONN_HOST_ERROR, SQLSTATE_UNKNOWN, ER(CR_CONN_HOST_ERROR),
|
|
||||||
host, socket_errno);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* Initialize and load cio plugin */
|
||||||
|
if (!(cio= ma_cio_init(&cinfo)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* set timeouts */
|
/* try to connect */
|
||||||
net->vio->read_timeout= mysql->options.read_timeout;
|
if (ma_cio_connect(cio, &cinfo) != 0)
|
||||||
net->vio->write_timeout= mysql->options.write_timeout;
|
|
||||||
|
|
||||||
if (mysql->options.extension && mysql->options.extension->async_context)
|
|
||||||
net->vio->async_context= mysql->options.extension->async_context;
|
|
||||||
|
|
||||||
if (!net->vio || my_net_init(net, net->vio))
|
|
||||||
{
|
{
|
||||||
vio_delete(net->vio);
|
ma_cio_close(cio);
|
||||||
net->vio = 0;
|
|
||||||
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
vio_keepalive(net->vio,TRUE);
|
|
||||||
|
if (my_net_init(net, cio))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
ma_cio_keepalive(net->cio);
|
||||||
strmov(mysql->net.sqlstate, "00000");
|
strmov(mysql->net.sqlstate, "00000");
|
||||||
|
|
||||||
|
|
||||||
/* set read timeout */
|
|
||||||
if (mysql->options.read_timeout >= 0)
|
|
||||||
vio_read_timeout(net->vio, mysql->options.read_timeout);
|
|
||||||
|
|
||||||
/* set write timeout */
|
|
||||||
if (mysql->options.write_timeout >= 0)
|
|
||||||
vio_write_timeout(net->vio, mysql->options.read_timeout);
|
|
||||||
/* Get version info */
|
/* Get version info */
|
||||||
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
|
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
|
||||||
if (mysql->options.connect_timeout >= 0 &&
|
/*
|
||||||
vio_wait_or_timeout(net->vio, FALSE, mysql->options.connect_timeout * 1000) < 1)
|
if (ma_cio_wait_io_or_timeout(net->cio, FALSE, 0) < 1)
|
||||||
{
|
{
|
||||||
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
|
||||||
ER(CR_SERVER_LOST_EXTENDED),
|
ER(CR_SERVER_LOST_EXTENDED),
|
||||||
@@ -1776,6 +1438,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
errno);
|
errno);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||||
{
|
{
|
||||||
if (mysql->net.last_errno == CR_SERVER_LOST)
|
if (mysql->net.last_errno == CR_SERVER_LOST)
|
||||||
@@ -1821,9 +1484,9 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
|
|
||||||
if (!my_multi_malloc(MYF(0),
|
if (!my_multi_malloc(MYF(0),
|
||||||
&mysql->host_info, (uint) strlen(host_info)+1,
|
&mysql->host_info, (uint) strlen(host_info)+1,
|
||||||
&mysql->host, (uint) strlen(host)+1,
|
&mysql->host, (uint) strlen(cinfo.host)+1,
|
||||||
&mysql->unix_socket,unix_socket ?
|
&mysql->unix_socket, cinfo.unix_socket ?
|
||||||
(uint) strlen(unix_socket)+1 : (uint) 1,
|
(uint) strlen(cinfo.unix_socket)+1 : (uint) 1,
|
||||||
&mysql->server_version, (uint) (end - (char*) net->read_pos),
|
&mysql->server_version, (uint) (end - (char*) net->read_pos),
|
||||||
NullS) ||
|
NullS) ||
|
||||||
!(mysql->user=my_strdup(user,MYF(0))) ||
|
!(mysql->user=my_strdup(user,MYF(0))) ||
|
||||||
@@ -1833,9 +1496,9 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
strmov(mysql->host_info,host_info);
|
strmov(mysql->host_info,host_info);
|
||||||
strmov(mysql->host,host);
|
strmov(mysql->host, cinfo.host);
|
||||||
if (unix_socket)
|
if (cinfo.unix_socket)
|
||||||
strmov(mysql->unix_socket,unix_socket);
|
strmov(mysql->unix_socket, cinfo.unix_socket);
|
||||||
else
|
else
|
||||||
mysql->unix_socket=0;
|
mysql->unix_socket=0;
|
||||||
mysql->port=port;
|
mysql->port=port;
|
||||||
@@ -1985,11 +1648,9 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
strmov(mysql->net.sqlstate, "00000");
|
strmov(mysql->net.sqlstate, "00000");
|
||||||
|
|
||||||
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
|
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));
|
||||||
reset_sigpipe(mysql);
|
|
||||||
DBUG_RETURN(mysql);
|
DBUG_RETURN(mysql);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
reset_sigpipe(mysql);
|
|
||||||
DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error));
|
DBUG_PRINT("error",("message: %u (%s)",net->last_errno,net->last_error));
|
||||||
{
|
{
|
||||||
/* Free alloced memory */
|
/* Free alloced memory */
|
||||||
@@ -2002,7 +1663,6 @@ error:
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static my_bool mysql_reconnect(MYSQL *mysql)
|
static my_bool mysql_reconnect(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL tmp_mysql;
|
MYSQL tmp_mysql;
|
||||||
@@ -2025,13 +1685,13 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
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 */
|
/* make sure that we reconnect with the same character set */
|
||||||
if (!tmp_mysql.options.charset_name ||
|
/* if (!tmp_mysql.options.charset_name ||
|
||||||
strcmp(tmp_mysql.options.charset_name, mysql->charset->csname))
|
strcmp(tmp_mysql.options.charset_name, mysql->charset->csname))
|
||||||
{
|
{
|
||||||
my_free(tmp_mysql.options.charset_name);
|
my_free(tmp_mysql.options.charset_name);
|
||||||
tmp_mysql.options.charset_name= my_strdup(mysql->charset->csname, MYF(MY_WME));
|
tmp_mysql.options.charset_name= my_strdup(mysql->charset->csname, MYF(MY_WME));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
tmp_mysql.reconnect= mysql->reconnect;
|
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,
|
||||||
@@ -2252,7 +1912,7 @@ void my_set_error(MYSQL *mysql,
|
|||||||
|
|
||||||
void mysql_close_slow_part(MYSQL *mysql)
|
void mysql_close_slow_part(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
if (mysql->net.vio)
|
if (mysql->net.cio)
|
||||||
{
|
{
|
||||||
free_old_query(mysql);
|
free_old_query(mysql);
|
||||||
mysql->status=MYSQL_STATUS_READY; /* Force command */
|
mysql->status=MYSQL_STATUS_READY; /* Force command */
|
||||||
@@ -2288,7 +1948,7 @@ mysql_close(MYSQL *mysql)
|
|||||||
|
|
||||||
/* Clear pointers for better safety */
|
/* Clear pointers for better safety */
|
||||||
bzero((char*) &mysql->options,sizeof(mysql->options));
|
bzero((char*) &mysql->options,sizeof(mysql->options));
|
||||||
mysql->net.vio= 0;
|
mysql->net.cio= 0;
|
||||||
if (mysql->free_me)
|
if (mysql->free_me)
|
||||||
my_free(mysql);
|
my_free(mysql);
|
||||||
}
|
}
|
||||||
@@ -2931,7 +2591,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
#else
|
#else
|
||||||
if (*(uint *)arg1 > MYSQL_PROTOCOL_SOCKET)
|
if (*(uint *)arg1 > MYSQL_PROTOCOL_SOCKET)
|
||||||
#endif
|
#endif
|
||||||
DBUG_RETURN(-1);
|
goto end;
|
||||||
mysql->options.protocol= *(uint *)arg1;
|
mysql->options.protocol= *(uint *)arg1;
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_READ_TIMEOUT:
|
case MYSQL_OPT_READ_TIMEOUT:
|
||||||
@@ -2953,11 +2613,12 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
(void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg1;
|
(void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg1;
|
||||||
break;
|
break;
|
||||||
case MYSQL_PLUGIN_DIR:
|
case MYSQL_PLUGIN_DIR:
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, plugin_dir, (char *)arg1, 1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, plugin_dir, (char *)arg1);
|
||||||
break;
|
break;
|
||||||
case MYSQL_DEFAULT_AUTH:
|
case MYSQL_DEFAULT_AUTH:
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, default_auth, (char *)arg1, 1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, default_auth, (char *)arg1);
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
case MYSQL_DATABASE_DRIVER:
|
case MYSQL_DATABASE_DRIVER:
|
||||||
{
|
{
|
||||||
MARIADB_DB_PLUGIN *db_plugin;
|
MARIADB_DB_PLUGIN *db_plugin;
|
||||||
@@ -2981,6 +2642,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
case MYSQL_OPT_NONBLOCK:
|
case MYSQL_OPT_NONBLOCK:
|
||||||
if (mysql->options.extension &&
|
if (mysql->options.extension &&
|
||||||
(ctxt = mysql->options.extension->async_context) != 0)
|
(ctxt = mysql->options.extension->async_context) != 0)
|
||||||
@@ -2990,7 +2652,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
suspended (as the stack is then in use).
|
suspended (as the stack is then in use).
|
||||||
*/
|
*/
|
||||||
if (ctxt->suspended)
|
if (ctxt->suspended)
|
||||||
DBUG_RETURN(1);
|
goto end;
|
||||||
my_context_destroy(&ctxt->async_context);
|
my_context_destroy(&ctxt->async_context);
|
||||||
my_free(ctxt);
|
my_free(ctxt);
|
||||||
}
|
}
|
||||||
@@ -2998,7 +2660,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
my_malloc(sizeof(*ctxt), MYF(MY_ZEROFILL))))
|
my_malloc(sizeof(*ctxt), MYF(MY_ZEROFILL))))
|
||||||
{
|
{
|
||||||
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
||||||
DBUG_RETURN(1);
|
goto end;
|
||||||
}
|
}
|
||||||
stacksize= 0;
|
stacksize= 0;
|
||||||
if (arg1)
|
if (arg1)
|
||||||
@@ -3008,7 +2670,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
if (my_context_init(&ctxt->async_context, stacksize))
|
if (my_context_init(&ctxt->async_context, stacksize))
|
||||||
{
|
{
|
||||||
my_free(ctxt);
|
my_free(ctxt);
|
||||||
DBUG_RETURN(1);
|
goto end;
|
||||||
}
|
}
|
||||||
if (!mysql->options.extension)
|
if (!mysql->options.extension)
|
||||||
if(!(mysql->options.extension= (struct st_mysql_options_extension *)
|
if(!(mysql->options.extension= (struct st_mysql_options_extension *)
|
||||||
@@ -3016,11 +2678,11 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
MYF(MY_WME | MY_ZEROFILL))))
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
{
|
{
|
||||||
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
|
||||||
DBUG_RETURN(1);
|
goto end;
|
||||||
}
|
}
|
||||||
mysql->options.extension->async_context= ctxt;
|
mysql->options.extension->async_context= ctxt;
|
||||||
if (mysql->net.vio)
|
if (mysql->net.cio)
|
||||||
mysql->net.vio->async_context= ctxt;
|
mysql->net.cio->async_context= ctxt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
||||||
@@ -3050,16 +2712,10 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
mysql->options.ssl_cipher=my_strdup((char *)arg1,MYF(MY_WME));
|
mysql->options.ssl_cipher=my_strdup((char *)arg1,MYF(MY_WME));
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_SSL_CRL:
|
case MYSQL_OPT_SSL_CRL:
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, ssl_crl, (char *)arg1, 1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, ssl_crl, (char *)arg1);
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_SSL_CRLPATH:
|
case MYSQL_OPT_SSL_CRLPATH:
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, ssl_crlpath, (char *)arg1, 1);
|
OPT_SET_EXTENDED_VALUE_STR(&mysql->options, ssl_crlpath, (char *)arg1);
|
||||||
break;
|
|
||||||
case MARIADB_OPT_SSL_FP:
|
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, ssl_fp, (char *)arg1, 1);
|
|
||||||
break;
|
|
||||||
case MARIADB_OPT_SSL_FP_LIST:
|
|
||||||
OPT_SET_EXTENDED_VALUE(&mysql->options, ssl_fp_list, (char *)arg1, 1);
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_CONNECT_ATTR_DELETE:
|
case MYSQL_OPT_CONNECT_ATTR_DELETE:
|
||||||
{
|
{
|
||||||
@@ -3148,6 +2804,10 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
case MYSQL_SECURE_AUTH:
|
case MYSQL_SECURE_AUTH:
|
||||||
mysql->options.secure_auth= *(my_bool *)arg1;
|
mysql->options.secure_auth= *(my_bool *)arg1;
|
||||||
break;
|
break;
|
||||||
|
case MYSQL_OPT_BIND:
|
||||||
|
my_free(mysql->options.bind_address);
|
||||||
|
mysql->options.bind_address= my_strdup(arg1, MYF(MY_WME));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@@ -3452,9 +3112,6 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)),
|
|||||||
mysql_unix_port = env;
|
mysql_unix_port = env;
|
||||||
}
|
}
|
||||||
mysql_debug(NullS);
|
mysql_debug(NullS);
|
||||||
#if defined(SIGPIPE) && !defined(THREAD) && !defined(_WIN32)
|
|
||||||
(void) signal(SIGPIPE,SIG_IGN);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef THREAD
|
#ifdef THREAD
|
||||||
else
|
else
|
||||||
@@ -3469,12 +3126,10 @@ void STDCALL mysql_server_end()
|
|||||||
{
|
{
|
||||||
if (!mysql_client_init)
|
if (!mysql_client_init)
|
||||||
return;
|
return;
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
my_ssl_end();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mysql_client_plugin_deinit();
|
mysql_client_plugin_deinit();
|
||||||
|
|
||||||
|
list_free(cio_callback, 0);
|
||||||
if (my_init_done)
|
if (my_init_done)
|
||||||
my_end(0);
|
my_end(0);
|
||||||
mysql_client_init= 0;
|
mysql_client_init= 0;
|
||||||
@@ -3550,9 +3205,13 @@ mysql_get_parameters(void)
|
|||||||
my_socket STDCALL
|
my_socket STDCALL
|
||||||
mysql_get_socket(const MYSQL *mysql)
|
mysql_get_socket(const MYSQL *mysql)
|
||||||
{
|
{
|
||||||
if (mysql->net.vio)
|
my_socket sock;
|
||||||
return vio_fd(mysql->net.vio);
|
if (mysql->net.cio)
|
||||||
return MARIADB_INVALID_SOCKET;
|
{
|
||||||
|
ma_cio_get_handle(mysql->net.cio, &sock);
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -53,7 +53,7 @@
|
|||||||
#include "mysql_version.h"
|
#include "mysql_version.h"
|
||||||
#include "mysqld_error.h"
|
#include "mysqld_error.h"
|
||||||
#include "errmsg.h"
|
#include "errmsg.h"
|
||||||
#include <violite.h>
|
#include <ma_cio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -988,7 +988,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_stmt_close");
|
DBUG_ENTER("mysql_stmt_close");
|
||||||
|
|
||||||
if (stmt && stmt->mysql && stmt->mysql->net.vio)
|
if (stmt && stmt->mysql && stmt->mysql->net.cio)
|
||||||
mysql_stmt_reset(stmt);
|
mysql_stmt_reset(stmt);
|
||||||
net_stmt_close(stmt, 1);
|
net_stmt_close(stmt, 1);
|
||||||
|
|
||||||
|
@@ -30,8 +30,9 @@
|
|||||||
#include "ma_common.h"
|
#include "ma_common.h"
|
||||||
#endif
|
#endif
|
||||||
#include "my_context.h"
|
#include "my_context.h"
|
||||||
#include "violite.h"
|
#include "ma_cio.h"
|
||||||
#include "mysql_async.h"
|
#include "mysql_async.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -41,7 +42,7 @@
|
|||||||
*/
|
*/
|
||||||
#define WIN_SET_NONBLOCKING(mysql) { \
|
#define WIN_SET_NONBLOCKING(mysql) { \
|
||||||
my_bool old_mode; \
|
my_bool old_mode; \
|
||||||
if ((mysql)->net.vio) vio_blocking((mysql)->net.vio, FALSE, &old_mode); \
|
if ((mysql)->net.cio) ma_cio_blocking((mysql)->net.cio, FALSE, &old_mode); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define WIN_SET_NONBLOCKING(mysql)
|
#define WIN_SET_NONBLOCKING(mysql)
|
||||||
@@ -62,19 +63,18 @@ my_context_install_suspend_resume_hook(struct mysql_async_context *b,
|
|||||||
|
|
||||||
/* Asynchronous connect(); socket must already be set non-blocking. */
|
/* Asynchronous connect(); socket must already be set non-blocking. */
|
||||||
int
|
int
|
||||||
my_connect_async(struct mysql_async_context *b, my_socket fd,
|
my_connect_async(MARIADB_CIO *cio,
|
||||||
const struct sockaddr *name, uint namelen, int vio_timeout)
|
const struct sockaddr *name, uint namelen, int vio_timeout)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
size_socket s_err_size;
|
size_socket s_err_size;
|
||||||
|
struct mysql_async_context *b= cio->mysql->options.extension->async_context;
|
||||||
|
my_socket sock;
|
||||||
|
|
||||||
|
ma_cio_get_handle(cio, &sock);
|
||||||
|
|
||||||
/* Make the socket non-blocking. */
|
/* Make the socket non-blocking. */
|
||||||
#ifdef _WIN32
|
ma_cio_blocking(cio, 0, 0);
|
||||||
ulong arg= 1;
|
|
||||||
ioctlsocket(fd, FIONBIO, (void *)&arg);
|
|
||||||
#else
|
|
||||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
b->events_to_wait_for= 0;
|
b->events_to_wait_for= 0;
|
||||||
/*
|
/*
|
||||||
@@ -83,7 +83,7 @@ my_connect_async(struct mysql_async_context *b, my_socket fd,
|
|||||||
application context. The application will then resume us when the socket
|
application context. The application will then resume us when the socket
|
||||||
polls ready for write, indicating that the connection attempt completed.
|
polls ready for write, indicating that the connection attempt completed.
|
||||||
*/
|
*/
|
||||||
res= connect(fd, name, namelen);
|
res= connect(sock, name, namelen);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -113,7 +113,7 @@ my_connect_async(struct mysql_async_context *b, my_socket fd,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
s_err_size= sizeof(res);
|
s_err_size= sizeof(res);
|
||||||
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &res, &s_err_size) != 0)
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*) &res, &s_err_size) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
@@ -135,14 +135,15 @@ my_connect_async(struct mysql_async_context *b, my_socket fd,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
my_recv_async(struct mysql_async_context *b, int fd,
|
my_recv_async(MARIADB_CIO *cio, const unsigned char *buf, size_t size, int timeout)
|
||||||
unsigned char *buf, size_t size, int timeout)
|
|
||||||
{
|
{
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
|
struct mysql_async_context *b= cio->async_context;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
res= recv(fd, buf, size, IF_WIN(0, MSG_DONTWAIT));
|
/* todo: async */
|
||||||
|
if (cio->methods->async_read)
|
||||||
|
res= cio->methods->async_read(cio, buf, size);
|
||||||
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;
|
||||||
@@ -163,14 +164,15 @@ my_recv_async(struct mysql_async_context *b, int fd,
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
my_send_async(struct mysql_async_context *b, int fd,
|
my_send_async(MARIADB_CIO *cio, const unsigned char *buf, size_t size, int timeout)
|
||||||
const unsigned char *buf, size_t size, int timeout)
|
|
||||||
{
|
{
|
||||||
ssize_t res;
|
ssize_t res;
|
||||||
|
struct mysql_async_context *b= cio->async_context;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
res= send(fd, buf, size, IF_WIN(0, MSG_DONTWAIT));
|
if (cio->methods->async_write)
|
||||||
|
res= cio->methods->async_write(cio, buf, size);
|
||||||
if (res >= 0 || IS_BLOCKING_ERROR())
|
if (res >= 0 || IS_BLOCKING_ERROR())
|
||||||
return res;
|
return res;
|
||||||
b->events_to_wait_for= MYSQL_WAIT_WRITE;
|
b->events_to_wait_for= MYSQL_WAIT_WRITE;
|
||||||
@@ -191,7 +193,7 @@ my_send_async(struct mysql_async_context *b, int fd,
|
|||||||
|
|
||||||
|
|
||||||
my_bool
|
my_bool
|
||||||
my_io_wait_async(struct mysql_async_context *b, enum enum_vio_io_event event,
|
my_io_wait_async(struct mysql_async_context *b, enum enum_cio_io_event event,
|
||||||
int timeout)
|
int timeout)
|
||||||
{
|
{
|
||||||
switch (event)
|
switch (event)
|
||||||
@@ -221,9 +223,9 @@ my_io_wait_async(struct mysql_async_context *b, enum enum_vio_io_event event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_SSL_FIXME
|
||||||
static my_bool
|
static my_bool
|
||||||
my_ssl_async_check_result(int res, struct mysql_async_context *b, SSL *ssl)
|
my_ssl_async_check_result(int res, struct mysql_async_context *b, MARIADB_SSL *cssl)
|
||||||
{
|
{
|
||||||
int ssl_err;
|
int ssl_err;
|
||||||
b->events_to_wait_for= 0;
|
b->events_to_wait_for= 0;
|
||||||
@@ -496,18 +498,36 @@ MK_ASYNC_INTERNAL_BODY(
|
|||||||
int STDCALL
|
int STDCALL
|
||||||
mysql_real_query_start(int *ret, MYSQL *mysql, const char *stmt_str, unsigned long length)
|
mysql_real_query_start(int *ret, MYSQL *mysql, const char *stmt_str, unsigned long length)
|
||||||
{
|
{
|
||||||
MK_ASYNC_START_BODY(
|
int res;
|
||||||
mysql_real_query,
|
struct mysql_async_context *b;
|
||||||
mysql,
|
struct mysql_real_query_params parms;
|
||||||
|
|
||||||
|
b= mysql->options.extension->async_context;
|
||||||
{
|
{
|
||||||
WIN_SET_NONBLOCKING(mysql)
|
WIN_SET_NONBLOCKING(mysql)
|
||||||
parms.mysql= mysql;
|
parms.mysql= mysql;
|
||||||
parms.stmt_str= stmt_str;
|
parms.stmt_str= stmt_str;
|
||||||
parms.length= length;
|
parms.length= length;
|
||||||
},
|
}
|
||||||
1,
|
|
||||||
r_int,
|
b->active= 1;
|
||||||
/* Nothing */)
|
res= my_context_spawn(&b->async_context, mysql_real_query_start_internal, &parms);
|
||||||
|
b->active= b->suspended= 0;
|
||||||
|
if (res > 0)
|
||||||
|
{
|
||||||
|
/* Suspended. */
|
||||||
|
b->suspended= 1;
|
||||||
|
return b->events_to_wait_for;
|
||||||
|
}
|
||||||
|
if (res < 0)
|
||||||
|
{
|
||||||
|
set_mysql_error((mysql), CR_OUT_OF_MEMORY, unknown_sqlstate);
|
||||||
|
*ret= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*ret= b->ret_result.r_int;
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
int STDCALL
|
int STDCALL
|
||||||
mysql_real_query_cont(int *ret, MYSQL *mysql, int ready_status)
|
mysql_real_query_cont(int *ret, MYSQL *mysql, int ready_status)
|
||||||
|
228
libmariadb/net.c
228
libmariadb/net.c
@@ -22,8 +22,10 @@
|
|||||||
** 3 byte length & 1 byte package-number.
|
** 3 byte length & 1 byte package-number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include <violite.h>
|
#include <mysql.h>
|
||||||
|
#include <ma_cio.h>
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
#include <m_string.h>
|
#include <m_string.h>
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
@@ -31,6 +33,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <ma_cio.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -46,7 +49,7 @@
|
|||||||
ulong max_allowed_packet=1024L * 1024L * 1024L;
|
ulong max_allowed_packet=1024L * 1024L * 1024L;
|
||||||
ulong net_read_timeout= NET_READ_TIMEOUT;
|
ulong net_read_timeout= NET_READ_TIMEOUT;
|
||||||
ulong net_write_timeout= NET_WRITE_TIMEOUT;
|
ulong net_write_timeout= NET_WRITE_TIMEOUT;
|
||||||
ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
|
ulong net_buffer_length= 8192; /* Default length. Enlarged if necessary */
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(MSDOS)
|
#if !defined(_WIN32) && !defined(MSDOS)
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -110,13 +113,13 @@ static int net_write_buff(NET *net,const char *packet, size_t len);
|
|||||||
|
|
||||||
/* Init with packet info */
|
/* Init with packet info */
|
||||||
|
|
||||||
int my_net_init(NET *net, Vio* vio)
|
int my_net_init(NET *net, MARIADB_CIO* cio)
|
||||||
{
|
{
|
||||||
if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME | MY_ZEROFILL))))
|
if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME | MY_ZEROFILL))))
|
||||||
return 1;
|
return 1;
|
||||||
max_allowed_packet= net->max_packet_size= MAX(net_buffer_length, max_allowed_packet);
|
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->buff_end=net->buff+(net->max_packet=net_buffer_length);
|
||||||
net->vio = vio;
|
net->cio = cio;
|
||||||
net->error=0; net->return_status=0;
|
net->error=0; net->return_status=0;
|
||||||
net->read_timeout=(uint) net_read_timeout; /* Timeout for read */
|
net->read_timeout=(uint) net_read_timeout; /* Timeout for read */
|
||||||
net->compress_pkt_nr= net->pkt_nr= 0;
|
net->compress_pkt_nr= net->pkt_nr= 0;
|
||||||
@@ -127,21 +130,18 @@ int my_net_init(NET *net, Vio* vio)
|
|||||||
net->where_b = net->remain_in_buf=0;
|
net->where_b = net->remain_in_buf=0;
|
||||||
net->last_errno=0;
|
net->last_errno=0;
|
||||||
|
|
||||||
if (vio != 0) /* If real connection */
|
if (cio != 0) /* If real connection */
|
||||||
{
|
{
|
||||||
net->fd = vio_fd(vio); /* For perl DBI/DBD */
|
ma_cio_get_handle(cio, &net->fd);
|
||||||
#if defined(MYSQL_SERVER) && !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
ma_cio_blocking(cio, 1, 0);
|
||||||
if (!(test_flags & TEST_BLOCKING))
|
ma_cio_fast_send(cio);
|
||||||
vio_blocking(vio, FALSE, 0);
|
|
||||||
#endif
|
|
||||||
vio_fastsend(vio);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_end(NET *net)
|
void net_end(NET *net)
|
||||||
{
|
{
|
||||||
my_free(net->buff);
|
my_free((gptr) net->buff);
|
||||||
net->buff=0;
|
net->buff=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,15 +219,17 @@ static my_bool net_check_socket_status(my_socket sock)
|
|||||||
|
|
||||||
void net_clear(NET *net)
|
void net_clear(NET *net)
|
||||||
{
|
{
|
||||||
|
my_socket sock;
|
||||||
DBUG_ENTER("net_clear");
|
DBUG_ENTER("net_clear");
|
||||||
|
|
||||||
|
ma_cio_get_handle(net->cio, &sock);
|
||||||
|
|
||||||
/* see conc-71: we need to check the socket status first:
|
/* see conc-71: we need to check the socket status first:
|
||||||
if the socket is dead we set net->error, so net_flush
|
if the socket is dead we set net->error, so net_flush
|
||||||
will report an error */
|
will report an error */
|
||||||
while (net_check_socket_status(net->vio->sd))
|
while (net_check_socket_status(sock))
|
||||||
{
|
{
|
||||||
/* vio_read returns size_t. so casting to long is required to check for -1 */
|
if ((ssize_t)ma_cio_cache_read(net->cio, (gptr)net->buff, (size_t) net->max_packet) <= 0)
|
||||||
if ((long)vio_read(net->vio, (gptr)net->buff, (size_t) net->max_packet) <= 0)
|
|
||||||
{
|
{
|
||||||
net->error= 2;
|
net->error= 2;
|
||||||
DBUG_PRINT("info", ("socket disconnected"));
|
DBUG_PRINT("info", ("socket disconnected"));
|
||||||
@@ -384,12 +386,6 @@ net_real_write(NET *net,const char *packet,size_t len)
|
|||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
char *pos,*end;
|
char *pos,*end;
|
||||||
thr_alarm_t alarmed;
|
|
||||||
#if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2)
|
|
||||||
ALARM alarm_buff;
|
|
||||||
#endif
|
|
||||||
uint retry_count=0;
|
|
||||||
my_bool net_blocking = vio_is_blocking(net->vio);
|
|
||||||
DBUG_ENTER("net_real_write");
|
DBUG_ENTER("net_real_write");
|
||||||
|
|
||||||
if (net->error == 2)
|
if (net->error == 2)
|
||||||
@@ -426,79 +422,23 @@ net_real_write(NET *net,const char *packet,size_t len)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_COMPRESS */
|
#endif /* HAVE_COMPRESS */
|
||||||
|
|
||||||
alarmed=0;
|
|
||||||
|
|
||||||
pos=(char*) packet; end=pos+len;
|
pos=(char*) packet; end=pos+len;
|
||||||
while (pos != end)
|
while (pos != end)
|
||||||
{
|
{
|
||||||
if ((long) (length=vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
|
if ((ssize_t) (length=ma_cio_write(net->cio,pos,(size_t) (end-pos))) <= 0)
|
||||||
{
|
{
|
||||||
my_bool interrupted = vio_should_retry(net->vio);
|
|
||||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2))
|
|
||||||
if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
|
|
||||||
{
|
|
||||||
if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
|
|
||||||
{ /* Always true for client */
|
|
||||||
if (!vio_is_blocking(net->vio))
|
|
||||||
{
|
|
||||||
while (vio_blocking(net->vio, TRUE, 0) < 0)
|
|
||||||
{
|
|
||||||
if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT)
|
|
||||||
continue;
|
|
||||||
#ifdef EXTRA_DEBUG
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
|
|
||||||
my_progname,vio_errno(net->vio));
|
|
||||||
#endif /* EXTRA_DEBUG */
|
|
||||||
net->error=2; /* Close socket */
|
|
||||||
net->last_errno= (interrupted ?
|
|
||||||
ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retry_count=0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) */
|
|
||||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
|
||||||
interrupted)
|
|
||||||
{
|
|
||||||
if (retry_count++ < RETRY_COUNT)
|
|
||||||
continue;
|
|
||||||
#ifdef EXTRA_DEBUG
|
|
||||||
fprintf(stderr, "%s: write looped, aborting thread\n",
|
|
||||||
my_progname);
|
|
||||||
#endif /* EXTRA_DEBUG */
|
|
||||||
}
|
|
||||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
|
||||||
if (vio_errno(net->vio) == SOCKET_EINTR)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("warning",("Interrupted write. Retrying..."));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
|
|
||||||
net->error=2; /* Close socket */
|
net->error=2; /* Close socket */
|
||||||
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
|
net->last_errno= ER_NET_ERROR_ON_WRITE;
|
||||||
ER_NET_ERROR_ON_WRITE);
|
net->reading_or_writing=0;
|
||||||
break;
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
pos+=length;
|
pos+=length;
|
||||||
statistic_add(bytes_sent,length,&LOCK_bytes_sent);
|
statistic_add(bytes_sent,length,&LOCK_bytes_sent);
|
||||||
}
|
}
|
||||||
#ifndef _WIN32
|
|
||||||
end:
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_COMPRESS
|
#ifdef HAVE_COMPRESS
|
||||||
if (net->compress)
|
if (net->compress)
|
||||||
my_free((void *)packet);
|
my_free((char*) packet);
|
||||||
#endif
|
#endif
|
||||||
if (thr_alarm_in_use(&alarmed))
|
|
||||||
{
|
|
||||||
thr_end_alarm(&alarmed);
|
|
||||||
vio_blocking(net->vio, net_blocking, 0);
|
|
||||||
}
|
|
||||||
net->reading_or_writing=0;
|
net->reading_or_writing=0;
|
||||||
DBUG_RETURN(((int) (pos != end)));
|
DBUG_RETURN(((int) (pos != end)));
|
||||||
}
|
}
|
||||||
@@ -507,66 +447,18 @@ net_real_write(NET *net,const char *packet,size_t len)
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Read something from server/clinet
|
** Read something from server/clinet
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
|
|
||||||
/*
|
|
||||||
Help function to clear the commuication buffer when we get a too
|
|
||||||
big packet
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed,
|
|
||||||
ALARM *alarm_buff)
|
|
||||||
{
|
|
||||||
uint retry_count=0;
|
|
||||||
if (!thr_alarm_in_use(alarmed))
|
|
||||||
{
|
|
||||||
if (thr_alarm(alarmed,net->timeout,alarm_buff) ||
|
|
||||||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE, 0) < 0))
|
|
||||||
return; /* Can't setup, abort */
|
|
||||||
}
|
|
||||||
while (remain > 0)
|
|
||||||
{
|
|
||||||
ulong length;
|
|
||||||
if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
|
|
||||||
{
|
|
||||||
my_bool interrupted = vio_should_retry(net->vio);
|
|
||||||
if (!thr_got_alarm(alarmed) && interrupted)
|
|
||||||
{ /* Probably in MIT threads */
|
|
||||||
if (retry_count++ < RETRY_COUNT)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
remain -=(ulong) length;
|
|
||||||
statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* MYSQL_SERVER */
|
|
||||||
|
|
||||||
|
|
||||||
static ulong
|
static ulong
|
||||||
my_real_read(NET *net, size_t *complen)
|
my_real_read(NET *net, size_t *complen)
|
||||||
{
|
{
|
||||||
uchar *pos;
|
uchar *pos;
|
||||||
size_t length;
|
size_t length;
|
||||||
uint i,retry_count=0;
|
uint i;
|
||||||
ulong len=packet_error;
|
ulong len=packet_error;
|
||||||
thr_alarm_t alarmed;
|
|
||||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
|
|
||||||
ALARM alarm_buff;
|
|
||||||
#endif
|
|
||||||
my_bool net_blocking=vio_is_blocking(net->vio);
|
|
||||||
size_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
|
size_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
|
||||||
NET_HEADER_SIZE);
|
NET_HEADER_SIZE);
|
||||||
*complen = 0;
|
*complen = 0;
|
||||||
|
|
||||||
net->reading_or_writing=1;
|
net->reading_or_writing=1;
|
||||||
thr_alarm_init(&alarmed);
|
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
if (net_blocking)
|
|
||||||
thr_alarm(&alarmed,net->timeout,&alarm_buff);
|
|
||||||
#endif /* MYSQL_SERVER */
|
|
||||||
|
|
||||||
pos = net->buff + net->where_b; /* net->packet -4 */
|
pos = net->buff + net->where_b; /* net->packet -4 */
|
||||||
for (i=0 ; i < 2 ; i++)
|
for (i=0 ; i < 2 ; i++)
|
||||||
@@ -574,68 +466,8 @@ my_real_read(NET *net, size_t *complen)
|
|||||||
while (remain > 0)
|
while (remain > 0)
|
||||||
{
|
{
|
||||||
/* First read is done with non blocking mode */
|
/* First read is done with non blocking mode */
|
||||||
if ((long) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L)
|
if ((ssize_t) (length=ma_cio_cache_read(net->cio,(char*) pos,remain)) <= 0L)
|
||||||
{
|
{
|
||||||
my_bool interrupted = vio_should_retry(net->vio);
|
|
||||||
|
|
||||||
DBUG_PRINT("info",("vio_read returned %d, errno: %d",
|
|
||||||
length, vio_errno(net->vio)));
|
|
||||||
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
|
|
||||||
/*
|
|
||||||
We got an error that there was no data on the socket. We now set up
|
|
||||||
an alarm to not 'read forever', change the socket to non blocking
|
|
||||||
mode and try again
|
|
||||||
*/
|
|
||||||
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
|
|
||||||
{
|
|
||||||
if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
|
|
||||||
{
|
|
||||||
if (!vio_is_blocking(net->vio))
|
|
||||||
{
|
|
||||||
while (vio_blocking(net->vio,TRUE, 0) < 0)
|
|
||||||
{
|
|
||||||
if (vio_should_retry(net->vio) &&
|
|
||||||
retry_count++ < RETRY_COUNT)
|
|
||||||
continue;
|
|
||||||
DBUG_PRINT("error",
|
|
||||||
("fcntl returned error %d, aborting thread",
|
|
||||||
vio_errno(net->vio)));
|
|
||||||
#ifdef EXTRA_DEBUG
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: read: fcntl returned error %d, aborting thread\n",
|
|
||||||
my_progname,vio_errno(net->vio));
|
|
||||||
#endif /* EXTRA_DEBUG */
|
|
||||||
len= packet_error;
|
|
||||||
net->error=2; /* Close socket */
|
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
net->last_errno=ER_NET_FCNTL_ERROR;
|
|
||||||
#endif
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
retry_count=0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* (!defined(_WIN32) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
|
|
||||||
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
|
|
||||||
interrupted)
|
|
||||||
{ /* Probably in MIT threads */
|
|
||||||
if (retry_count++ < RETRY_COUNT)
|
|
||||||
continue;
|
|
||||||
#ifdef EXTRA_DEBUG
|
|
||||||
fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
|
|
||||||
my_progname,vio_errno(net->vio));
|
|
||||||
#endif /* EXTRA_DEBUG */
|
|
||||||
}
|
|
||||||
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
|
|
||||||
if (vio_should_retry(net->vio))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DBUG_PRINT("error",("Couldn't read packet: remain: %d errno: %d length: %d alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
|
|
||||||
len= packet_error;
|
len= packet_error;
|
||||||
net->error=2; /* Close socket */
|
net->error=2; /* Close socket */
|
||||||
goto end;
|
goto end;
|
||||||
@@ -662,9 +494,6 @@ my_real_read(NET *net, size_t *complen)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
len= packet_error;
|
len= packet_error;
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
|
|
||||||
#endif
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
net->compress_pkt_nr= ++net->pkt_nr;
|
net->compress_pkt_nr= ++net->pkt_nr;
|
||||||
@@ -685,10 +514,6 @@ my_real_read(NET *net, size_t *complen)
|
|||||||
{
|
{
|
||||||
if (net_realloc(net,helping))
|
if (net_realloc(net,helping))
|
||||||
{
|
{
|
||||||
#ifdef MYSQL_SERVER
|
|
||||||
if (i == 1)
|
|
||||||
my_net_skip_rest(net, len, &alarmed, &alarm_buff);
|
|
||||||
#endif
|
|
||||||
len= packet_error; /* Return error */
|
len= packet_error; /* Return error */
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -699,11 +524,6 @@ my_real_read(NET *net, size_t *complen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (thr_alarm_in_use(&alarmed))
|
|
||||||
{
|
|
||||||
thr_end_alarm(&alarmed);
|
|
||||||
vio_blocking(net->vio, net_blocking, 0);
|
|
||||||
}
|
|
||||||
net->reading_or_writing=0;
|
net->reading_or_writing=0;
|
||||||
return(len);
|
return(len);
|
||||||
}
|
}
|
||||||
|
@@ -1,713 +0,0 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
MA 02111-1307, USA */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Note that we can't have assertion on file descriptors; The reason for
|
|
||||||
this is that during mysql shutdown, another thread can close a file
|
|
||||||
we are working on. In this case we should just return read errors from
|
|
||||||
the file descriptior.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */
|
|
||||||
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <violite.h>
|
|
||||||
#include <my_sys.h>
|
|
||||||
#include <my_net.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#ifdef HAVE_POLL
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
#include <ma_secure.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define socklen_t int
|
|
||||||
#pragma comment (lib, "ws2_32")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(MSDOS) && !defined(_WIN32) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__FreeBSD__)
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#if !defined(alpha_linux_port)
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__EMX__) || defined(OS2)
|
|
||||||
#define ioctlsocket ioctl
|
|
||||||
#endif /* defined(__EMX__) */
|
|
||||||
|
|
||||||
#if defined(MSDOS) || defined(_WIN32)
|
|
||||||
#define O_NONBLOCK 1 /* For emulation of fcntl() */
|
|
||||||
#endif
|
|
||||||
#ifndef EWOULDBLOCK
|
|
||||||
#define SOCKET_EWOULDBLOCK SOCKET_EAGAIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <mysql_async.h>
|
|
||||||
#include <my_context.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define ma_get_error() WSAGetLastError()
|
|
||||||
#else
|
|
||||||
#define ma_get_error() errno
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void *vio_ptr;
|
|
||||||
typedef char *vio_cstring;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper to fill most of the Vio* with defaults.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void vio_reset(Vio* vio, enum enum_vio_type type,
|
|
||||||
my_socket sd, HANDLE hPipe,
|
|
||||||
my_bool localhost)
|
|
||||||
{
|
|
||||||
uchar *save_cache= vio->cache;
|
|
||||||
int save_timeouts[2]= {vio->read_timeout, vio->write_timeout};
|
|
||||||
bzero((char*) vio, sizeof(*vio));
|
|
||||||
vio->type= type;
|
|
||||||
vio->sd= sd;
|
|
||||||
vio->hPipe= hPipe;
|
|
||||||
vio->localhost= localhost;
|
|
||||||
/* do not clear cache */
|
|
||||||
vio->cache= vio->cache_pos= save_cache;
|
|
||||||
vio->cache_size= 0;
|
|
||||||
vio->read_timeout= save_timeouts[0];
|
|
||||||
vio->write_timeout= save_timeouts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void vio_timeout(Vio *vio, int type, uint timeval)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
uint timeout= timeval; /* milli secs */
|
|
||||||
#else
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec= timeval;
|
|
||||||
timeout.tv_usec= (timeval % 1000) * 1000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (setsockopt(vio->sd, SOL_SOCKET, type,
|
|
||||||
#ifdef _WIN32
|
|
||||||
(const char *)&timeout,
|
|
||||||
#else
|
|
||||||
(const void *)&timeout,
|
|
||||||
#endif
|
|
||||||
sizeof(timeout)))
|
|
||||||
{
|
|
||||||
DBUG_PRINT("error", ("setsockopt failed. Errno: %d", errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vio_read_timeout(Vio *vio, uint timeout)
|
|
||||||
{
|
|
||||||
vio->read_timeout= (timeout >= 0) ? timeout * 1000 : -1;
|
|
||||||
vio_timeout(vio, SO_RCVTIMEO, vio->read_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vio_write_timeout(Vio *vio, uint timeout)
|
|
||||||
{
|
|
||||||
vio->write_timeout= (timeout >= 0) ? timeout * 1000 : -1;
|
|
||||||
vio_timeout(vio, SO_SNDTIMEO, vio->write_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the socket or TCP/IP connection and read the fnctl() status */
|
|
||||||
|
|
||||||
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
|
|
||||||
{
|
|
||||||
Vio *vio;
|
|
||||||
DBUG_ENTER("vio_new");
|
|
||||||
DBUG_PRINT("enter", ("sd=%d", sd));
|
|
||||||
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
|
|
||||||
{
|
|
||||||
vio_reset(vio, type, sd, 0, localhost);
|
|
||||||
sprintf(vio->desc,
|
|
||||||
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
|
|
||||||
vio->sd);
|
|
||||||
#if !defined(__WIN32) && !defined(__EMX__) && !defined(OS2)
|
|
||||||
#if !defined(NO_FCNTL_NONBLOCK)
|
|
||||||
vio->fcntl_mode = fcntl(sd, F_GETFL);
|
|
||||||
#elif defined(HAVE_SYS_IOCTL_H) /* hpux */
|
|
||||||
/* Non blocking sockets doesn't work good on HPUX 11.0 */
|
|
||||||
(void) ioctl(sd,FIOSNBIO,0);
|
|
||||||
#endif
|
|
||||||
#else /* !defined(_WIN32) && !defined(__EMX__) */
|
|
||||||
{
|
|
||||||
/* set to blocking mode by default */
|
|
||||||
ulong arg=0, r;
|
|
||||||
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg/*, sizeof(arg)*/);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (!(vio->cache= my_malloc(VIO_CACHE_SIZE, MYF(MY_WME))))
|
|
||||||
{
|
|
||||||
my_free(vio);
|
|
||||||
vio= NULL;
|
|
||||||
}
|
|
||||||
vio->cache_size= 0;
|
|
||||||
vio->cache_pos= vio->cache;
|
|
||||||
DBUG_RETURN(vio);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
Vio *vio_new_win32pipe(HANDLE hPipe)
|
|
||||||
{
|
|
||||||
Vio *vio;
|
|
||||||
DBUG_ENTER("vio_new_handle");
|
|
||||||
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_ZEROFILL))))
|
|
||||||
{
|
|
||||||
vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
|
|
||||||
strmov(vio->desc, "named pipe");
|
|
||||||
}
|
|
||||||
DBUG_RETURN(vio);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void vio_delete(Vio * vio)
|
|
||||||
{
|
|
||||||
/* It must be safe to delete null pointers. */
|
|
||||||
/* This matches the semantics of C++'s delete operator. */
|
|
||||||
if (vio)
|
|
||||||
{
|
|
||||||
if (vio->type != VIO_CLOSED)
|
|
||||||
vio_close(vio);
|
|
||||||
my_free(vio->cache);
|
|
||||||
my_free(vio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int vio_errno(Vio *vio __attribute__((unused)))
|
|
||||||
{
|
|
||||||
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
|
|
||||||
}
|
|
||||||
|
|
||||||
int vio_wait_or_timeout(Vio *vio, my_bool is_read, int timeout)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
#ifndef _WIN32
|
|
||||||
struct pollfd p_fd;
|
|
||||||
#else
|
|
||||||
struct timeval tv= {0,0};
|
|
||||||
fd_set fds, exc_fds;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* we don't support it via named pipes yet.
|
|
||||||
* maybe this could be handled via PeekNamedPipe somehow !? */
|
|
||||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Note that if zero timeout, then we will not block, so we do not need to
|
|
||||||
yield to calling application in the async case.
|
|
||||||
*/
|
|
||||||
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
|
||||||
{
|
|
||||||
rc= my_io_wait_async(vio->async_context,
|
|
||||||
(is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE,
|
|
||||||
timeout);
|
|
||||||
return(rc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifndef _WIN32
|
|
||||||
p_fd.fd= vio->sd;
|
|
||||||
p_fd.events= (is_read) ? POLLIN : POLLOUT;
|
|
||||||
|
|
||||||
do {
|
|
||||||
rc= poll(&p_fd, 1, timeout);
|
|
||||||
} while (rc == -1 || errno == EINTR);
|
|
||||||
|
|
||||||
if (rc == 0)
|
|
||||||
errno= ETIMEDOUT;
|
|
||||||
#else
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_ZERO(&exc_fds);
|
|
||||||
|
|
||||||
FD_SET(vio->sd, &fds);
|
|
||||||
FD_SET(vio->sd, &exc_fds);
|
|
||||||
|
|
||||||
if (timeout >= 0)
|
|
||||||
{
|
|
||||||
tv.tv_sec= timeout / 1000;
|
|
||||||
tv.tv_usec= (timeout % 1000) * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc= select(0, (is_read) ? &fds : NULL,
|
|
||||||
(is_read) ? NULL : &fds,
|
|
||||||
&exc_fds,
|
|
||||||
(timeout >= 0) ? &tv : NULL);
|
|
||||||
if (rc == SOCKET_ERROR)
|
|
||||||
errno= WSAGetLastError();
|
|
||||||
if (rc == 0)
|
|
||||||
errno= ETIMEDOUT;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t vio_real_read(Vio *vio, gptr buf, size_t size)
|
|
||||||
{
|
|
||||||
size_t r;
|
|
||||||
|
|
||||||
switch(vio->type) {
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
case VIO_TYPE_SSL:
|
|
||||||
return my_ssl_read(vio, (char *)buf, size);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
case VIO_TYPE_NAMEDPIPE:
|
|
||||||
{
|
|
||||||
DWORD length= 0;
|
|
||||||
if (!ReadFile(vio->hPipe, buf, (DWORD)size, &length, NULL))
|
|
||||||
return -1;
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
if (vio->async_context && vio->async_context->active)
|
|
||||||
r= my_recv_async(vio->async_context,
|
|
||||||
vio->sd,
|
|
||||||
buf, size, vio->read_timeout);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (vio->async_context)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If switching from non-blocking to blocking API usage, set the socket
|
|
||||||
back to blocking mode.
|
|
||||||
*/
|
|
||||||
my_bool old_mode;
|
|
||||||
vio_blocking(vio, TRUE, &old_mode);
|
|
||||||
}
|
|
||||||
#ifndef _WIN32
|
|
||||||
do {
|
|
||||||
r= read(vio->sd, buf, size);
|
|
||||||
} while (r == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
while (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
||||||
&& vio->read_timeout > 0)
|
|
||||||
{
|
|
||||||
if (vio_wait_or_timeout(vio, TRUE, vio->write_timeout) < 1)
|
|
||||||
return 0;
|
|
||||||
do {
|
|
||||||
r= read(vio->sd, buf, size);
|
|
||||||
} while (r == -1 && errno == EINTR);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
WSABUF wsaData;
|
|
||||||
DWORD dwBytes = 0;
|
|
||||||
DWORD flags = 0;
|
|
||||||
|
|
||||||
wsaData.len= size;
|
|
||||||
wsaData.buf= buf;
|
|
||||||
|
|
||||||
if (WSARecv(vio->sd, &wsaData, 1, &dwBytes, &flags, NULL, NULL) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
errno= WSAGetLastError();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
r= (size_t)dwBytes;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t vio_read(Vio * vio, gptr buf, size_t size)
|
|
||||||
{
|
|
||||||
size_t r;
|
|
||||||
DBUG_ENTER("vio_read");
|
|
||||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
|
||||||
|
|
||||||
if (!vio->cache)
|
|
||||||
DBUG_RETURN(vio_real_read(vio, buf, size));
|
|
||||||
|
|
||||||
if (vio->cache + vio->cache_size > vio->cache_pos)
|
|
||||||
{
|
|
||||||
r= MIN(size, vio->cache + vio->cache_size - vio->cache_pos);
|
|
||||||
memcpy(buf, vio->cache_pos, r);
|
|
||||||
vio->cache_pos+= r;
|
|
||||||
}
|
|
||||||
else if (size >= VIO_CACHE_MIN_SIZE)
|
|
||||||
{
|
|
||||||
r= vio_real_read(vio, buf, size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r= vio_real_read(vio, vio->cache, VIO_CACHE_SIZE);
|
|
||||||
if (r > 0)
|
|
||||||
{
|
|
||||||
if (size < r)
|
|
||||||
{
|
|
||||||
vio->cache_size= r; /* might be < VIO_CACHE_SIZE */
|
|
||||||
vio->cache_pos= vio->cache + size;
|
|
||||||
r= size;
|
|
||||||
}
|
|
||||||
memcpy(buf, vio->cache, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
if ((size_t)r == -1)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
|
|
||||||
}
|
|
||||||
#endif /* DBUG_OFF */
|
|
||||||
DBUG_PRINT("exit", ("%u", (uint)r));
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Return data from the beginning of the receive queue without removing
|
|
||||||
that data from the queue. A subsequent receive call will return the same data.
|
|
||||||
*/
|
|
||||||
my_bool vio_read_peek(Vio *vio, size_t *bytes)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (ioctlsocket(vio->sd, FIONREAD, (unsigned long*)bytes))
|
|
||||||
return TRUE;
|
|
||||||
#else
|
|
||||||
char buffer[1024];
|
|
||||||
ssize_t length;
|
|
||||||
|
|
||||||
vio_blocking(vio, 0, 0);
|
|
||||||
length= recv(vio->sd, &buffer, sizeof(buffer), MSG_PEEK);
|
|
||||||
if (length < 0)
|
|
||||||
return TRUE;
|
|
||||||
*bytes= length;
|
|
||||||
#endif
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t vio_write(Vio * vio, const gptr buf, size_t size)
|
|
||||||
{
|
|
||||||
size_t r;
|
|
||||||
DBUG_ENTER("vio_write");
|
|
||||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
if (vio->type == VIO_TYPE_SSL)
|
|
||||||
{
|
|
||||||
r= my_ssl_write(vio, (uchar *)buf, size);
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
if ( vio->type == VIO_TYPE_NAMEDPIPE)
|
|
||||||
{
|
|
||||||
DWORD length;
|
|
||||||
if (!WriteFile(vio->hPipe, (char*) buf, (DWORD)size, &length, NULL))
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
DBUG_RETURN(length);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (vio->async_context && vio->async_context->active)
|
|
||||||
r= my_send_async(vio->async_context, vio->sd, buf, size,
|
|
||||||
vio->write_timeout);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (vio->async_context)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If switching from non-blocking to blocking API usage, set the socket
|
|
||||||
back to blocking mode.
|
|
||||||
*/
|
|
||||||
my_bool old_mode;
|
|
||||||
vio_blocking(vio, TRUE, &old_mode);
|
|
||||||
}
|
|
||||||
#ifndef _WIN32
|
|
||||||
do {
|
|
||||||
r= send(vio->sd, buf, size, vio->write_timeout ? MSG_DONTWAIT : MSG_WAITALL);
|
|
||||||
} while (r == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
while (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
|
|
||||||
vio->write_timeout > 0)
|
|
||||||
{
|
|
||||||
if (vio_wait_or_timeout(vio, FALSE, vio->write_timeout) < 1)
|
|
||||||
return 0;
|
|
||||||
do {
|
|
||||||
r= send(vio->sd, buf, size, vio->write_timeout ? MSG_DONTWAIT : MSG_WAITALL);
|
|
||||||
} while (r == -1 && errno == EINTR);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
WSABUF wsaData;
|
|
||||||
DWORD dwBytes = 0;
|
|
||||||
|
|
||||||
wsaData.len= size;
|
|
||||||
wsaData.buf= (char *)buf;
|
|
||||||
|
|
||||||
if (WSASend(vio->sd, &wsaData, 1, &dwBytes, 0, NULL, NULL) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
errno= WSAGetLastError();
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
r= (size_t)dwBytes;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifndef DBUG_OFF
|
|
||||||
if ((size_t)r == -1)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
|
|
||||||
}
|
|
||||||
#endif /* DBUG_OFF */
|
|
||||||
DBUG_PRINT("exit", ("%u", (uint)r));
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vio_blocking(Vio *vio, my_bool block, my_bool *previous_mode)
|
|
||||||
{
|
|
||||||
int *sd_flags= &vio->fcntl_mode;
|
|
||||||
int save_flags= vio->fcntl_mode;
|
|
||||||
my_bool tmp;
|
|
||||||
my_socket sock= vio->sd;
|
|
||||||
|
|
||||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!previous_mode)
|
|
||||||
previous_mode= &tmp;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
*previous_mode= (*sd_flags & O_NONBLOCK) != 0;
|
|
||||||
*sd_flags = (block) ? *sd_flags & ~O_NONBLOCK : *sd_flags | O_NONBLOCK;
|
|
||||||
{
|
|
||||||
ulong arg= 1 - block;
|
|
||||||
if (ioctlsocket(sock, FIONBIO, (void *)&arg))
|
|
||||||
{
|
|
||||||
vio->fcntl_mode= save_flags;
|
|
||||||
return(WSAGetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#if defined(O_NONBLOCK)
|
|
||||||
*previous_mode= (*sd_flags & O_NONBLOCK) != 0;
|
|
||||||
*sd_flags = (block) ? *sd_flags & ~O_NONBLOCK : *sd_flags | O_NONBLOCK;
|
|
||||||
#elif defined(O_NDELAY)
|
|
||||||
*previous_mode= (*sd_flags & O_NODELAY) != 0;
|
|
||||||
*sd_flags = (block) ? *sd_flags & ~O_NODELAY : *sd_flags | O_NODELAY;
|
|
||||||
#elif defined(FNDELAY)
|
|
||||||
*previous_mode= (*sd_flags & O_FNDELAY) != 0;
|
|
||||||
*sd_flags = (block) ? *sd_flags & ~O_FNDELAY : *sd_flags | O_FNDELAY;
|
|
||||||
#else
|
|
||||||
#error socket blocking is not supported on this platform
|
|
||||||
#endif
|
|
||||||
if (fcntl(sock, F_SETFL, *sd_flags) == -1)
|
|
||||||
{
|
|
||||||
vio->fcntl_mode= save_flags;
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
my_bool
|
|
||||||
vio_is_blocking(Vio * vio)
|
|
||||||
{
|
|
||||||
my_bool r;
|
|
||||||
DBUG_ENTER("vio_is_blocking");
|
|
||||||
r = !(vio->fcntl_mode & O_NONBLOCK);
|
|
||||||
DBUG_PRINT("exit", ("%d", (int) r));
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vio_fastsend(Vio * vio __attribute__((unused)))
|
|
||||||
{
|
|
||||||
int r=0;
|
|
||||||
DBUG_ENTER("vio_fastsend");
|
|
||||||
|
|
||||||
#ifdef IPTOS_THROUGHPUT
|
|
||||||
{
|
|
||||||
#ifndef __EMX__
|
|
||||||
int tos = IPTOS_THROUGHPUT;
|
|
||||||
if (!setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos)))
|
|
||||||
#endif /* !__EMX__ */
|
|
||||||
{
|
|
||||||
int nodelay = 1;
|
|
||||||
if (setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void *) &nodelay,
|
|
||||||
sizeof(nodelay))) {
|
|
||||||
DBUG_PRINT("warning",
|
|
||||||
("Couldn't set socket option for fast send"));
|
|
||||||
r= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* IPTOS_THROUGHPUT */
|
|
||||||
DBUG_PRINT("exit", ("%d", r));
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
|
|
||||||
{
|
|
||||||
int r=0;
|
|
||||||
uint opt = 0;
|
|
||||||
DBUG_ENTER("vio_keepalive");
|
|
||||||
DBUG_PRINT("enter", ("sd=%d set_keep_alive=%d", vio->sd, (int)
|
|
||||||
set_keep_alive));
|
|
||||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
|
||||||
{
|
|
||||||
if (set_keep_alive)
|
|
||||||
opt = 1;
|
|
||||||
r = setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
|
|
||||||
sizeof(opt));
|
|
||||||
}
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my_bool
|
|
||||||
vio_should_retry(Vio * vio __attribute__((unused)))
|
|
||||||
{
|
|
||||||
int en = socket_errno;
|
|
||||||
return en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vio_close(Vio * vio)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
DBUG_ENTER("vio_close");
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
if (vio->type == VIO_TYPE_SSL)
|
|
||||||
{
|
|
||||||
r = my_ssl_close(vio);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (vio->type == VIO_TYPE_NAMEDPIPE)
|
|
||||||
{
|
|
||||||
r=CloseHandle(vio->hPipe);
|
|
||||||
}
|
|
||||||
else if (vio->type != VIO_CLOSED)
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
{
|
|
||||||
r=0;
|
|
||||||
if (shutdown(vio->sd,2))
|
|
||||||
r= -1;
|
|
||||||
if (closesocket(vio->sd))
|
|
||||||
r= -1;
|
|
||||||
}
|
|
||||||
if (r)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
|
|
||||||
/* FIXME: error handling (not critical for MySQL) */
|
|
||||||
}
|
|
||||||
vio->type= VIO_CLOSED;
|
|
||||||
vio->sd= -1;
|
|
||||||
DBUG_RETURN(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *vio_description(Vio * vio)
|
|
||||||
{
|
|
||||||
return vio->desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum enum_vio_type vio_type(Vio* vio)
|
|
||||||
{
|
|
||||||
return vio->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
my_socket vio_fd(Vio* vio)
|
|
||||||
{
|
|
||||||
return vio->sd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my_bool vio_peer_addr(Vio * vio, char *buf)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("vio_peer_addr");
|
|
||||||
DBUG_PRINT("enter", ("sd=%d", vio->sd));
|
|
||||||
if (vio->localhost)
|
|
||||||
{
|
|
||||||
strmov(buf,"127.0.0.1");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
socklen_t addrLen = sizeof(struct sockaddr);
|
|
||||||
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
|
|
||||||
&addrLen) != 0)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
my_inet_ntoa(vio->remote.sin_addr,buf);
|
|
||||||
}
|
|
||||||
DBUG_PRINT("exit", ("addr=%s", buf));
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void vio_in_addr(Vio *vio, struct in_addr *in)
|
|
||||||
{
|
|
||||||
DBUG_ENTER("vio_in_addr");
|
|
||||||
if (vio->localhost)
|
|
||||||
bzero((char*) in, sizeof(*in)); /* This should never be executed */
|
|
||||||
else
|
|
||||||
*in=vio->remote.sin_addr;
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return 0 if there is data to be read */
|
|
||||||
/*
|
|
||||||
my_bool vio_poll_read(Vio *vio,uint timeout)
|
|
||||||
{
|
|
||||||
#ifndef HAVE_POLL
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
struct pollfd fds;
|
|
||||||
int res;
|
|
||||||
DBUG_ENTER("vio_poll");
|
|
||||||
fds.fd=vio->sd;
|
|
||||||
fds.events=POLLIN;
|
|
||||||
fds.revents=0;
|
|
||||||
if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
|
|
||||||
{
|
|
||||||
DBUG_RETURN(res < 0 ? 0 : 1);
|
|
||||||
}
|
|
||||||
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* HAVE_VIO */
|
|
@@ -94,6 +94,7 @@ mysql_declare_client_plugin(REMOTEIO)
|
|||||||
"Georg Richter",
|
"Georg Richter",
|
||||||
"Remote IO plugin",
|
"Remote IO plugin",
|
||||||
{0,1,0},
|
{0,1,0},
|
||||||
|
"LGPL",
|
||||||
ma_rio_init,
|
ma_rio_init,
|
||||||
ma_rio_deinit,
|
ma_rio_deinit,
|
||||||
&ma_rio_methods
|
&ma_rio_methods
|
||||||
|
@@ -62,7 +62,7 @@ ENDIF()
|
|||||||
|
|
||||||
FOREACH(API_TEST ${API_TESTS})
|
FOREACH(API_TEST ${API_TESTS})
|
||||||
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c)
|
ADD_EXECUTABLE(${API_TEST} ${API_TEST}.c)
|
||||||
TARGET_LINK_LIBRARIES(${API_TEST} mytap mariadbclient ${EXTRA_LIBS})
|
TARGET_LINK_LIBRARIES(${API_TEST} mytap libmariadb ${EXTRA_LIBS})
|
||||||
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
|
ADD_TEST(${API_TEST} ${EXECUTABLE_OUTPUT_PATH}/${API_TEST})
|
||||||
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
|
SET_TESTS_PROPERTIES(${API_TEST} PROPERTIES TIMEOUT 120)
|
||||||
ENDFOREACH(API_TEST)
|
ENDFOREACH(API_TEST)
|
||||||
|
@@ -177,35 +177,6 @@ static int test_bug31418(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
|
|
||||||
should not crash server and should not hang in case of errors.
|
|
||||||
|
|
||||||
Since those functions can't be seen in modern API (unless client library
|
|
||||||
was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
|
|
||||||
*/
|
|
||||||
static int test_bug6081(MYSQL *mysql)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (mysql_get_server_version(mysql) < 50100) {
|
|
||||||
diag("Test requires MySQL Server version 5.1 or above");
|
|
||||||
return SKIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc= simple_command(mysql, MYSQL_COM_DROP_DB, (char*) schema,
|
|
||||||
(ulong)strlen(schema), 0U, NULL);
|
|
||||||
FAIL_IF(!rc, "Error expected");
|
|
||||||
|
|
||||||
rc= simple_command(mysql, MYSQL_COM_CREATE_DB, (char*) schema,
|
|
||||||
(ulong)strlen(schema), 0U, NULL);
|
|
||||||
FAIL_IF(!rc, "Error expected");
|
|
||||||
|
|
||||||
rc= mysql_select_db(mysql, schema);
|
|
||||||
check_mysql_rc(rc, mysql);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Query processing */
|
/* Query processing */
|
||||||
|
|
||||||
static int test_debug_example(MYSQL *mysql)
|
static int test_debug_example(MYSQL *mysql)
|
||||||
@@ -1051,8 +1022,8 @@ static int test_remote2(MYSQL *my)
|
|||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
{"test_remote1", test_remote1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_remote1", test_remote1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_remote2", test_remote2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_remote2", test_remote2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc117", test_conc117, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc117", test_conc117, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc_114", test_conc_114, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc_114", test_conc_114, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_connect_attrs", test_connect_attrs, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_connect_attrs", test_connect_attrs, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc49", test_conc49, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc49", test_conc49, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
@@ -1061,7 +1032,6 @@ struct my_tests_st my_tests[] = {
|
|||||||
{"test_debug_example", test_debug_example, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_debug_example", test_debug_example, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_bug29692", test_bug29692, TEST_CONNECTION_NEW, CLIENT_FOUND_ROWS, NULL, NULL},
|
{"test_bug29692", test_bug29692, TEST_CONNECTION_NEW, CLIENT_FOUND_ROWS, NULL, NULL},
|
||||||
{"test_bug31418", test_bug31418, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_bug31418", test_bug31418, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_bug6081", test_bug6081, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
|
||||||
{"test_frm_bug", test_frm_bug, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_frm_bug", test_frm_bug, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_wl4166_1", test_wl4166_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_wl4166_1", test_wl4166_1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_wl4166_2", test_wl4166_2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_wl4166_2", test_wl4166_2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
|
@@ -507,7 +507,9 @@ void run_tests(struct my_tests_st *test) {
|
|||||||
return; /* default doesn't work anymore */
|
return; /* default doesn't work anymore */
|
||||||
}
|
}
|
||||||
else if (mysql && !(test[i].connection & TEST_CONNECTION_DONT_CLOSE))
|
else if (mysql && !(test[i].connection & TEST_CONNECTION_DONT_CLOSE))
|
||||||
|
{
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
skip(1, "%s", test[i].skipmsg);
|
skip(1, "%s", test[i].skipmsg);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user