~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/net_serv.c

  • Committer: Monty Taylor
  • Date: 2008-08-01 23:59:59 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801235959-n8ypy9r5aohown77
Gettext error compiles and passes test!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
/*
 
17
  HFTODO this must be hidden if we don't want client capabilities in 
 
18
  embedded library
19
19
 */
20
 
 
21
 
#include "config.h"
22
 
#include <drizzled/session.h>
23
 
 
24
 
#include <assert.h>
25
 
#include <stdio.h>
26
 
#include <stdlib.h>
27
 
#include <string.h>
 
20
#include <drizzled/global.h>
 
21
#include <drizzle.h>
 
22
#include <drizzled/error.h>
 
23
#include <mysys/my_sys.h>
 
24
#include <mystrings/m_string.h>
 
25
#include <vio/violite.h>
28
26
#include <signal.h>
29
27
#include <errno.h>
30
 
#include <sys/socket.h>
31
28
#include <sys/poll.h>
32
 
#include <zlib.h>
33
 
#include <algorithm>
34
 
 
35
 
#include "errmsg.h"
36
 
#include "vio.h"
37
 
#include "net_serv.h"
38
 
 
39
 
using namespace std;
40
 
 
41
 
namespace drizzle_protocol
42
 
{
43
29
 
44
30
/*
45
31
  The following handles the differences when this is linked between the
50
36
  can't normally do this the client should have a bigger max_allowed_packet.
51
37
*/
52
38
 
53
 
  /* Constants when using compression */
54
 
#define NET_HEADER_SIZE 4               /* standard header size */
55
 
#define COMP_HEADER_SIZE 3              /* compression header extra size */
56
 
 
 
39
 
 
40
#define DONT_USE_THR_ALARM
 
41
 
 
42
#include <mysys/thr_alarm.h>
 
43
 
 
44
 
 
45
#define update_statistics(A)
 
46
#define thd_increment_bytes_sent(N)
 
47
 
 
48
#define TEST_BLOCKING           8
57
49
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
58
 
const char  *not_error_sqlstate= "00000";
59
50
 
60
51
static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len);
61
 
static int drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len);
 
52
 
62
53
 
63
54
/** Init with packet info. */
64
55
 
65
 
bool drizzleclient_net_init(NET *net, Vio* vio, uint32_t buffer_length)
 
56
bool my_net_init(NET *net, Vio* vio)
66
57
{
67
58
  net->vio = vio;
68
 
  net->max_packet= (uint32_t) buffer_length;
69
 
  net->max_packet_size= max(buffer_length,
70
 
                            drizzled::global_system_variables.max_allowed_packet);
71
 
 
72
 
  if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
73
 
                                          NET_HEADER_SIZE + COMP_HEADER_SIZE)))
 
59
  my_net_local_init(net);                       /* Set some limits */
 
60
  if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
 
61
                                     NET_HEADER_SIZE + COMP_HEADER_SIZE,
 
62
                                     MYF(MY_WME))))
74
63
    return(1);
75
64
  net->buff_end=net->buff+net->max_packet;
76
65
  net->error=0; net->return_status=0;
82
71
  net->last_errno=0;
83
72
  net->unused= 0;
84
73
 
85
 
  if (vio != 0)                    /* If real connection */
 
74
  if (vio != 0)                                 /* If real connection */
86
75
  {
87
 
    net->fd  = drizzleclient_vio_fd(vio);            /* For perl DBI/DBD */
88
 
    drizzleclient_vio_fastsend(vio);
 
76
    net->fd  = vio_fd(vio);                     /* For perl DBI/DBD */
 
77
    vio_fastsend(vio);
89
78
  }
90
79
  return(0);
91
80
}
92
81
 
93
 
bool drizzleclient_net_init_sock(NET * net, int sock, int flags,
94
 
                                 uint32_t buffer_length)
95
 
{
96
 
 
97
 
  Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags);
98
 
  if (drizzleclient_vio_tmp == NULL)
99
 
    return true;
100
 
  else
101
 
    if (drizzleclient_net_init(net, drizzleclient_vio_tmp, buffer_length))
102
 
    {
103
 
      /* Only delete the temporary vio if we didn't already attach it to the
104
 
       * NET object.
105
 
       */
106
 
      if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp))
107
 
        drizzleclient_vio_delete(drizzleclient_vio_tmp);
108
 
      else
109
 
      {
110
 
        (void) shutdown(sock, SHUT_RDWR);
111
 
        (void) close(sock);
112
 
      }
113
 
      return true;
114
 
    }
115
 
  return false;
116
 
}
117
 
 
118
 
void drizzleclient_net_end(NET *net)
119
 
{
120
 
  if (net->buff != NULL)
121
 
    free(net->buff);
122
 
  net->buff= NULL;
 
82
 
 
83
void net_end(NET *net)
 
84
{
 
85
  my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
 
86
  net->buff=0;
123
87
  return;
124
88
}
125
89
 
126
 
void drizzleclient_net_close(NET *net)
127
 
{
128
 
  if (net->vio != NULL)
129
 
  {
130
 
    drizzleclient_vio_delete(net->vio);
131
 
    net->vio= 0;
132
 
  }
133
 
}
134
 
 
135
 
bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
136
 
{
137
 
  return drizzleclient_vio_peer_addr(net->vio, buf, port, buflen);
138
 
}
139
 
 
140
 
void drizzleclient_net_keepalive(NET *net, bool flag)
141
 
{
142
 
  drizzleclient_vio_keepalive(net->vio, flag);
143
 
}
144
 
 
145
 
int drizzleclient_net_get_sd(NET *net)
146
 
{
147
 
  return net->vio->sd;
148
 
}
149
 
 
150
 
bool drizzleclient_net_more_data(NET *net)
151
 
{
152
 
  return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
153
 
}
154
90
 
155
91
/** Realloc the packet buffer. */
156
92
 
157
 
static bool drizzleclient_net_realloc(NET *net, size_t length)
 
93
bool net_realloc(NET *net, size_t length)
158
94
{
159
 
  unsigned char *buff;
 
95
  uchar *buff;
160
96
  size_t pkt_length;
161
97
 
162
98
  if (length >= net->max_packet_size)
163
99
  {
164
100
    /* @todo: 1 and 2 codes are identical. */
165
101
    net->error= 1;
166
 
    net->last_errno= CR_NET_PACKET_TOO_LARGE;
 
102
    net->last_errno= ER_NET_PACKET_TOO_LARGE;
167
103
    return(1);
168
104
  }
169
 
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
 
105
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); 
170
106
  /*
171
107
    We must allocate some extra bytes for the end 0 and to be able to
172
108
    read big compressed blocks
173
109
  */
174
 
  if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length +
175
 
                               NET_HEADER_SIZE + COMP_HEADER_SIZE)))
 
