~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to vio/viosocket.c

  • Committer: Brian Aker
  • Date: 2008-07-13 21:20:24 UTC
  • Revision ID: brian@tangent.org-20080713212024-o6263c1vha7yxdeu
More bool removal. More cow bell!

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
*/
22
22
 
23
23
#include "vio_priv.h"
24
 
#include <sys/socket.h>
25
 
#include <drizzled/util/test.h>
26
24
 
27
25
int vio_errno(Vio *vio __attribute__((unused)))
28
26
{
29
 
  return errno;
 
27
  return socket_errno;          /* On Win32 this mapped to WSAGetLastError() */
30
28
}
31
29
 
32
30
 
33
 
size_t vio_read(Vio * vio, unsigned char* buf, size_t size)
 
31
size_t vio_read(Vio * vio, uchar* buf, size_t size)
34
32
{
35
33
  size_t r;
36
34
 
37
35
  /* Ensure nobody uses vio_read_buff and vio_read simultaneously */
38
36
  assert(vio->read_end == vio->read_pos);
39
 
  r= read(vio->sd, buf, size);
40
 
 
 
37
  errno=0;                                      /* For linux */
 
38
  r = read(vio->sd, buf, size);
41
39
  return r;
42
40
}
43
41
 
47
45
  reduce number of syscalls.
48
46
*/
49
47
 
50
 
size_t vio_read_buff(Vio *vio, unsigned char* buf, size_t size)
 
48
size_t vio_read_buff(Vio *vio, uchar* buf, size_t size)
51
49
{
52
50
  size_t rc;
53
51
#define VIO_UNBUFFERED_READ_MIN_SIZE 2048
54
52
 
55
53
  if (vio->read_pos < vio->read_end)
56
54
  {
57
 
    rc= cmin((size_t) (vio->read_end - vio->read_pos), size);
 
55
    rc= min((size_t) (vio->read_end - vio->read_pos), size);
58
56
    memcpy(buf, vio->read_pos, rc);
59
57
    vio->read_pos+= rc;
60
58
    /*
65
63
  }
66
64
  else if (size < VIO_UNBUFFERED_READ_MIN_SIZE)
67
65
  {
68
 
    rc= vio_read(vio, (unsigned char*) vio->read_buffer, VIO_READ_BUFFER_SIZE);
 
66
    rc= vio_read(vio, (uchar*) vio->read_buffer, VIO_READ_BUFFER_SIZE);
69
67
    if (rc != 0 && rc != (size_t) -1)
70
68
    {
71
69
      if (rc > size)
85
83
}
86
84
 
87
85
 
88
 
size_t vio_write(Vio * vio, const unsigned char* buf, size_t size)
 
86
size_t vio_write(Vio * vio, const uchar* buf, size_t size)
89
87
{
90
88
  size_t r;
91
89
 
94
92
  return r;
95
93
}
96
94
 
97
 
int vio_blocking(Vio * vio, bool set_blocking_mode, bool *old_mode)
 
95
int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode,
 
96
                 my_bool *old_mode)
98
97
{
99
98
  int r=0;
100
99
 
101
100
  *old_mode= test(!(vio->fcntl_mode & O_NONBLOCK));
102
101
 
 
102
#if !defined(NO_FCNTL_NONBLOCK)
103
103
  if (vio->sd >= 0)
104
104
  {
105
105
    int old_fcntl=vio->fcntl_mode;
116
116
      }
117
117
    }
118
118
  }
119
 
 
 
119
#else
 
120
  r= set_blocking_mode ? 0 : 1;
 
121
#endif /* !defined(NO_FCNTL_NONBLOCK) */
120
122
  return r;
121
123
}
122
124
 
123
 
bool
 
125
my_bool
124
126
vio_is_blocking(Vio * vio)
125
127
{
126
 
  bool r;
 
128
  my_bool r;
127
129
  r = !(vio->fcntl_mode & O_NONBLOCK);
128
130
 
129
131
  return r;
132
134
 
133
135
int vio_fastsend(Vio * vio __attribute__((unused)))
134
136
{
135
 
  int nodelay = 1;
136
 
  int error;
137
 
 
138
 
  error= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
139
 
                    &nodelay, sizeof(nodelay));
140
 
  if (error != 0)
141
 
  {
142
 
    perror("setsockopt");
143
 
    assert(error == 0);
144
 
  }
145
 
 
146
 
  return error;
 
137
  int r=0;
 
138
 
 
139
#if defined(IPTOS_THROUGHPUT)
 
140
  {
 
141
    int tos = IPTOS_THROUGHPUT;
 
142
    r= setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos));
 
143
  }
 
