summaryrefslogtreecommitdiff
path: root/sql-common
diff options
context:
space:
mode:
authormonty@mashka.mysql.fi <>2003-08-19 00:08:08 +0300
committermonty@mashka.mysql.fi <>2003-08-19 00:08:08 +0300
commit4f7512160bfd467e5d53c3e133e1842fac2737ce (patch)
treedf4f8c8cf4d399e322333c5516d5c19507b1fda8 /sql-common
parent2263e3e51faba531a0a7055dbf706a6a8719ad70 (diff)
downloadmariadb-git-4f7512160bfd467e5d53c3e133e1842fac2737ce.tar.gz
After merge fixes
Use server character set if --default-character-set is not used Added convert_string() for more efficient alloc+character-set convert of strings
Diffstat (limited to 'sql-common')
-rw-r--r--sql-common/client.c121
1 files changed, 83 insertions, 38 deletions
diff --git a/sql-common/client.c b/sql-common/client.c
index f9219e5418d..222f0bf0288 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -134,6 +134,10 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name;
static void mysql_close_free_options(MYSQL *mysql);
static void mysql_close_free(MYSQL *mysql);
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+static int wait_for_data(my_socket fd, uint timeout);
+#endif
+
/****************************************************************************
A modified version of connect(). my_connect() allows you to specify
a timeout value, in seconds, that we should wait until we
@@ -143,17 +147,13 @@ static void mysql_close_free(MYSQL *mysql);
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-my_bool my_connect(my_socket s, const struct sockaddr *name,
- uint namelen, uint timeout)
+int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
+ uint timeout)
{
#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
- return connect(s, (struct sockaddr*) name, namelen) != 0;
+ return connect(fd, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
- SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
- fd_set sfds;
- struct timeval tv;
- time_t start_time, now_time;
/*
If they passed us a timeout of zero, we should behave
@@ -161,60 +161,98 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
*/
if (timeout == 0)
- return connect(s, (struct sockaddr*) name, namelen) != 0;
+ return connect(fd, (struct sockaddr*) name, namelen);
- flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
+ flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
#ifdef O_NONBLOCK
- fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
#endif
- res = connect(s, (struct sockaddr*) name, namelen);
- s_err = errno; /* Save the error... */
- fcntl(s, F_SETFL, flags);
+ res= connect(fd, (struct sockaddr*) name, namelen);
+ s_err= errno; /* Save the error... */
+ fcntl(fd, F_SETFL, flags);
if ((res != 0) && (s_err != EINPROGRESS))
{
- errno = s_err; /* Restore it */
- return(1);
+ errno= s_err; /* Restore it */
+ return(-1);
}
if (res == 0) /* Connected quickly! */
return(0);
+ return wait_for_data(fd, timeout);
+#endif
+}
+
+
+/*
+ Wait up to timeout seconds for a connection to be established.
+
+ We prefer to do this with poll() as there is no limitations with this.
+ If not, we will use select()
+*/
+
+#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
+
+static int wait_for_data(my_socket fd, uint timeout)
+{
+#ifdef HAVE_POLL
+ struct pollfd ufds;
+ int res;
+
+ ufds.fd= fd;
+ ufds.events= POLLIN | POLLPRI;
+ if (!(res= poll(&ufds, 1, (int) timeout*1000)))
+ {
+ errno= EINTR;
+ return -1;
+ }
+ if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+ return -1;
+ return 0;
+#else
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
+ fd_set sfds;
+ struct timeval tv;
+ time_t start_time, now_time;
+ int res, s_err;
+
+ if (fd >= FD_SETSIZE) /* Check if wrong error */
+ return 0; /* Can't use timeout */
/*
- Otherwise, our connection is "in progress." We can use
- the select() call to wait up to a specified period of time
- for the connection to succeed. If select() returns 0
- (after waiting howevermany seconds), our socket never became
- writable (host is probably unreachable.) Otherwise, if
+ Our connection is "in progress." We can use the select() call to wait
+ up to a specified period of time for the connection to suceed.
+ If select() returns 0 (after waiting howevermany seconds), our socket
+ never became writable (host is probably unreachable.) Otherwise, if
select() returns 1, then one of two conditions exist:
-
+
1. An error occured. We use getsockopt() to check for this.
2. The connection was set up sucessfully: getsockopt() will
return 0 as an error.
-
+
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
who posted this method of timing out a connect() in
comp.unix.programmer on August 15th, 1997.
*/
FD_ZERO(&sfds);
- FD_SET(s, &sfds);
+ FD_SET(fd, &sfds);
/*
- select could be interrupted by a signal, and if it is,
+ select could be interrupted by a signal, and if it is,
the timeout should be adjusted and the select restarted
- to work around OSes that don't restart select and
+ to work around OSes that don't restart select and
implementations of select that don't adjust tv upon
failure to reflect the time remaining
- */
+ */
start_time = time(NULL);
for (;;)
{
tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
#if defined(HPUX10) && defined(THREAD)
- if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
+ if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
break;
#else
- if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
+ if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
break;
#endif
if (res == 0) /* timeout */
@@ -222,7 +260,7 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
now_time=time(NULL);
timeout-= (uint) (now_time - start_time);
if (errno != EINTR || (int) timeout <= 0)
- return 1;
+ return -1;
}
/*
@@ -232,18 +270,19 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
*/
s_err=0;
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
- return(1);
+ if (getsockopt(fd, 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(-1); /* but return an error... */
}
return (0); /* ok */
-
-#endif
+#endif /* HAVE_POLL */
}
+#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */
+
/*
Create a named pipe connection
@@ -1452,6 +1491,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
struct sockaddr_in sock_addr;
ulong pkt_length;
NET *net= &mysql->net;
+ uint charset_number;
#ifdef MYSQL_SERVER
thr_alarm_t alarmed;
ALARM alarm_buff;
@@ -1744,17 +1784,19 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->server_language=end[2];
mysql->server_status=uint2korr(end+3);
}
+ charset_number= mysql->server_language;
/* Set character set */
if ((charset_name=mysql->options.charset_name))
{
- const char *save=charsets_dir;
+ const char *save= charsets_dir;
if (mysql->options.charset_dir)
charsets_dir=mysql->options.charset_dir;
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
MY_CS_PRIMARY,
MYF(MY_WME));
- charsets_dir=save;
+ charset_number= mysql->charset ? mysql->charset->number : 0;
+ charsets_dir= save;
}
else if (mysql->server_language)
{
@@ -1766,7 +1808,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->charset = default_charset_info; /* shouldn't be fatal */
}
else
- mysql->charset=default_charset_info;
+ {
+ mysql->charset= default_charset_info;
+ charset_number= mysql->charset->number;
+ }
if (!mysql->charset)
{
@@ -1846,7 +1891,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* 4.1 server and 4.1 client has a 32 byte option flag */
int4store(buff,client_flag);
int4store(buff+4, net->max_packet_size);
- buff[8]= mysql->charset->number;
+ buff[8]= (char) charset_number;
bzero(buff+9, 32-9);
end= buff+32;
}