110
  if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
 
111
                                  NET_HEADER_SIZE + COMP_HEADER_SIZE,
 
112
                                  MYF(MY_WME))))
176
113
  {
177
114
    /* @todo: 1 and 2 codes are identical. */
178
115
    net->error= 1;
179
 
    net->last_errno= CR_OUT_OF_MEMORY;
 
116
    net->last_errno= ER_OUT_OF_RESOURCES;
180
117
    /* In the server the error is reported by MY_WME flag. */
181
118
    return(1);
182
119
  }
183
120
  net->buff=net->write_pos=buff;
184
 
  net->buff_end=buff+(net->max_packet= (uint32_t) pkt_length);
 
121
  net->buff_end=buff+(net->max_packet= (ulong) pkt_length);
185
122
  return(0);
186
123
}
187
124
 
188
125
 
189
126
/**
190
 
   Check if there is any data to be read from the socket.
191
 
 
192
 
   @param sd   socket descriptor
193
 
 
194
 
   @retval
195
 
   0  No data to read
196
 
   @retval
197
 
   1  Data or EOF to read
198
 
   @retval
199
 
   -1   Don't know if data is ready or not
 
127
  Check if there is any data to be read from the socket.
 
128
 
 
129
  @param sd   socket descriptor
 
130
 
 
131
  @retval
 
132
    0  No data to read
 
133
  @retval
 
134
    1  Data or EOF to read
 
135
  @retval
 
136
    -1   Don't know if data is ready or not
200
137
*/
201
138
 
202
 
static bool net_data_is_ready(int sd)
 
139
static int net_data_is_ready(my_socket sd)
203
140
{
204
141
  struct pollfd ufds;
205
142
  int res;
214
151
}
215
152
 
216
153
/**
217
 
   Remove unwanted characters from connection
218
 
   and check if disconnected.
219
 
 
220
 
   Read from socket until there is nothing more to read. Discard
221
 
   what is read.
222
 
 
223
 
   If there is anything when to read 'drizzleclient_net_clear' is called this
224
 
   normally indicates an error in the protocol.
225
 
 
226
 
   When connection is properly closed (for TCP it means with
227
 
   a FIN packet), then select() considers a socket "ready to read",
228
 
   in the sense that there's EOF to read, but read() returns 0.
229
 
 
230
 
   @param net            NET handler
231
 
   @param clear_buffer           if <> 0, then clear all data from comm buff
 
154
  Remove unwanted characters from connection
 
155
  and check if disconnected.
 
156
 
 
157
    Read from socket until there is nothing more to read. Discard
 
158
    what is read.
 
159
 
 
160
    If there is anything when to read 'net_clear' is called this
 
161
    normally indicates an error in the protocol.
 
162
 
 
163
    When connection is properly closed (for TCP it means with
 
164
    a FIN packet), then select() considers a socket "ready to read",
 
165
    in the sense that there's EOF to read, but read() returns 0.
 
166
 
 
167
  @param net                    NET handler
 
168
  @param clear_buffer           if <> 0, then clear all data from comm buff
232
169
*/
233
170
 
234
 
void drizzleclient_net_clear(NET *net, bool clear_buffer)
 
171
void net_clear(NET *net, bool clear_buffer)
235
172
{
 
173
  size_t count;
 
174
  int32_t ready;
 
175
 
236
176
  if (clear_buffer)
237
177
  {
238
 
    while (net_data_is_ready(net->vio->sd) > 0)
 
178
    while ((ready= net_data_is_ready(net->vio->sd)) > 0)
239
179
    {
240
180
      /* The socket is ready */
241
 
      if (drizzleclient_vio_read(net->vio, net->buff,
242
 
                   (size_t) net->max_packet) <= 0)
 
181
      if ((long) (count= vio_read(net->vio, net->buff,
 
182
                                  (size_t) net->max_packet)) <= 0)
243
183
      {
244
184
        net->error= 2;
245
185
        break;
246
186
      }
247
187
    }
248
188
  }
249
 
  net->pkt_nr=net->compress_pkt_nr=0;        /* Ready for new command */
 
189
  net->pkt_nr=net->compress_pkt_nr=0;           /* Ready for new command */
250
190
  net->write_pos=net->buff;
251
191
  return;
252
192
}
254
194
 
255
195
/** Flush write_buffer if not empty. */
256
196
 
257
 
bool drizzleclient_net_flush(NET *net)
 
