summaryrefslogtreecommitdiff
path: root/libmysql
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2002-07-23 18:31:22 +0300
committerunknown <monty@mashka.mysql.fi>2002-07-23 18:31:22 +0300
commita8caad316a89d6eeb8c22e70bc7a5fd4cf6ce904 (patch)
tree2e458857fc65791ee553b4cde0e28ef9459050a5 /libmysql
parent6b3e98d505297e6cbd0cbd22d4f46eacb091d924 (diff)
downloadmariadb-git-a8caad316a89d6eeb8c22e70bc7a5fd4cf6ce904.tar.gz
New SET syntax & system variables.
Made a some new buffers thread specific and changeable. Resize of key_buffer. AUTO_COMMIT -> AUTOCOMMIT Fixed mutex bug in DROP DATABASE Fixed bug when using auto_increment as second part of a key where first part could include NULL. Split handler->extra() to extra() and extra_opt() to be able to support thread specific buffers. Don't write message to error log when slave reconnects becasue of timeout. Fixed possible update problem when using DELETE/UPDATE on small tables (In some cases we used index even if table scanning would be better) A lot of minior code cleanups BitKeeper/deleted/.del-net.c~ef21d6402bb882f9: Delete: libmysql/net.c BitKeeper/etc/ignore: added libmysql/net.c Docs/manual.texi: New SET syntax & system variables. client/client_priv.h: moved order of include files client/mysql.cc: Removed compiler warning client/mysqladmin.c: Use new SHOW GLOBAL syntax (if server supports it) configure.in: version change include/Makefile.am: indentation cleanup include/my_getopt.h: Made some helper functions global include/my_sys.h: Removed not used code include/myisam.h: Added extra argument to ..._extra() include/myisammrg.h: Added extra argument to ..._extra() include/mysql_com.h: changed NET to be able to support changeable system variables include/mysql_embed.h: Added MYSQL_SERVER_SUFFIX include/mysql_version.h.in: Added check of multiple including (needed for embedded library) include/mysqld_error.h: New error messages innobase/dict/dict0dict.c: Remove compiler warnings innobase/include/ut0mem.h: Remove compiler warnings innobase/include/ut0mem.ic: Remove compiler warnings isam/isamchk.c: new init_key_cache() arguments isam/isamlog.c: new init_key_cache() arguments isam/test2.c: new init_key_cache() arguments isam/test3.c: new init_key_cache() arguments libmysql/Makefile.am: Removed net.c (Automaticly make it from net_serv.cc) libmysql/Makefile.shared: Removed net.c (Automaticly make it from net_serv.cc) libmysql/libmysql.c: Changeable system variables libmysqld/Makefile.am: Added set_var.cc file libmysqld/embedded_priv.h: Changed order of include fiels libmysqld/lib_sql.cc: merge with mysqld.cc (for changeable variables) libmysqld/libmysqld.c: New changeable system variables myisam/mi_check.c: Added extra argument to ..._extra() myisam/mi_extra.c: Added extra argument to ..._extra() myisam/mi_open.c: Removed not used variable myisam/mi_test1.c: Changed call to init_key_cache myisam/mi_test2.c: Added extra argument to ..._extra() myisam/mi_test3.c: Added extra argument to ..._extra() myisam/mi_write.c: Add cache size argument to bulk-insert-init myisam/myisamchk.c: Use new key cache myisam/myisamdef.h: new mi_init_bulk_insert() arguments myisam/myisamlog.c: Added extra argument to ..._extra() myisam/myisampack.c: Added extra argument to ..._extra() myisammrg/myrg_extra.c: Added extra argument to ..._extra() myisammrg/myrg_rrnd.c: Added extra argument to ..._extra() mysql-test/r/insert_select.result: New changeable system variables mysql-test/r/key.result: Test of bug in auto_increment mysql-test/r/query_cache.result: New changeable system variables mysql-test/r/rpl000001.result: New changeable system variables mysql-test/r/rpl000016.result: New changeable system variables mysql-test/r/union.result: New changeable system variables mysql-test/r/user_var.result: New changeable system variables mysql-test/r/variables.result: New changeable system variables mysql-test/t/key.test: Test of bug in auto_increment mysql-test/t/query_cache.test: New changeable system variables mysql-test/t/rpl000001.test: New changeable system variables mysql-test/t/rpl000009.test: New changeable system variables mysql-test/t/rpl000016.test: New changeable system variables mysql-test/t/rpl_compat.test: New changeable system variables mysql-test/t/union.test: New changeable system variables mysql-test/t/user_var.test: New changeable system variables mysql-test/t/variables.test: New changeable system variables mysys/default.c: Bigger default memory allocation mysys/mf_iocache.c: Removed compiler warning mysys/mf_keycache.c: Made key cache resizable on the fly Removed not needed extra argument to init_key_cache() mysys/my_getopt.c: Made some helper functions global sql/Makefile.am: Aded set_var.cc sql/convert.cc: Comment cleanup sql/field.cc: new changeable system variables sql/filesort.cc: new changeable system variables sql/ha_berkeley.cc: AUTO_COMMIT -> AUTOCOMMIT sql/ha_innodb.cc: new changeable system variables sql/ha_myisam.cc: Added extra argument to ..._extra() sql/ha_myisam.h: Added extra argument to ..._extra() sql/ha_myisammrg.cc: Added extra argument to ..._extra() sql/ha_myisammrg.h: Added extra argument to ..._extra() sql/handler.cc: Added extra argument to ..._extra() Added resize of key cache Change ha_table_typelib for use with new system variables sql/handler.h: Added extra argument to ..._extra() sql/item.cc: new changeable system variables sql/item.h: Added better support of Item_uint sql/item_func.cc: Added support for SET @@[global | session] system_variable sql/item_strfunc.cc: new changeable system variables sql/key.cc: Fixed bug in auto_increment on second part keys sql/lex.h: Removed not needed keywords sql/log.cc: new changeable system variables sql/log_event.cc: new changeable system variables sql/log_event.h: Removed not needed var reference sql/mini_client.cc: new changeable system variables code cleanup sql/mini_client.h: Indentation cleanup sql/mysql_priv.h: Changed order of include files & variables to make file more readable sql/mysqld.cc: Changed order of variables to make file more readable. Support for changeable variables Rename of system variables Moved init_vars to set_var.cc Changed output of --help sql/net_pkg.cc: Added my_net_local_init() to make it possible to set different defaults for network connection depending if you are a client, embedded library or server. sql/net_serv.cc: new changeable system variables To support this, some global variables had to be move to the NET structure. sql/records.cc: new changeable system variables use extra_opt() sql/repl_failsafe.cc: new changeable system variables minior code cleanups sql/repl_failsafe.h: removed not needed external var reference sql/share/czech/errmsg.txt: new changeable system variables sql/share/danish/errmsg.txt: new changeable system variables sql/share/dutch/errmsg.txt: new changeable system variables sql/share/english/errmsg.txt: new changeable system variables sql/share/estonian/errmsg.txt: new changeable system variables sql/share/french/errmsg.txt: new changeable system variables sql/share/german/errmsg.txt: new changeable system variables sql/share/greek/errmsg.txt: new changeable system variables sql/share/hungarian/errmsg.txt: new changeable system variables sql/share/italian/errmsg.txt: new changeable system variables sql/share/japanese/errmsg.txt: new changeable system variables sql/share/korean/errmsg.txt: new changeable system variables sql/share/norwegian-ny/errmsg.txt: new changeable system variables sql/share/norwegian/errmsg.txt: new changeable system variables sql/share/polish/errmsg.txt: new changeable system variables sql/share/portuguese/errmsg.txt: new changeable system variables sql/share/romanian/errmsg.txt: new changeable system variables sql/share/russian/errmsg.txt: new changeable system variables sql/share/slovak/errmsg.txt: new changeable system variables sql/share/spanish/errmsg.txt: new changeable system variables sql/share/swedish/errmsg.txt: new changeable system variables sql/share/ukrainian/errmsg.txt: new changeable system variables sql/slave.cc: new changeable system variables Added some suppression of error messages Initialize current_thd for all slave threads. sql/sql_acl.cc: Added checking of arguments for SET PASSWORD (for new SET defintion) sql/sql_acl.h: new prototypes sql/sql_base.cc: new changeable system variables sql/sql_cache.cc: new changeable system variables sql/sql_cache.h: Renamed some arguments to make code more readable sql/sql_class.cc: new changeable system variables sql/sql_class.h: New changeable system variables Code cleanup sql/sql_db.cc: Fixed bug in DROP DATABASE sql/sql_delete.cc: Usage of wrong define in test (possible speed problem) sql/sql_insert.cc: use extra_opt() Code cleanup sql/sql_lex.cc: Added support for SET @@[global | session] system_variable sql/sql_lex.h: Added support for SET @@[global | session] system_variable sql/sql_load.cc: Cleanup for embedded library Use extra_opt() sql/sql_parse.cc: Cleanup for embedded library New changeable system variables sql/sql_repl.cc: new changeable system variables sql/sql_repl.h: Fixed variable definitions sql/sql_select.cc: new changeable system variables sql/sql_show.cc: New changeable system variables sql/sql_table.cc: Fixed bug in DROP DATABASE sql/sql_union.cc: New changeable system variables sql/sql_update.cc: Usage of wrong define in test (possible speed problem) sql/sql_yacc.yy: New changeable system variables sql/structs.h: Added typedef for SHOW_VAR sql/table.cc: Fixed bug in auto_increment on second part keys sql/uniques.cc: Comment fix sql/unireg.h: A
Diffstat (limited to 'libmysql')
-rw-r--r--libmysql/Makefile.am12
-rw-r--r--libmysql/Makefile.shared9
-rw-r--r--libmysql/libmysql.c16
-rw-r--r--libmysql/net.c826
4 files changed, 28 insertions, 835 deletions
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index 2eaf9709a36..3d380c14076 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -17,9 +17,9 @@
# This file is public domain and comes with NO WARRANTY of any kind
-target = libmysqlclient.la
-target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
-LIBS = @CLIENT_LIBS@
+target = libmysqlclient.la
+target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -DMYSQL_CLIENT
+LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
@@ -60,7 +60,9 @@ link_sources:
for f in $$ms $(mysysheaders); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
- done;
+ done; \
+ rm -f $(srcdir)/net.c; \
+ @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c
# This part requires GNUmake
#
@@ -77,7 +79,7 @@ nh = my_global.h config-win32.h dbug.h errmsg.h \
mysql.h mysql_com.h mysql_version.h mysqld_error.h \
mysys_err.h my_pthread.h thr_alarm.h violite.h hash.h
# Get a list of the needed objects
-lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects)
+lobjs = $(mysysobjects1) $(dbugobjects) $(mystringsobjects) $(sqlobjects)
do-lib-dist:
dir=libmysql-$(MYSQL_NO_DASH_VERSION); \
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 1e36a74ab12..87f9fe42a3c 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -31,8 +31,8 @@ noinst_PROGRAMS = conf_to_src
CHARSET_OBJS=@CHARSET_OBJS@
LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo}
-target_sources = libmysql.c net.c password.c manager.c \
- get_password.c errmsg.c
+target_sources = libmysql.c password.c manager.c \
+ get_password.c errmsg.c
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
strmake.lo strend.lo \
@@ -60,12 +60,13 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_iocache2.lo my_seek.lo \
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo \
my_getopt.lo my_gethostbyname.lo
+sqlobjects = net.lo
# Not needed in the minimum library
mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
- $(vio_objects)
+ $(vio_objects) $(sqlobjects)
target_ldflags = -version-info @SHARED_LIB_VERSION@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
@@ -84,7 +85,7 @@ clean-local:
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
`echo $(vio_objects) | sed "s;\.lo;.c;g"` \
$(mystringsextra) $(mysysheaders) ctype_extra_sources.c \
- ../linked_client_sources
+ net.c ../linked_client_sources
ctype_extra_sources.c: conf_to_src
./conf_to_src $(top_srcdir) @CHARSETS_NEED_SOURCE@ > \
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index fa505063deb..458e5db24d5 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -59,6 +59,10 @@
static my_bool mysql_client_init=0;
uint mysql_port=0;
my_string mysql_unix_port=0;
+ulong net_buffer_length=8192;
+ulong max_allowed_packet=16*1024*1024L;
+ulong net_read_timeout= NET_READ_TIMEOUT;
+ulong net_write_timeout= NET_WRITE_TIMEOUT;
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS)
@@ -2890,6 +2894,18 @@ uint STDCALL mysql_thread_safe(void)
****************************************************************************/
/*
+ Functions called my my_net_init() to set some application specific variables
+*/
+
+void my_net_local_init(NET *net)
+{
+ net->max_packet= (uint) net_buffer_length;
+ net->read_timeout= (uint) net_read_timeout;
+ net->write_timeout=(uint) net_write_timeout;
+ net->max_packet_size= max(net_buffer_length, max_allowed_packet);
+}
+
+/*
Add escape characters to a string (blob?) to make it suitable for a insert
to should at least have place for length*2+1 chars
Returns the length of the to string
diff --git a/libmysql/net.c b/libmysql/net.c
deleted file mode 100644
index 0d6e548a873..00000000000
--- a/libmysql/net.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/* Write and read of logical packets to/from socket
-** Writes are cached into net_buffer_length big packets.
-** Read packets are reallocated dynamicly when reading big packets.
-** Each logical packet has the following pre-info:
-** 3 byte length & 1 byte package-number.
-*/
-
-#ifdef EMBEDDED_LIBRARY
-#define net_read_timeout net_read_timeout1
-#define net_write_timeout net_write_timeout1
-#endif
-
-#ifdef __WIN__
-#include <winsock.h>
-#endif
-#include <my_global.h>
-#include <mysql.h>
-#include <mysql_embed.h>
-#include <mysql_com.h>
-#include <mysqld_error.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <my_net.h>
-#include <violite.h>
-#include <signal.h>
-#include <errno.h>
-
-/*
- The following handles the differences when this is linked between the
- client and the server.
-
- This gives an error if a too big packet is found
- The server can change this with the -O switch, but because the client
- can't normally do this the client should have a bigger max_allowed_packet.
-*/
-
-#ifdef MYSQL_SERVER
-ulong max_allowed_packet=65536;
-extern ulong net_read_timeout,net_write_timeout;
-extern uint test_flags;
-#define USE_QUERY_CACHE
-extern void query_cache_insert(NET *net, const char *packet, ulong length);
-#else
-ulong max_allowed_packet=16*1024*1024L;
-ulong net_read_timeout= NET_READ_TIMEOUT;
-ulong net_write_timeout= NET_WRITE_TIMEOUT;
-#endif
-
-#if defined(__WIN__) || !defined(MYSQL_SERVER)
- /* The following is because alarms doesn't work on windows. */
-#define NO_ALARM
-#endif
-
-#ifndef NO_ALARM
-#include "my_pthread.h"
-void sql_print_error(const char *format,...);
-#define RETRY_COUNT mysqld_net_retry_count
-extern ulong mysqld_net_retry_count;
-extern ulong bytes_sent, bytes_received;
-extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
-#else
-#undef statistic_add
-#define statistic_add(A,B,C)
-#define DONT_USE_THR_ALARM
-#define RETRY_COUNT 1
-#endif /* NO_ALARM */
-
-#include "thr_alarm.h"
-
-#define TEST_BLOCKING 8
-#define MAX_THREE_BYTES 255L*255L*255L
-
-ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */
-
-static int net_write_buff(NET *net,const char *packet,ulong len);
-
-
- /* Init with packet info */
-
-int my_net_init(NET *net, Vio* vio)
-{
- if (!(net->buff=(uchar*) my_malloc((uint32) net_buffer_length+
- NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
- return 1;
- if (net_buffer_length > max_allowed_packet)
- max_allowed_packet=net_buffer_length;
- net->buff_end=net->buff+(net->max_packet=net_buffer_length);
- net->vio = vio;
- net->no_send_ok = 0;
- net->error=0; net->return_errno=0; net->return_status=0;
- net->timeout=(uint) net_read_timeout; /* Timeout for read */
- net->pkt_nr=net->compress_pkt_nr=0;
- net->write_pos=net->read_pos = net->buff;
- net->last_error[0]=0;
- net->compress=0; net->reading_or_writing=0;
- net->where_b = net->remain_in_buf=0;
- net->last_errno=0;
- net->query_cache_query=0;
-
- if (vio != 0) /* If real connection */
- {
- net->fd = vio_fd(vio); /* For perl DBI/DBD */
-#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
- if (!(test_flags & TEST_BLOCKING))
- vio_blocking(vio, FALSE);
-#endif
- vio_fastsend(vio);
- }
- return 0;
-}
-
-void net_end(NET *net)
-{
- my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR));
- net->buff=0;
-}
-
-/* Realloc the packet buffer */
-
-static my_bool net_realloc(NET *net, ulong length)
-{
- uchar *buff;
- ulong pkt_length;
- if (length >= max_allowed_packet)
- {
- DBUG_PRINT("error",("Packet too large (%lu)", length));
- net->error=1;
- net->last_errno=ER_NET_PACKET_TOO_LARGE;
- return 1;
- }
- pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
- /* We must allocate some extra bytes for the end 0 and to be able to
- read big compressed blocks */
- if (!(buff=(uchar*) my_realloc((char*) net->buff, (uint32) pkt_length +
- NET_HEADER_SIZE + COMP_HEADER_SIZE,
- MYF(MY_WME))))
- {
- net->error=1;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
-#endif
- return 1;
- }
- net->buff=net->write_pos=buff;
- net->buff_end=buff+(net->max_packet=pkt_length);
- return 0;
-}
-
- /* Remove unwanted characters from connection */
-
-void net_clear(NET *net)
-{
-#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
- int count; /* One may get 'unused' warn */
- bool is_blocking=vio_is_blocking(net->vio);
- if (is_blocking)
- vio_blocking(net->vio, FALSE);
- if (!vio_is_blocking(net->vio)) /* Safety if SSL */
- {
- while ( (count = vio_read(net->vio, (char*) (net->buff),
- (uint32) net->max_packet)) > 0)
- DBUG_PRINT("info",("skipped %d bytes from file: %s",
- count,vio_description(net->vio)));
- if (is_blocking)
- vio_blocking(net->vio, TRUE);
- }
-#endif /* EXTRA_DEBUG */
- net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
- net->write_pos=net->buff;
-}
-
- /* Flush write_buffer if not empty. */
-
-int net_flush(NET *net)
-{
- int error=0;
- DBUG_ENTER("net_flush");
- if (net->buff != net->write_pos)
- {
- error=net_real_write(net,(char*) net->buff,
- (ulong) (net->write_pos - net->buff));
- net->write_pos=net->buff;
- }
- /* Sync packet number if using compression */
- if (net->compress)
- net->pkt_nr=net->compress_pkt_nr;
- DBUG_RETURN(error);
-}
-
-
-/*****************************************************************************
-** Write something to server/client buffer
-*****************************************************************************/
-
-/*
-** Write a logical packet with packet header
-** Format: Packet length (3 bytes), packet number(1 byte)
-** When compression is used a 3 byte compression length is added
-** NOTE: If compression is used the original package is modified!
-*/
-
-int
-my_net_write(NET *net,const char *packet,ulong len)
-{
- uchar buff[NET_HEADER_SIZE];
- /*
- Big packets are handled by splitting them in packets of MAX_THREE_BYTES
- length. The last packet is always a packet that is < MAX_THREE_BYTES.
- (The last packet may even have a lengt of 0)
- */
- while (len >= MAX_THREE_BYTES)
- {
- const ulong z_size = MAX_THREE_BYTES;
- int3store(buff, z_size);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) ||
- net_write_buff(net, packet, z_size))
- return 1;
- packet += z_size;
- len-= z_size;
- }
- /* Write last packet */
- int3store(buff,len);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
- return 1;
- return net_write_buff(net,packet,len);
-}
-
-/*
- Send a command to the server.
- As the command is part of the first data packet, we have to do some data
- juggling to put the command in there, without having to create a new
- packet.
- This function will split big packets into sub-packets if needed.
- (Each sub packet can only be 2^24 bytes)
-*/
-
-int
-net_write_command(NET *net,uchar command,const char *packet,ulong len)
-{
- ulong length=len+1; /* 1 extra byte for command */
- uchar buff[NET_HEADER_SIZE+1];
- uint header_size=NET_HEADER_SIZE+1;
- buff[4]=command; /* For first packet */
-
- if (length >= MAX_THREE_BYTES)
- {
- /* Take into account that we have the command in the first header */
- len= MAX_THREE_BYTES -1;
- do
- {
- int3store(buff, MAX_THREE_BYTES);
- buff[3]= (uchar) net->pkt_nr++;
- if (net_write_buff(net,(char*) buff, header_size) ||
- net_write_buff(net,packet,len))
- return 1;
- packet+= len;
- length-= MAX_THREE_BYTES;
- len=MAX_THREE_BYTES;
- header_size=NET_HEADER_SIZE;
- } while (length >= MAX_THREE_BYTES);
- len=length; /* Data left to be written */
- }
- int3store(buff,length);
- buff[3]= (uchar) net->pkt_nr++;
- return test(net_write_buff(net,(char*) buff,header_size) ||
- net_write_buff(net,packet,len) || net_flush(net));
-}
-
-/*
- Caching the data in a local buffer before sending it.
- One can force the buffer to be flushed with 'net_flush'.
-*/
-
-static int
-net_write_buff(NET *net,const char *packet,ulong len)
-{
- ulong left_length=(ulong) (net->buff_end - net->write_pos);
-
- while (len > left_length)
- {
- memcpy((char*) net->write_pos,packet,left_length);
- if (net_real_write(net,(char*) net->buff,net->max_packet))
- return 1;
- net->write_pos=net->buff;
- packet+=left_length;
- len-=left_length;
- left_length=net->max_packet;
- }
- memcpy((char*) net->write_pos,packet,len);
- net->write_pos+=len;
- return 0;
-}
-
-
-/*
- Read and write one packet using timeouts.
- If needed, the packet is compressed before sending.
-*/
-
-int
-net_real_write(NET *net,const char *packet,ulong len)
-{
- long int length;
- char *pos,*end;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
- uint retry_count=0;
- my_bool net_blocking = vio_is_blocking(net->vio);
- DBUG_ENTER("net_real_write");
-
-#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE)
- if (net->query_cache_query != 0)
- query_cache_insert(net, packet, len);
-#endif
-
- if (net->error == 2)
- DBUG_RETURN(-1); /* socket can't be used */
-
- net->reading_or_writing=2;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- ulong complen;
- uchar *b;
- uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
- if (!(b=(uchar*) my_malloc((uint32) len + NET_HEADER_SIZE +
- COMP_HEADER_SIZE, MYF(MY_WME))))
- {
-#ifdef MYSQL_SERVER
- net->last_errno=ER_OUT_OF_RESOURCES;
- net->error=2;
-#endif
- net->reading_or_writing=0;
- DBUG_RETURN(1);
- }
- memcpy(b+header_length,packet,len);
-
- if (my_compress((byte*) b+header_length,&len,&complen))
- {
- DBUG_PRINT("warning",
- ("Compression error; Continuing without compression"));
- complen=0;
- }
- int3store(&b[NET_HEADER_SIZE],complen);
- int3store(b,len);
- b[3]=(uchar) (net->compress_pkt_nr++);
- len+= header_length;
- packet= (char*) b;
- }
-#endif /* HAVE_COMPRESS */
-
- /* DBUG_DUMP("net",packet,len); */
-#ifndef NO_ALARM
- thr_alarm_init(&alarmed);
- if (net_blocking)
- thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
-#else
- alarmed=0;
-#endif /* NO_ALARM */
-
- pos=(char*) packet; end=pos+len;
- while (pos != end)
- {
- if ((long) (length=vio_write(net->vio,pos,(uint32) (end-pos))) <= 0)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-#if (!defined(__WIN__) && !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)
- {
- 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 */
- goto end;
- }
- }
- retry_count=0;
- continue;
- }
- }
- else
-#endif /* (!defined(__WIN__) && !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 */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
- ER_NET_ERROR_ON_WRITE);
-#endif /* MYSQL_SERVER */
- break;
- }
- pos+=length;
- statistic_add(bytes_sent,length,&LOCK_bytes_sent);
- }
-#ifndef __WIN__
- end:
-#endif
-#ifdef HAVE_COMPRESS
- if (net->compress)
- my_free((char*) packet,MYF(0));
-#endif
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- DBUG_RETURN(((int) (pos != end)));
-}
-
-
-/*****************************************************************************
-** Read something from server/clinet
-*****************************************************************************/
-
-#ifndef NO_ALARM
-/*
- Help function to clear the commuication buffer when we get a too
- big packet
-*/
-
-static void my_net_skip_rest(NET *net, uint32 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))
- 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 -= (uint32) length;
- statistic_add(bytes_received,length,&LOCK_bytes_received);
- }
-}
-#endif /* NO_ALARM */
-
-
-/*
- Reads one packet to net->buff + net->where_b
- Returns length of packet. Long packets are handled by my_net_read().
- This function reallocates the net->buff buffer if necessary.
-*/
-
-static ulong
-my_real_read(NET *net, ulong *complen)
-{
- uchar *pos;
- long length;
- uint i,retry_count=0;
- ulong len=packet_error;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
- my_bool net_blocking=vio_is_blocking(net->vio);
- uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
- *complen = 0;
-
- net->reading_or_writing=1;
- thr_alarm_init(&alarmed);
-#ifndef NO_ALARM
- if (net_blocking)
- thr_alarm(&alarmed,net->timeout,&alarm_buff);
-#endif /* NO_ALARM */
-
- pos = net->buff + net->where_b; /* net->packet -4 */
- for (i=0 ; i < 2 ; i++)
- {
- while (remain > 0)
- {
- /* First read is done with non blocking mode */
- if ((int) (length=vio_read(net->vio,(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(__WIN__) && !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->timeout,&alarm_buff)) /* Don't wait too long */
- {
- if (!vio_is_blocking(net->vio))
- {
- while (vio_blocking(net->vio,TRUE) < 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(__WIN__) && !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: %lu errno: %d length: %ld alarmed: %d", remain,vio_errno(net->vio),length,alarmed));
- len= packet_error;
- net->error=2; /* Close socket */
-#ifdef MYSQL_SERVER
- net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED :
- ER_NET_READ_ERROR);
-#endif
- goto end;
- }
- remain -= (uint32) length;
- pos+= (ulong) length;
- statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received);
- }
- if (i == 0)
- { /* First parts is packet length */
- ulong helping;
- if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
- {
- if (net->buff[net->where_b] != (uchar) 255)
- {
- DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %u)",
- (int) net->buff[net->where_b + 3],
- net->pkt_nr));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n",
- (int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr);
-#endif
- }
- len= packet_error;
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
-#endif
- goto end;
- }
- net->compress_pkt_nr= ++net->pkt_nr;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- /* complen is > 0 if package is really compressed */
- *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
- }
-#endif
-
- len=uint3korr(net->buff+net->where_b);
- if (!len) /* End of big multi-packet */
- goto end;
- helping = max(len,*complen) + net->where_b;
- /* The necessary size of net->buff */
- if (helping >= net->max_packet)
- {
- if (net_realloc(net,helping))
- {
-#ifndef NO_ALARM
- if (i == 1)
- my_net_skip_rest(net, (uint32) len, &alarmed);
-#endif
- len= packet_error; /* Return error */
- goto end;
- }
- }
- pos=net->buff + net->where_b;
- remain = (uint32) len;
- }
- }
-
-end:
- if (thr_alarm_in_use(&alarmed))
- {
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking);
- }
- net->reading_or_writing=0;
- return(len);
-}
-
-
-/*
- Read a packet from the client/server and return it without the internal
- package header.
- If the packet is the first packet of a multi-packet packet
- (which is indicated by the length of the packet = 0xffffff) then
- all sub packets are read and concatenated.
- If the packet was compressed, its uncompressed and the length of the
- uncompressed packet is returned.
-
- The function returns the length of the found packet or packet_error.
- net->read_pos points to the read data.
-*/
-
-ulong
-my_net_read(NET *net)
-{
- ulong len,complen;
-
-#ifdef HAVE_COMPRESS
- if (!net->compress)
- {
-#endif
- len = my_real_read(net,&complen);
- if (len == MAX_THREE_BYTES)
- {
- /* First packet of a multi-packet. Concatenate the packets */
- ulong save_pos = net->where_b;
- ulong total_length=0;
- do
- {
- net->where_b += len;
- total_length += len;
- len = my_real_read (net,&complen);
- } while (len == MAX_THREE_BYTES);
- if (len != packet_error)
- len+= total_length;
- net->where_b = save_pos;
- }
- net->read_pos = net->buff + net->where_b;
- if (len != packet_error)
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- return len;
-#ifdef HAVE_COMPRESS
- }
- else
- {
- /* We are using the compressed protocol */
-
- ulong buf_length= net->buf_length;
- ulong start_of_packet= net->buf_length - net->remain_in_buf;
- ulong first_packet_offset=start_of_packet;
- uint read_length, multi_byte_packet=0;
-
- if (net->remain_in_buf)
- {
- /* Restore the character that was overwritten by the end 0 */
- net->buff[start_of_packet]=net->save_char;
- }
- else
- {
- /* reuse buffer, as there is noting in it that we need */
- buf_length=start_of_packet=first_packet_offset=0;
- }
- for (;;)
- {
- ulong packet_len;
-
- if (buf_length - start_of_packet >= NET_HEADER_SIZE)
- {
- read_length = uint3korr(net->buff+start_of_packet);
- if (!read_length)
- {
- /* End of multi-byte packet */
- start_of_packet += NET_HEADER_SIZE;
- break;
- }
- if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
- {
- if (multi_byte_packet)
- {
- /* Remove packet header for second packet */
- memmove(net->buff + first_packet_offset + start_of_packet,
- net->buff + first_packet_offset + start_of_packet +
- NET_HEADER_SIZE,
- buf_length - start_of_packet);
- start_of_packet += read_length;
- buf_length -= NET_HEADER_SIZE;
- }
- else
- start_of_packet+= read_length + NET_HEADER_SIZE;
-
- if (read_length != MAX_THREE_BYTES) /* last package */
- {
- multi_byte_packet= 0; /* No last zero len packet */
- break;
- }
- multi_byte_packet= NET_HEADER_SIZE;
- /* Move data down to read next data packet after current one */
- if (first_packet_offset)
- {
- memmove(net->buff,net->buff+first_packet_offset,
- buf_length-first_packet_offset);
- buf_length-=first_packet_offset;
- start_of_packet -= first_packet_offset;
- first_packet_offset=0;
- }
- continue;
- }
- }
- /* Move data down to read next data packet after current one */
- if (first_packet_offset)
- {
- memmove(net->buff,net->buff+first_packet_offset,
- buf_length-first_packet_offset);
- buf_length-=first_packet_offset;
- start_of_packet -= first_packet_offset;
- first_packet_offset=0;
- }
-
- net->where_b=buf_length;
- if ((packet_len = my_real_read(net,&complen)) == packet_error)
- return packet_error;
- if (my_uncompress((byte*) net->buff + net->where_b, &packet_len,
- &complen))
- {
- net->error=2; /* caller will close socket */
-#ifdef MYSQL_SERVER
- net->last_errno=ER_NET_UNCOMPRESS_ERROR;
-#endif
- return packet_error;
- }
- buf_length+=packet_len;
- }
-
- net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
- net->buf_length= buf_length;
- net->remain_in_buf= (ulong) (buf_length - start_of_packet);
- len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
- multi_byte_packet);
- net->save_char= net->read_pos[len]; /* Must be saved */
- net->read_pos[len]=0; /* Safeguard for mysql_use_result */
- }
-#endif /* HAVE_COMPRESS */
- return len;
-}
-
-int net_request_file(NET* net, const char* fname)
-{
- char tmp [FN_REFLEN+1],*end;
- DBUG_ENTER("net_request_file");
- tmp[0] = (char) 251; /* NULL_LENGTH */
- end=strnmov(tmp+1,fname,sizeof(tmp)-2);
- DBUG_RETURN(my_net_write(net,tmp,(uint) (end-tmp)) ||
- net_flush(net));
-}