144
#endif                                    /* IPTOS_THROUGHPUT */
 
145
  if (!r)
 
146
  {
 
147
    int nodelay = 1;
 
148
 
 
149
    r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
 
150
                  IF_WIN(const char*, void*) &nodelay,
 
151
                  sizeof(nodelay));
 
152
 
 
153
  }
 
154
  if (r)
 
155
  {
 
156
    r= -1;
 
157
  }
 
158
 
 
159
  return r;
147
160
}
148
161
 
149
 
int32_t vio_keepalive(Vio* vio, bool set_keep_alive)
 
162
int vio_keepalive(Vio* vio, my_bool set_keep_alive)
150
163
{
151
164
  int r= 0;
152
 
  uint32_t opt= 0;
153
 
 
154
 
  if (set_keep_alive)
155
 
    opt= 1;
156
 
 
157
 
  r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
158
 
  if (r != 0)
 
165
  uint opt= 0;
 
166
 
 
167
  if (vio->type != VIO_TYPE_NAMEDPIPE)
159
168
  {
160
 
    perror("setsockopt");
161
 
    assert(r == 0);
 
169
    if (set_keep_alive)
 
170
      opt= 1;
 
171
    r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
 
172
                  sizeof(opt));
162
173
  }
163
174
 
164
175
  return r;
165
176
}
166
177
 
167
178
 
168
 
bool
 
179
my_bool
169
180
vio_should_retry(Vio * vio __attribute__((unused)))
170
181
{
171
 
  int en = errno;
172
 
  return (en == EAGAIN || en == EINTR ||
173
 
          en == EWOULDBLOCK);
 
182
  int en = socket_errno;
 
183
  return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
 
184
          en == SOCKET_EWOULDBLOCK);
174
185
}
175
186
 
176
187
 
177
 
bool
 
188
my_bool
178
189
vio_was_interrupted(Vio *vio __attribute__((unused)))
179
190
{
180
 
  int en= errno;
181
 
  return (en == EAGAIN || en == EINTR ||
182
 
          en == EWOULDBLOCK || en == ETIMEDOUT);
 
191
  int en= socket_errno;
 
192
  return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
 
193
          en == SOCKET_EWOULDBLOCK || en == SOCKET_ETIMEDOUT);
183
194
}
184
195
 
185
196
 
191
202
    assert(vio->sd >= 0);
192
203
    if (shutdown(vio->sd, SHUT_RDWR))
193
204
      r= -1;
194
 
    if (close(vio->sd))
 
205
    if (closesocket(vio->sd))
195
206
      r= -1;
196
207
  }
197
208
  vio->type= VIO_CLOSED;
211
222
  return vio->type;
212
223
}
213
224
 
214
 
int vio_fd(Vio* vio)
 
225
my_socket vio_fd(Vio* vio)
215
226
{
216
227
  return vio->sd;
217
228
}
218
229
 
219
 
bool vio_peer_addr(Vio *vio, char *buf, uint16_t *port, size_t buflen)
 
230
my_bool vio_peer_addr(Vio *vio, char *buf, uint16 *port, size_t buflen)
220
231
{
221
 
  int error;
222
 
  char port_buf[NI_MAXSERV];
223
 
  socklen_t addrLen = sizeof(vio->remote);
224
 
 
225
 
  if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
226
 
                  &addrLen) != 0)
227
 
  {
228
 
    return true;
229
 
  }
230
 
  vio->addrLen= (int)addrLen;