197
bool net_flush(NET *net)
258
198
{
259
 
  bool error= 0;
 
199
  my_bool error= 0;
260
200
  if (net->buff != net->write_pos)
261
201
  {
262
 
    error=drizzleclient_net_real_write(net, net->buff,
263
 
                         (size_t) (net->write_pos - net->buff)) ? 1 : 0;
 
202
    error=test(net_real_write(net, net->buff,
 
203
                              (size_t) (net->write_pos - net->buff)));
264
204
    net->write_pos=net->buff;
265
205
  }
266
206
  /* Sync packet number if using compression */
271
211
 
272
212
 
273
213
/*****************************************************************************
274
 
 ** Write something to server/client buffer
275
 
 *****************************************************************************/
 
214
** Write something to server/client buffer
 
215
*****************************************************************************/
276
216
 
277
217
/**
278
 
   Write a logical packet with packet header.
279
 
 
280
 
   Format: Packet length (3 bytes), packet number(1 byte)
281
 
   When compression is used a 3 byte compression length is added
282
 
 
283
 
   @note
284
 
   If compression is used the original package is modified!
 
218
  Write a logical packet with packet header.
 
219
 
 
220
  Format: Packet length (3 bytes), packet number(1 byte)
 
221
  When compression is used a 3 byte compression length is added
 
222
 
 
223
  @note
 
224
    If compression is used the original package is modified!
285
225
*/
286
226
 
287
227
bool
288
 
drizzleclient_net_write(NET *net,const unsigned char *packet,size_t len)
 
228
my_net_write(NET *net,const uchar *packet,size_t len)
289
229
{
290
 
  unsigned char buff[NET_HEADER_SIZE];
 
230
  uchar buff[NET_HEADER_SIZE];
291
231
  if (unlikely(!net->vio)) /* nowhere to write */
292
232
    return 0;
293
233
  /*
297
237
  */
298
238
  while (len >= MAX_PACKET_LENGTH)
299
239
  {
300
 
    const uint32_t z_size = MAX_PACKET_LENGTH;
 
240
    const ulong z_size = MAX_PACKET_LENGTH;
301
241
    int3store(buff, z_size);
302
 
    buff[3]= (unsigned char) net->pkt_nr++;
 
242
    buff[3]= (uchar) net->pkt_nr++;
303
243
    if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
304
 
        net_write_buff(net, packet, z_size))
 
244
        net_write_buff(net, packet, z_size))
305
245
      return 1;
306
246
    packet += z_size;
307
247
    len-=     z_size;
308
248
  }
309
249
  /* Write last packet */
310
250
  int3store(buff,len);
311
 
  buff[3]= (unsigned char) net->pkt_nr++;
 
251
  buff[3]= (uchar) net->pkt_nr++;
312
252
  if (net_write_buff(net, buff, NET_HEADER_SIZE))
313
253
    return 1;
314
 
  return net_write_buff(net,packet,len) ? 1 : 0;
 
254
  return test(net_write_buff(net,packet,len));
315
255
}
316
256
 
317
257
/**
318
 
   Send a command to the server.
319
 
 
320
 
   The reason for having both header and packet is so that libdrizzle
321
 
   can easy add a header to a special command (like prepared statements)
322
 
   without having to re-alloc the string.
323
 
 
324
 
   As the command is part of the first data packet, we have to do some data
325
 
   juggling to put the command in there, without having to create a new
326
 
   packet.
327
 
 
328
 
   This function will split big packets into sub-packets if needed.
329
 
   (Each sub packet can only be 2^24 bytes)
330
 
 
331
 
   @param net        NET handler
332
 
   @param command    Command in MySQL server (enum enum_server_command)
333
 
   @param header    Header to write after command
334
 
   @param head_len    Length of header
335
 
   @param packet    Query or parameter to query
336
 
   @param len        Length of packet
337
 
 
338
 
   @retval
339
 
   0    ok
340
 
   @retval
341
 
   1    error
 
258
  Send a command to the server.
 
259
 
 
260
    The reason for having both header and packet is so that libdrizzle
 
261
    can easy add a header to a special command (like prepared statements)
 
262
    without having to re-alloc the string.
 
263
 
 
264
    As the command is part of the first data packet, we have to do some data
 
265
    juggling to put the command in there, without having to create a new
 
266
    packet.
 
267
  
 
268
    This function will split big packets into sub-packets if needed.
 
269
    (Each sub packet can only be 2^24 bytes)
 
270
 
 
271
  @param net            NET handler
 
272
  @param command        Command in MySQL server (enum enum_server_command)
 
273
  @param header Header to write after command
 
274
  @param head_len       Length of header
 
275
  @param packet Query or parameter to query
 
276
  @param len            Length of packet
 
277
 
 
278
  @retval
 
279
    0   ok
 
280
  @retval
 
281
    1   error
342
282
*/
343
283
 
344
284
bool
345
 
drizzleclient_net_write_command(NET *net,unsigned char command,
346
 
                  const unsigned char *header, size_t head_len,
347
 
                  const unsigned char *packet, size_t len)
 
285
net_write_command(NET *net,uchar command,
 
286
                  const uchar *header, size_t head_len,
 
287
                  const uchar *packet, size_t len)
348
288
{
349
 
  uint32_t length=len+1+head_len;            /* 1 extra byte for command */
350
 
  unsigned char buff[NET_HEADER_SIZE+1];
351
 
  uint32_t header_size=NET_HEADER_SIZE+1;
 
289
  ulong length=len+1+head_len;                  /* 1 extra byte for command */
 
290
  uchar buff[NET_HEADER_SIZE+1];
 
291
  uint header_size=NET_HEADER_SIZE+1;
352
292
 
353
 
  buff[4]=command;                /* For first packet */
 
293
  buff[4]=command;                              /* For first packet */
354
294
 
355
295
  if (length >= MAX_PACKET_LENGTH)
356
296
  {
359
299
    do
360
300
    {
361
301
      int3store(buff, MAX_PACKET_LENGTH);
362
 
      buff[3]= (unsigned char) net->pkt_nr++;
 
302
      buff[3]= (uchar) net->pkt_nr++;
363
303
      if (net_write_buff(net, buff, header_size) ||
364
 
          net_write_buff(net, header, head_len) ||
365
 
          net_write_buff(net, packet, len))
366
 
        return(1);
 
304
          net_write_buff(net, header, head_len) ||
 
305
          net_write_buff(net, packet, len))
 
306
        return(1);
367
307
      packet+= len;
368
308
      length-= MAX_PACKET_LENGTH;
369
309
      len= MAX_PACKET_LENGTH;
370
310
      head_len= 0;
371
311
      header_size= NET_HEADER_SIZE;
372
312
    } while (length >= MAX_PACKET_LENGTH);
373
 
    len=length;                    /* Data left to be written */
 
313
    len=length;                                 /* Data left to be written */
374
314
  }
