~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/mysql_protocol/vio.cc

  • Committer: Stewart Smith
  • Date: 2009-10-08 05:39:17 UTC
  • mto: This revision was merged to the branch mainline in revision 1179.
  • Revision ID: stewart@flamingspork.com-20091008053917-b7u3opyo8997438r
removeĀ unusedĀ find_string_in_array

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
 
 
16
 
/*
17
 
  Note that we can't have assertion on file descriptors;  The reason for
18
 
  this is that during mysql shutdown, another thread can close a file
19
 
  we are working on.  In this case we should just return read errors from
20
 
  the file descriptior.
21
 
*/
22
 
#include "config.h"
23
 
#include "vio.h"
24
 
#include <string.h>
25
 
#include <drizzled/util/test.h>
26
 
#include <sys/socket.h>
27
 
#include <string.h>
28
 
#include <sys/types.h>
29
 
#include <netinet/tcp.h>
30
 
#include <netinet/in.h>
31
 
#include <sys/poll.h>
32
 
#include <unistd.h>
33
 
#include <fcntl.h>
34
 
#include <netdb.h>
35
 
#include <algorithm>
36
 
#include <cstdlib>
37
 
#include <cassert>
38
 
#include <cstdio>
39
 
#include <fcntl.h>
40
 
 
41
 
using namespace std;
42
 
 
43
 
namespace drizzle_plugin
44
 
