2
Copyright (C) 2000-2007 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; see the file COPYING. If not, write to the
15
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20
/* The socket wrapper source implements a Socket class that hides the
21
* differences between Berkely style sockets and Windows sockets, allowing
22
* transparent TCP access.
26
#include "runtime.hpp"
27
#include "socket_wrapper.hpp"
33
#include <arpa/inet.h>
34
#include <netinet/in.h>
35
#include <sys/ioctl.h>
40
#if defined(__sun) || defined(__SCO_VERSION__) || defined(__NETWARE__)
41
#include <sys/filio.h>
45
const int SOCKET_EINVAL = WSAEINVAL;
46
const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK;
47
const int SOCKET_EAGAIN = WSAEWOULDBLOCK;
49
const int SOCKET_EINVAL = EINVAL;
50
const int SOCKET_EWOULDBLOCK = EWOULDBLOCK;
51
const int SOCKET_EAGAIN = EAGAIN;
58
Socket::Socket(socket_t s)
59
: socket_(s), wouldBlock_(false), nonBlocking_(false)
63
void Socket::set_fd(socket_t s)
69
socket_t Socket::get_fd() const
77
// don't close automatically now
81
void Socket::closeSocket()
83
if (socket_ != INVALID_SOCKET) {
89
socket_ = INVALID_SOCKET;
94
uint Socket::get_ready() const
97
unsigned long ready = 0;
98
ioctlsocket(socket_, FIONREAD, &ready);
101
64-bit Solaris requires the variable passed to
102
FIONREAD be a 32-bit value.
104
unsigned int ready = 0;
105
ioctl(socket_, FIONREAD, &ready);
112
uint Socket::send(const byte* buf, unsigned int sz, int flags) const
114
const byte* pos = buf;
115
const byte* end = pos + sz;
118
int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
119
static_cast<int>(end - pos), flags);
131
uint Socket::receive(byte* buf, unsigned int sz, int flags)
135
int recvd = ::recv(socket_, reinterpret_cast<char *>(buf), sz, flags);
137
// idea to seperate error from would block by arnetheduck@gmail.com
139
if (get_lastError() == SOCKET_EWOULDBLOCK ||
140
get_lastError() == SOCKET_EAGAIN) {
141
wouldBlock_ = true; // would have blocked this time only
142
nonBlocking_ = true; // socket nonblocking, win32 only way to tell
147
return static_cast<uint>(-1);
153
// wait if blocking for input, return false for error
157
return receive(&b, 1, MSG_PEEK) != static_cast<uint>(-1);
161
void Socket::shutDown(int how)
163
shutdown(socket_, how);
167
int Socket::get_lastError()
170
return WSAGetLastError();
177
bool Socket::WouldBlock() const
183
bool Socket::IsNonBlocking() const
189
void Socket::set_lastError(int errorCode)
192
WSASetLastError(errorCode);