375
315
  int3store(buff,length);
376
 
  buff[3]= (unsigned char) net->pkt_nr++;
377
 
  return((net_write_buff(net, buff, header_size) ||
378
 
          (head_len && net_write_buff(net, header, head_len)) ||
379
 
          net_write_buff(net, packet, len) || drizzleclient_net_flush(net)) ? 1 : 0 );
 
316
  buff[3]= (uchar) net->pkt_nr++;
 
317
  return(test(net_write_buff(net, buff, header_size) ||
 
318
                   (head_len && net_write_buff(net, header, head_len)) ||
 
319
                   net_write_buff(net, packet, len) || net_flush(net)));
380
320
}
381
321
 
382
322
/**
383
 
   Caching the data in a local buffer before sending it.
 
323
  Caching the data in a local buffer before sending it.
384
324
 
385
325
   Fill up net->buffer and send it to the client when full.
386
326
 
387
 
   If the rest of the to-be-sent-packet is bigger than buffer,
388
 
   send it in one big block (to avoid copying to internal buffer).
389
 
   If not, copy the rest of the data to the buffer and return without
390
 
   sending data.
391
 
 
392
 
   @param net        Network handler
393
 
   @param packet    Packet to send
394
 
   @param len        Length of packet
395
 
 
396
 
   @note
397
 
   The cached buffer can be sent as it is with 'drizzleclient_net_flush()'.
398
 
   In this code we have to be careful to not send a packet longer than
399
 
   MAX_PACKET_LENGTH to drizzleclient_net_real_write() if we are using the compressed
400
 
   protocol as we store the length of the compressed packet in 3 bytes.
401
 
 
402
 
   @retval
403
 
   0    ok
404
 
   @retval
405
 
   1
 
327
    If the rest of the to-be-sent-packet is bigger than buffer,
 
328
    send it in one big block (to avoid copying to internal buffer).
 
329
    If not, copy the rest of the data to the buffer and return without
 
330
    sending data.
 
331
 
 
332
  @param net            Network handler
 
333
  @param packet Packet to send
 
334
  @param len            Length of packet
 
335
 
 
336
  @note
 
337
    The cached buffer can be sent as it is with 'net_flush()'.
 
338
    In this code we have to be careful to not send a packet longer than
 
339
    MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
 
340
    protocol as we store the length of the compressed packet in 3 bytes.
 
341
 
 
342
  @retval
 
343
    0   ok
 
344
  @retval
 
345
    1
406
346
*/
407
347
 
408
348
static bool
409
349
net_write_buff(NET *net, const unsigned char *packet, uint32_t len)
410
350
{
411
 
  uint32_t left_length;
 
351
  ulong left_length;
412
352
  if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
413
353
    left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff);
414
354
  else
415
 
    left_length= (uint32_t) (net->buff_end - net->write_pos);
 
355
    left_length= (ulong) (net->buff_end - net->write_pos);
416
356
 
417
357
  if (len > left_length)
418
358
  {
419
359
    if (net->write_pos != net->buff)
420
360
    {
421
361
      /* Fill up already used packet and write it */
422
 
      memcpy(net->write_pos,packet,left_length);
423
 
      if (drizzleclient_net_real_write(net, net->buff,
424
 
                         (size_t) (net->write_pos - net->buff) + left_length))
425
 
        return 1;
 
362
      memcpy((char*) net->write_pos,packet,left_length);
 
363
      if (net_real_write(net, net->buff, 
 
364
                         (size_t) (net->write_pos - net->buff) + left_length))
 
365
        return 1;
426
366
      net->write_pos= net->buff;
427
367
      packet+= left_length;
428
368
      len-= left_length;
430
370
    if (net->compress)
431
371
    {
432
372
      /*
433
 
        We can't have bigger packets than 16M with compression
434
 
        Because the uncompressed length is stored in 3 bytes
 
373
        We can't have bigger packets than 16M with compression
 
374
        Because the uncompressed length is stored in 3 bytes
435
375
      */
436
376
      left_length= MAX_PACKET_LENGTH;
437
377
      while (len > left_length)
438
378
      {
439
 
        if (drizzleclient_net_real_write(net, packet, left_length))
440
 
          return 1;
441
 
        packet+= left_length;
442
 
        len-= left_length;
 
379
        if (net_real_write(net, packet, left_length))
 
380
          return 1;
 
381
        packet+= left_length;
 
382
        len-= left_length;
443
383
      }
444
384
    }
445
385
    if (len > net->max_packet)
446
 
      return drizzleclient_net_real_write(net, packet, len) ? 1 : 0;
 
386
      return net_real_write(net, packet, len) ? 1 : 0;
447
387
    /* Send out rest of the blocks as full sized blocks */
448
388
  }
449
 
  memcpy(net->write_pos,packet,len);
 
389
  memcpy((char*) net->write_pos,packet,len);
450
390
  net->write_pos+= len;
451
391
  return 0;
452
392
}
453
393
 
454
394
 
455
395
/**
456
 
   Read and write one packet using timeouts.
457
 
   If needed, the packet is compressed before sending.
 
396
  Read and write one packet using timeouts.
 
397
  If needed, the packet is compressed before sending.
458
398
 
459
 
   @todo
460
 
   - TODO is it needed to set this variable if we have no socket
 
399
  @todo
 
400
    - TODO is it needed to set this variable if we have no socket
461
401
*/
462
402
 