231
 
 
232
 
  if ((error= getnameinfo((struct sockaddr *)(&vio->remote), 
233
 
                          addrLen,
234
 
                          buf, buflen,
235
 
                          port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
236
 
  {
237
 
    return true;
238
 
  }
239
 
 
240
 
  *port= (uint16_t)strtol(port_buf, (char **)NULL, 10);
 
232
  if (vio->localhost)
 
233
  {
 
234
    strmov(buf, "127.0.0.1");
 
235
    *port= 0;
 
236
  }
 
237
  else
 
238
  {
 
239
    int error;
 
240
    char port_buf[NI_MAXSERV];
 
241
    size_socket addrLen = sizeof(vio->remote);
 
242
    if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
 
243
                    &addrLen) != 0)
 
244
    {
 
245
      return true;
 
246
    }
 
247
    vio->addrLen= (int)addrLen;
 
248
 
 
249
    if ((error= getnameinfo((struct sockaddr *)(&vio->remote), 
 
250
                            addrLen,
 
251
                            buf, buflen,
 
252
                            port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
 
253
    {
 
254
      return true;
 
255
    }
 
256
 
 
257
    *port= (uint16)strtol(port_buf, (char **)NULL, 10);
 
258
 
 
259
    /*
 
260
      A lot of users do not have IPv6 loopback resolving to localhost
 
261
      correctly setup. Should this exist? No. If we do not do it though
 
262
      we will be getting a lot of support questions from users who
 
263
      have bad setups. This code should be removed by say... 2012.
 
264
        -Brian
 
265
    */
 
266
    if (!memcmp(buf, "::ffff:127.0.0.1", sizeof("::ffff:127.0.0.1")))
 
267
      strmov(buf, "127.0.0.1");
 
268
  }
241
269
 
242
270
  return false;
243
271
}
245
273
 
246
274
/* Return 0 if there is data to be read */
247
275
 
248
 
bool vio_poll_read(Vio *vio, int32_t timeout)
 
276
my_bool vio_poll_read(Vio *vio,uint timeout)
249
277
{
 
278
#if defined(HAVE_POLL)
250
279
  struct pollfd fds;
251
280
  int res;
252
281
 
258
287
    return res < 0 ? false : true;              /* Don't return 1 on errors */
259
288
  }
260
289
  return (fds.revents & (POLLIN | POLLERR | POLLHUP) ? false : true);
 
290
#else
 
291
  return 0;
 
292
#endif
261
293
}
262
294
 
263
295
 
264
 
bool vio_peek_read(Vio *vio, uint32_t *bytes)
 
296
my_bool vio_peek_read(Vio *vio, uint *bytes)
265
297
{
 
298
#if FIONREAD_IN_SYS_IOCTL
 
299
  int len;
 
300
  if (ioctl(vio->sd, FIONREAD, &len) < 0)
 
301
    return TRUE;
 
302
  *bytes= len;
 
303
  return FALSE;
 
304
#else
266
305
  char buf[1024];
267
306
  ssize_t res= recv(vio->sd, &buf, sizeof(buf), MSG_PEEK);
268
 
 
269
307
  if (res < 0)
270
 
    return true;
271
 
  *bytes= (uint32_t)res;
272
 
  return false;
 
308
    return TRUE;
 
309
  *bytes= res;
 
310
  return FALSE;
 
311
#endif
273
312
}
274
313
 
275
 
void vio_timeout(Vio *vio, bool is_sndtimeo, int32_t timeout)
 
314
void vio_timeout(Vio *vio, uint which, uint timeout)
276
315
{
277
 
  int error;
 
316
#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
 
317
  int r;
278
318
 
 
319
  {
279
320
  /* POSIX specifies time as struct timeval. */
280
321
  struct timeval wait_timeout;
281
322
  wait_timeout.tv_sec= timeout;
282
323
  wait_timeout.tv_usec= 0;
283
324
 
284
 
  assert(timeout >= 0 && timeout <= INT32_MAX);
285
 
  assert(vio->sd != -1);
286
 
  error= setsockopt(vio->sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
287
 
                    &wait_timeout,
288
 
                    (socklen_t)sizeof(struct timeval));
289
 
  if (error != 0)
290
 
  {
291
 
    perror("setsockopt");
292
 
    assert(error == 0);
 
325
  r= setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO,
 
326
                IF_WIN(const char*, const void*)&wait_timeout,
 
327
                sizeof(wait_timeout));
 
328
 
293
329
  }
 
330
#else
 
331
/*
 
332
  Platforms not suporting setting of socket timeout should either use
 
333
  thr_alarm or just run without read/write timeout(s)
 
334
*/
 
335
#endif
294
336
}