{
45
 
 
46
 
Vio::Vio(int nsd) :
47
 
  closed(false),
48
 
  sd(nsd),
49
 
  fcntl_mode(0),
50
 
  local(),
51
 
  remote(),
52
 
  read_pos(NULL),
53
 
  read_end(NULL)
54
 
{
55
 
  /*
56
 
    We call fcntl() to set the flags and then immediately read them back
57
 
    to make sure that we and the system are in agreement on the state of
58
 
    things.
59
 
 
60
 
    An example of why we need to do this is FreeBSD (and apparently some
61
 
    other BSD-derived systems, like Mac OS X), where the system sometimes
62
 
    reports that the socket is set for non-blocking when it really will
63
 
    block.
64
 
  */
65
 
  fcntl(sd, F_SETFL, 0);
66
 
  fcntl_mode= fcntl(sd, F_GETFL);
67
 
}
68
 
 
69
 
Vio::~Vio()
70
 
{
71
 
 if (!closed)
72
 
    close();
73
 
}
74
 
 
75
 
int Vio::close()
76
 
{
77
 
  int r=0;
78
 
  if (!closed)
79
 
  {
80
 
    assert(sd >= 0);
81
 
    if (shutdown(sd, SHUT_RDWR))
82
 
      r= -1;
83
 
    if (::close(sd))
84
 
      r= -1;
85
 
  }
86
 
  closed= true;
87
 
  sd=   -1;
88
 
 
89
 
  return r;
90
 
}
91
 
 
92
 
size_t Vio::read(unsigned char* buf, size_t size)
93
 
{
94
 
  size_t r;
95
 
 
96
 
  /* Ensure nobody uses vio_read_buff and vio_read simultaneously */
97
 
  assert(read_end == read_pos);
98
 
  r= ::read(sd, buf, size);
99
 
 
100
 
  return r;
101
 
}
102
 
 
103
 
size_t Vio::write(const unsigned char* buf, size_t size)
104
 
{
105
 
  size_t r;
106
 
 
107
 
  r = ::write(sd, buf, size);
108
 
 
109
 
  return r;
110
 
}
111
 
 
112
 
int Vio::blocking(bool set_blocking_mode, bool *old_mode)
113
 
{
114
 
  int r=0;
115
 
 
116
 
  // make sure ptr is not NULL:
117
 
  if (NULL != old_mode)
118
 
    *old_mode= drizzled::test(!(fcntl_mode & O_NONBLOCK));
119
 
 
120
 
  if (sd >= 0)
121
 
  {
122
 
    int old_fcntl=fcntl_mode;
123
 
    if (set_blocking_mode)
124
 
      fcntl_mode &= ~O_NONBLOCK; /* clear bit */
125
 
    else
126
 
      fcntl_mode |= O_NONBLOCK; /* set bit */
127
 
    if (old_fcntl != fcntl_mode)
128
 
    {
129
 
      r= fcntl(sd, F_SETFL, fcntl_mode);
130
 
      if (r == -1)
131
 
      {
132
 
        fcntl_mode= old_fcntl;
133
 
      }
134
 
    }
135
 
  }
136
 
 
137
 
  return r;
138
 
}
139
 
 
140
 
int Vio::fastsend()
141
 
{
142
 
  int nodelay = 1;
143
 
  int error;
144
 
 
145
 
  error= setsockopt(sd, IPPROTO_TCP, TCP_NODELAY,
146
 
                    &nodelay, sizeof(nodelay));
147
 
  if (error != 0)
148
 
  {
149
 
    perror("setsockopt");
150
 
  }
151
 
 
152
 
  return error;
153
 
}
154
 
 
155
 
int32_t Vio::keepalive(bool set_keep_alive)
156
 
{
157
 
  int r= 0;
158
 
  uint32_t opt= 0;
159
 
 
160
 
  if (set_keep_alive)
161
 
    opt= 1;
162
 
 
163
 
  r= setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
164
 
  if (r != 0)
165
 
  {
166
 
    perror("setsockopt");
167
 
    assert(r == 0);
168
 
  }
169
 
 
170
 
  return r;
171
 
}
172
 
 
173
 
bool Vio::should_retry() const
174
 
{
175
 
  int en = errno;
176
 
  return (en == EAGAIN || en == EINTR ||
177
 
          en == EWOULDBLOCK);
178
 
}
179
 
 
180
 
bool Vio::was_interrupted() const
181
 
{
182
 
  int en= errno;
183
 
  return (en == EAGAIN || en == EINTR ||
184
 
          en == EWOULDBLOCK || en == ETIMEDOUT);
185
 
}
186
 
 
187
 
bool Vio::peer_addr(char *buf, uint16_t *port, size_t buflen) const
188
 
{
189
 
  int error;
190
 
  char port_buf[NI_MAXSERV];
191
 
  socklen_t al = sizeof(remote);
192
 
 
193
 
  if (getpeername(sd, (struct sockaddr *) (&remote),
194
 
                  &al) != 0)
195
 
  {
196
 
    return true;
197
 
  }
198
 
 
199
 
  if ((error= getnameinfo((struct sockaddr *)(&remote),
200
 
                          al,
201
 
                          buf, buflen,
202
 
                          port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
203
 
  {
204
 
    return true;
205
 
  }
206
 
 
207
 
  *port= (uint16_t)strtol(port_buf, (char **)NULL, 10);
208
 
 
209
 
  return false;
210
 
}
211
 
 
212
 
void Vio::timeout(bool is_sndtimeo, int32_t t)
213
 
{
214
 
  int error;
215
 
 
216
 
  /* POSIX specifies time as struct timeval. */
217
 
  struct timeval wait_timeout;
218
 
  wait_timeout.tv_sec= t;
219
 
  wait_timeout.tv_usec= 0;
220
 
 
221
 
  assert(t >= 0 && t <= INT32_MAX);
222
 
  assert(sd != -1);
223
 
  error= setsockopt(sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
224
 
                    &wait_timeout,
225
 
                    (socklen_t)sizeof(struct timeval));
226
 
  if (error == -1 && errno != ENOPROTOOPT)
227
 
  {
228
 
    perror("setsockopt");
229
 
    assert(error == 0);
230
 
  }
231
 
}
232
 
 
233
 
int Vio::get_errno() const
234
 
{
235
 
  return errno;
236
 
}
237
 
 
238
 
int Vio::get_fd() const
239
 
{
240
 
  return sd;
241
 
}
242
 
 
243
 
 
244
 
char *Vio::get_read_pos() const
245
 
{
246
 
  return read_pos;
247
 
}
248
 
 
249
 
char *Vio::get_read_end() const
250
 
{
251
 
  return read_end;
252
 
}
253
 
 
254
 
} /* namespace drizzle_plugin */