463
403
/*
464
404
  TODO: rewrite this in a manner to do non-block writes. If a write can not be made, and we are
465
405
  in the server, yield to another process and come back later.
466
406
*/
467
 
static int
468
 
drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len)
 
407
int
 
408
net_real_write(NET *net,const uchar *packet, size_t len)
469
409
{
470
410
  size_t length;
471
 
  const unsigned char *pos, *end;
472
 
  uint32_t retry_count= 0;
 
411
  const uchar *pos,*end;
 
412
  uint retry_count= 0;
473
413
 
474
414
  /* Backup of the original SO_RCVTIMEO timeout */
 
415
  struct timeval backtime;
 
416
  int error;
475
417
 
476
418
  if (net->error == 2)
477
 
    return(-1);                /* socket can't be used */
 
419
    return(-1);                         /* socket can't be used */
478
420
 
479
421
  net->reading_or_writing=2;
480
422
  if (net->compress)
481
423
  {
482
424
    size_t complen;
483
 
    unsigned char *b;
484
 
    const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
485
 
    if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE +
486
 
                             COMP_HEADER_SIZE)))
 
425
    uchar *b;
 
426
    uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
 
427
    if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
 
428
                                COMP_HEADER_SIZE, MYF(MY_WME))))
487
429
    {
488
430
      net->error= 2;
489
 
      net->last_errno= CR_OUT_OF_MEMORY;
 
431
      net->last_errno= ER_OUT_OF_RESOURCES;
490
432
      /* In the server, the error is reported by MY_WME flag. */
491
433
      net->reading_or_writing= 0;
492
434
      return(1);
493
435
    }
494
436
    memcpy(b+header_length,packet,len);
495
437
 
496
 
    complen= len * 120 / 100 + 12;
497
 
    unsigned char * compbuf= (unsigned char *) malloc(complen);
498
 
    if (compbuf != NULL)
499
 
    {
500
 
      uLongf tmp_complen= complen;
501
 
      int res= compress((Bytef*) compbuf, &tmp_complen,
502
 
                        (Bytef*) (b+header_length),
503
 
                        len);
504
 
      complen= tmp_complen;
505
 
 
506
 
      free(compbuf);
507
 
 
508
 
      if ((res != Z_OK) || (complen >= len))
509
 
        complen= 0;
510
 
      else
511
 
      {
512
 
        size_t tmplen= complen;
513
 
        complen= len;
514
 
        len= tmplen;
515
 
      }
516
 
    }
517
 
    else
518
 
    {
 
438
    if (my_compress(b+header_length, &len, &complen))
519
439
      complen=0;
520
 
    }
521
440
    int3store(&b[NET_HEADER_SIZE],complen);
522
441
    int3store(b,len);
523
 
    b[3]=(unsigned char) (net->compress_pkt_nr++);
 
442
    b[3]=(uchar) (net->compress_pkt_nr++);
524
443
    len+= header_length;
525
444
    packet= b;
526
445
  }
527
446
 
 
447
  /* Check for error, currently assert */
 
448
  if (net->write_timeout)
 
449
  {
 
450
    struct timeval waittime;
 
451
    socklen_t length;
 
452
 
 
453
    waittime.tv_sec= net->write_timeout;
 
454
    waittime.tv_usec= 0;
 
455
 
 
456
    memset(&backtime, 0, sizeof(struct timeval));
 
457
    length= sizeof(struct timeval);
 
458
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
459
                      &backtime, &length);
 
460
    if (error != 0)
 
461
    {
 
462
      perror("getsockopt");
 
463
      assert(error == 0);
 
464
    }
 
465
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
466
                      &waittime, (socklen_t)sizeof(struct timeval));
 
467
    assert(error == 0);
 
468
  }
528
469
  pos= packet;
529
470
  end=pos+len;
530
471
  /* Loop until we have read everything */
531
472
  while (pos != end)
532
473
  {
533
 
    assert(pos);
534
 
    if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
 
474
    if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
535
475
    {
536
 
     /*
537
 
      * We could end up here with net->vio == NULL
538
 
      * See LP bug#436685
539
 
      * If that is the case, we exit the while loop
540
 
      */
541
 
      if (net->vio == NULL)
542
 
        break;
543
 
      
544
 
      const bool interrupted= drizzleclient_vio_should_retry(net->vio);
545
 
      /*
546
 
        If we read 0, or we were interrupted this means that
547
 
        we need to switch to blocking mode and wait until the timeout
 
476
      my_bool interrupted= vio_should_retry(net->vio);
 
477
      /* 
 
478
        If we read 0, or we were interrupted this means that 
 
479
        we need to switch to blocking mode and wait until the timeout 
548
480
        on the socket kicks in.
549
481
      */
550
482
      if ((interrupted || length == 0))
551
483
      {
552
484
        bool old_mode;
553
485
 
554
 
        while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0)
 
486
        while (vio_blocking(net->vio, true, &old_mode) < 0)
555
487
        {
556
 
          if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count)
 
488
          if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
557
489
            continue;
558
490
          net->error= 2;                     /* Close socket */
559
 
          net->last_errno= CR_NET_PACKET_TOO_LARGE;
 
491
          net->last_errno= ER_NET_PACKET_TOO_LARGE;
560
492
          goto end;
561
493
        }
562
494
        retry_count=0;
567
499
        if (retry_count++ < net->retry_count)
568
500
          continue;
569
501
      }
570
 
 
571
 
      if (drizzleclient_vio_errno(net->vio) == EINTR)
 
502
      
 
503
      if (vio_errno(net->vio) == SOCKET_EINTR)
572
504
      {
573
505
        continue;
574
506
      }
575
 
      net->error= 2;                /* Close socket */
576
 
      net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED :
577
 
                        CR_NET_ERROR_ON_WRITE);
 
507
      net->error= 2;                            /* Close socket */
 
508
      net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
 
509
                        ER_NET_ERROR_ON_WRITE);
578
510
      break;
579
511
    }
580
512
    pos+=length;
581
 
    current_session->status_var.bytes_sent+= length;
 
513
    update_statistics(thd_increment_bytes_sent(length));
582
514
  }
583
 
end:
584
 
  if ((net->compress) && (packet != NULL))
585
 
    free((char*) packet);
 
515
 end:
 
516
  if (net->compress)
 
517
    my_free((char*) packet,MYF(0));
586
518
  net->reading_or_writing=0;
587
519
 
 
520
  if (net->write_timeout)
 
521
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
522
                      &backtime, (socklen_t)sizeof(struct timeval));
 
523
 
588
524
  return(((int) (pos != end)));
589
525
}
590
526
 
591
527
 
592
528
/**
593
 
   Reads one packet to net->buff + net->where_b.
594
 
   Long packets are handled by drizzleclient_net_read().
595
 
   This function reallocates the net->buff buffer if necessary.
 
529
  Reads one packet to net->buff + net->where_b.
 
530
  Long packets are handled by my_net_read().
 
531
  This function reallocates the net->buff buffer if necessary.
596
532
 
597
 
   @return
598
 
   Returns length of packet.
 
533
  @return
 
534
    Returns length of packet.
599
535
*/
600
536
 
601
 
static uint32_t
 
537
static ulong
602
538
my_real_read(NET *net, size_t *complen)
603
539
{
604
 
  unsigned char *pos;
 
540
  uchar *pos;
605
541
  size_t length;
606
 
  uint32_t i,retry_count=0;
607
 
  size_t len=packet_error;
 
542
  uint i,retry_count=0;
 
543
  ulong len=packet_error;
608
544
  uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
609
 
                    NET_HEADER_SIZE);
 
545
                  NET_HEADER_SIZE);
 
546
  /* Backup of the original SO_RCVTIMEO timeout */
 
547
  struct timeval backtime;
 
548
  int error= 0;
610
549
 
611
550
  *complen = 0;
612
551
 
613
552
  net->reading_or_writing= 1;
614
 
  /* Read timeout is set in drizzleclient_net_set_read_timeout */
615
 
 
616
 
  pos = net->buff + net->where_b;        /* net->packet -4 */
 
553
  /* Read timeout is set in my_net_set_read_timeout */
 
554
 
 
555
  pos = net->buff + net->where_b;               /* net->packet -4 */
 
556
 
 
557
 
 
558
  /* Check for error, currently assert */
 
559
  if (net->read_timeout)
 
560
  {
 
561
    struct timeval waittime;
 
562
    socklen_t length;
 
563
 
 
564
    waittime.tv_sec= net->read_timeout;
 
565
    waittime.tv_usec= 0;
 
566
 
 
567
    memset(&backtime, 0, sizeof(struct timeval));
 
568
    length= sizeof(struct timeval);
 
569
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
570
                      &backtime, &length);
 
571
    if (error != 0)
 
572
    {
 
573
      perror("getsockopt");
 
574
      assert(error == 0);
 
575
    }
 
576
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
577
                      &waittime, (socklen_t)sizeof(struct timeval));
 
578
    assert(error == 0);
 
579
  }
617
580
 
618
581
  for (i= 0; i < 2 ; i++)
619
582
  {
620
583
    while (remain > 0)
621
584
    {
622
585
      /* First read is done with non blocking mode */
623
 
      if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L)
 
586
      if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
624
587
      {
625
 
        if (net->vio == NULL)
626
 
          goto end;
627
 
 
628
 
        const bool interrupted = drizzleclient_vio_should_retry(net->vio);
 
588
        bool interrupted = vio_should_retry(net->vio);
629
589
 
630
590
        if (interrupted)
631
 
        {                    /* Probably in MIT threads */
 
591
        {                                       /* Probably in MIT threads */
632
592
          if (retry_count++ < net->retry_count)
633
593
            continue;
634
594
        }
635
 
        if (drizzleclient_vio_errno(net->vio) == EINTR)
 
595
        if (vio_errno(net->vio) == SOCKET_EINTR)
636
596
        {
637
597
          continue;
638
598
        }
639
599
        len= packet_error;
640
 
        net->error= 2;                /* Close socket */
641
 
        net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ?
642
 
                          CR_NET_READ_INTERRUPTED :
643
 
                          CR_NET_READ_ERROR);
644
 
        ER(net->last_errno);
 
600
        net->error= 2;                          /* Close socket */
 
601
        net->last_errno= (vio_was_interrupted(net->vio) ?
 
602
                          ER_NET_READ_INTERRUPTED :
 
603
                          ER_NET_READ_ERROR);
645
604
        goto end;
646
605
      }
647
606
      remain -= (uint32_t) length;
648
607
      pos+= length;
649
 
      current_session->status_var.bytes_received+= length;
 
608
      update_statistics(thd_increment_bytes_received(length));
650
609
    }
651
610
    if (i == 0)
652
 
    {                    /* First parts is packet length */
653
 
      uint32_t helping;
 
611
    {                                   /* First parts is packet length */
 
612
      ulong helping;
654
613
 
655
 
      if (net->buff[net->where_b + 3] != (unsigned char) net->pkt_nr)
 
614
      if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
656
615
      {
657
616
        len= packet_error;
658
617
        /* Not a NET error on the client. XXX: why? */
669
628
      }
670
629
 
671
630
      len=uint3korr(net->buff+net->where_b);
672
 
      if (!len)                /* End of big multi-packet */
 
631
      if (!len)                         /* End of big multi-packet */
673
632
        goto end;
674
633
      helping = max(len,*complen) + net->where_b;
675
634
      /* The necessary size of net->buff */
676
635
      if (helping >= net->max_packet)
677
636
      {
678
 
        if (drizzleclient_net_realloc(net,helping))
 
637
        if (net_realloc(net,helping))
679
638
        {
680
639
          len= packet_error;          /* Return error and close connection */
681
640
          goto end;
687
646
  }
688
647
 
689
648
end:
 
649
  if  (net->read_timeout)
 
650
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
651
                      &backtime, (socklen_t)sizeof(struct timeval));
 
652
  assert(error == 0);
690
653
  net->reading_or_writing= 0;
691
654
 
692
655
  return(len);
694
657
 
695
658
 
696
659
/**
697
 
   Read a packet from the client/server and return it without the internal
698
 
   package header.
699
 
 
700
 
   If the packet is the first packet of a multi-packet packet
701
 
   (which is indicated by the length of the packet = 0xffffff) then
702
 
   all sub packets are read and concatenated.
703
 
 
704
 
   If the packet was compressed, its uncompressed and the length of the
705
 
   uncompressed packet is returned.
706
 
 
707
 
   @return
708
 
   The function returns the length of the found packet or packet_error.
709
 
   net->read_pos points to the read data.
 
660
  Read a packet from the client/server and return it without the internal
 
661
  package header.
 
662
 
 
663
  If the packet is the first packet of a multi-packet packet
 
664
  (which is indicated by the length of the packet = 0xffffff) then
 
665
  all sub packets are read and concatenated.
 
666
 
 
667
  If the packet was compressed, its uncompressed and the length of the
 
668
  uncompressed packet is returned.
 
669
 
 
670
  @return
 
671
  The function returns the length of the found packet or packet_error.
 
672
  net->read_pos points to the read data.
710
673
*/
711
674
 
712
675
uint32_t
713
 
drizzleclient_net_read(NET *net)
 
676
my_net_read(NET *net)
714
677
{
715
678
  size_t len, complen;
716
679
 
720
683
    if (len == MAX_PACKET_LENGTH)
721
684
    {
722
685
      /* First packet of a multi-packet.  Concatenate the packets */
723
 
      uint32_t save_pos = net->where_b;
 
686
      ulong save_pos = net->where_b;
724
687
      size_t total_length= 0;
725
688
      do
726
689
      {
727
 
        net->where_b += len;
728
 
        total_length += len;
729
 
        len = my_real_read(net,&complen);
 
690
        net->where_b += len;
 
691
        total_length += len;
 
692
        len = my_real_read(net,&complen);
730
693
      } while (len == MAX_PACKET_LENGTH);
731
694
      if (len != packet_error)
732
 
        len+= total_length;
 
695
        len+= total_length;
733
696
      net->where_b = save_pos;
734
697
    }
735
698
    net->read_pos = net->buff + net->where_b;
736
699
    if (len != packet_error)
737
 
      net->read_pos[len]=0;        /* Safeguard for drizzleclient_use_result */
 
700
      net->read_pos[len]=0;             /* Safeguard for drizzle_use_result */
738
701
    return len;
739
702
  }
740
703
  else
741
704
  {
742
705
    /* We are using the compressed protocol */
743
706
 
744
 
    uint32_t buf_length;
745
 
    uint32_t start_of_packet;
746
 
    uint32_t first_packet_offset;
747
 
    uint32_t read_length, multi_byte_packet=0;
 
707
    ulong buf_length;
 
708
    ulong start_of_packet;
 
709
    ulong first_packet_offset;
 
710
    uint read_length, multi_byte_packet=0;
748
711
 
749
712
    if (net->remain_in_buf)
750
713
    {
751
 
      buf_length= net->buf_length;        /* Data left in old packet */
 
714
      buf_length= net->buf_length;              /* Data left in old packet */
752
715
      first_packet_offset= start_of_packet= (net->buf_length -
753
 
                                             net->remain_in_buf);
 
716
                                             net->remain_in_buf);
754
717
      /* Restore the character that was overwritten by the end 0 */
755
718
      net->buff[start_of_packet]= net->save_char;
756
719
    }
761
724
    }
762
725
    for (;;)
763
726
    {
764
 
      uint32_t packet_len;
 
727
      ulong packet_len;
765
728
 
766
729
      if (buf_length - start_of_packet >= NET_HEADER_SIZE)
767
730
      {
768
 
        read_length = uint3korr(net->buff+start_of_packet);
769
 
        if (!read_length)
770
 
        {
771
 
          /* End of multi-byte packet */
772
 
          start_of_packet += NET_HEADER_SIZE;
773
 
          break;
774
 
        }
775
 
        if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
776
 
        {
777
 
          if (multi_byte_packet)
778
 
          {
779
 
            /* Remove packet header for second packet */
780
 
            memmove(net->buff + first_packet_offset + start_of_packet,
781
 
                    net->buff + first_packet_offset + start_of_packet +
782
 
                    NET_HEADER_SIZE,
783
 
                    buf_length - start_of_packet);
784
 
            start_of_packet += read_length;
785
 
            buf_length -= NET_HEADER_SIZE;
786
 
          }
787
 
          else
788
 
            start_of_packet+= read_length + NET_HEADER_SIZE;
 
731
        read_length = uint3korr(net->buff+start_of_packet);
 
732
        if (!read_length)
 
733
        { 
 
734
          /* End of multi-byte packet */
 
735
          start_of_packet += NET_HEADER_SIZE;
 
736
          break;
 
737
        }
 
738
        if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
 
739
        {
 
740
          if (multi_byte_packet)
 
741
          {
 
742
            /* Remove packet header for second packet */
 
743
            memmove(net->buff + first_packet_offset + start_of_packet,
 
744
                    net->buff + first_packet_offset + start_of_packet +
 
745
                    NET_HEADER_SIZE,
 
746
                    buf_length - start_of_packet);
 
747
            start_of_packet += read_length;
 
748
            buf_length -= NET_HEADER_SIZE;
 
749
          }
 
750
          else
 
751
            start_of_packet+= read_length + NET_HEADER_SIZE;
789
752
 
790
 
          if (read_length != MAX_PACKET_LENGTH)    /* last package */
791
 
          {
792
 
            multi_byte_packet= 0;        /* No last zero len packet */
793
 
            break;
794
 
          }
795
 
          multi_byte_packet= NET_HEADER_SIZE;
796
 
          /* Move data down to read next data packet after current one */
797
 
          if (first_packet_offset)
798
 
          {
799
 
            memmove(net->buff,net->buff+first_packet_offset,
800
 
                    buf_length-first_packet_offset);
801
 
            buf_length-=first_packet_offset;
802
 
            start_of_packet -= first_packet_offset;
803
 
            first_packet_offset=0;
804
 
          }
805
 
          continue;
806
 
        }
 
753
          if (read_length != MAX_PACKET_LENGTH) /* last package */
 
754
          {
 
755
            multi_byte_packet= 0;               /* No last zero len packet */
 
756
            break;
 
757
          }
 
758
          multi_byte_packet= NET_HEADER_SIZE;
 
759
          /* Move data down to read next data packet after current one */
 
760
          if (first_packet_offset)
 
761
          {
 
762
            memmove(net->buff,net->buff+first_packet_offset,
 
763
                    buf_length-first_packet_offset);
 
764
            buf_length-=first_packet_offset;
 
765
            start_of_packet -= first_packet_offset;
 
766
            first_packet_offset=0;
 
767
          }
 
768
          continue;
 
769
        }
807
770
      }
808
771
      /* Move data down to read next data packet after current one */
809
772
      if (first_packet_offset)
810
773
      {
811
 
        memmove(net->buff,net->buff+first_packet_offset,
812
 
                buf_length-first_packet_offset);
813
 
        buf_length-=first_packet_offset;
814
 
        start_of_packet -= first_packet_offset;
815
 
        first_packet_offset=0;
 
774
        memmove(net->buff,net->buff+first_packet_offset,
 
775
                buf_length-first_packet_offset);
 
776
        buf_length-=first_packet_offset;
 
777
        start_of_packet -= first_packet_offset;
 
778
        first_packet_offset=0;
816
779
      }
817
780
 
818
781
      net->where_b=buf_length;
819
782
      if ((packet_len = my_real_read(net,&complen)) == packet_error)
820
 
        return packet_error;
821
 
 
822
 
      if (complen)
 
783
        return packet_error;
 
784
      if (my_uncompress(net->buff + net->where_b, packet_len,
 
785
                        &complen))
823
786
      {
824
 
        unsigned char * compbuf= (unsigned char *) malloc(complen);
825
 
        if (compbuf != NULL)
826
 
        {
827
 
          uLongf tmp_complen= complen;
828
 
          int error= uncompress((Bytef*) compbuf, &tmp_complen,
829
 
                                (Bytef*) (net->buff + net->where_b),
830
 
                                (uLong)packet_len);
831
 
          complen= tmp_complen;
832
 
 
833
 
          if (error != Z_OK)
834
 
          {
835
 
            net->error= 2;            /* caller will close socket */
836
 
            net->last_errno= CR_NET_UNCOMPRESS_ERROR;
837
 
          }
838
 
          else
839
 
          {
840
 
            memcpy((net->buff + net->where_b), compbuf, complen);
841
 
          }
842
 
          free(compbuf);
843
 
        }
 
787
        net->error= 2;                  /* caller will close socket */
 
788
        net->last_errno= ER_NET_UNCOMPRESS_ERROR;
 
789
        return packet_error;
844
790
      }
845
 
      else
846
 
        complen= packet_len;
847
 
 
 
791
      buf_length+= complen;
848
792
    }
849
 
    buf_length+= complen;
850
793
 
851
794
    net->read_pos=      net->buff+ first_packet_offset + NET_HEADER_SIZE;
852
795
    net->buf_length=    buf_length;
853
 
    net->remain_in_buf= (uint32_t) (buf_length - start_of_packet);
854
 
    len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
 
796
    net->remain_in_buf= (ulong) (buf_length - start_of_packet);
 
797
    len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
855
798
           multi_byte_packet);
856
 
    net->save_char= net->read_pos[len];    /* Must be saved */
857
 
    net->read_pos[len]=0;        /* Safeguard for drizzleclient_use_result */
 
799
    net->save_char= net->read_pos[len]; /* Must be saved */
 
800
    net->read_pos[len]=0;               /* Safeguard for drizzle_use_result */
858
801
  }
859
802
  return len;
860
 
  }
861
 
 
862
 
 
863
 
void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout)
 
803
}
 
804
 
 
805
 
 
806
void my_net_set_read_timeout(NET *net, uint timeout)
864
807
{
865
808
  net->read_timeout= timeout;
866
 
#ifndef __sun
867
809
  if (net->vio)
868
 
    drizzleclient_vio_timeout(net->vio, 0, timeout);
869
 
#endif
 
810
    vio_timeout(net->vio, 0, timeout);
870
811
  return;
871
812
}
872
813
 
873
814
 
874
 
void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout)
 
815
void my_net_set_write_timeout(NET *net, uint timeout)
875
816
{
876
817
  net->write_timeout= timeout;
877
 
#ifndef __sun
878
818
  if (net->vio)
879
 
    drizzleclient_vio_timeout(net->vio, 1, timeout);
880
 
#endif
 
819
    vio_timeout(net->vio, 1, timeout);
881
820
  return;
882
821
}
883
 
/**
884
 
  Clear possible error state of struct NET
885
 
 
886
 
  @param net  clear the state of the argument
887
 
*/
888
 
 
889
 
void drizzleclient_drizzleclient_net_clear_error(NET *net)
890
 
{
891
 
  net->last_errno= 0;
892
 
  net->last_error[0]= '\0';
893
 
  strcpy(net->sqlstate, not_error_sqlstate);
894
 
}
895
 
 
896
 
} /* namespace drizzle_protocol */