12
12
You should have received a copy of the GNU General Public License
13
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 */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
17
Note that we can't have assertion on file descriptors; The reason for
42
41
using namespace std;
44
static void _vio_delete(Vio* vio)
47
return; /* It must be safe to delete null pointers. */
51
free((unsigned char*) vio);
54
static int _vio_errno(Vio *vio)
60
static size_t _vio_read(Vio * vio, unsigned char* buf, size_t size)
54
We call fcntl() to set the flags and then immediately read them back
55
to make sure that we and the system are in agreement on the state of
58
An example of why we need to do this is FreeBSD (and apparently some
59
other BSD-derived systems, like Mac OS X), where the system sometimes
60
reports that the socket is set for non-blocking when it really will
63
fcntl(sd, F_SETFL, 0);
64
fcntl_mode= fcntl(sd, F_GETFL);
66
memset(&local, 0, sizeof(local));
67
memset(&remote, 0, sizeof(remote));
82
if (shutdown(sd, SHUT_RDWR))
93
size_t Vio::read(unsigned char* buf, size_t size)
64
97
/* Ensure nobody uses vio_read_buff and vio_read simultaneously */
65
assert(vio->read_end == vio->read_pos);
66
r= read(vio->sd, buf, size);
98
assert(read_end == read_pos);
99
r= ::read(sd, buf, size);
71
static size_t _vio_write(Vio * vio, const unsigned char* buf, size_t size)
104
size_t Vio::write(const unsigned char* buf, size_t size)
75
r = write(vio->sd, buf, size);
108
r = ::write(sd, buf, size);
80
static int _vio_blocking(Vio * vio, bool set_blocking_mode, bool *old_mode)
113
int Vio::blocking(bool set_blocking_mode, bool *old_mode)
84
*old_mode= drizzled::test(!(vio->fcntl_mode & O_NONBLOCK));
117
// make sure ptr is not NULL:
118
if (NULL != old_mode)
119
*old_mode= drizzled::test(!(fcntl_mode & O_NONBLOCK));
88
int old_fcntl=vio->fcntl_mode;
123
int old_fcntl=fcntl_mode;
89
124
if (set_blocking_mode)
90
vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
125
fcntl_mode &= ~O_NONBLOCK; /* clear bit */
92
vio->fcntl_mode |= O_NONBLOCK; /* set bit */
93
if (old_fcntl != vio->fcntl_mode)
127
fcntl_mode |= O_NONBLOCK; /* set bit */
128
if (old_fcntl != fcntl_mode)
95
r= fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
130
r= fcntl(sd, F_SETFL, fcntl_mode);
98
vio->fcntl_mode= old_fcntl;
133
fcntl_mode= old_fcntl;
106
static int _vio_fastsend(Vio * vio)
112
error= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
146
error= setsockopt(sd, IPPROTO_TCP, TCP_NODELAY,
113
147
&nodelay, sizeof(nodelay));
116
150
perror("setsockopt");
123
static int32_t _vio_keepalive(Vio* vio, bool set_keep_alive)
156
int32_t Vio::keepalive(bool set_keep_alive)
141
static bool _vio_should_retry(Vio * vio)
174
bool Vio::should_retry() const
145
177
return (en == EAGAIN || en == EINTR ||
149
static bool _vio_was_interrupted(Vio *vio)
181
bool Vio::was_interrupted() const
153
184
return (en == EAGAIN || en == EINTR ||
154
en == EWOULDBLOCK || en == ETIMEDOUT);
157
static int _vio_close(Vio * vio)
162
assert(vio->sd >= 0);
163
if (shutdown(vio->sd, SHUT_RDWR))
174
static bool _vio_peer_addr(Vio *vio, char *buf, uint16_t *port, size_t buflen)
185
en == EWOULDBLOCK || en == ETIMEDOUT);
188
bool Vio::peer_addr(char *buf, uint16_t *port, size_t buflen) const
177
191
char port_buf[NI_MAXSERV];
178
socklen_t addrLen = sizeof(vio->remote);
192
socklen_t al = sizeof(remote);
180
if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
194
if (getpeername(sd, (struct sockaddr *) (&remote),
185
vio->addrLen= (int)addrLen;
187
if ((error= getnameinfo((struct sockaddr *)(&vio->remote),
200
if ((error= getnameinfo((struct sockaddr *)(&remote),
190
203
port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
200
static void _vio_timeout(Vio *vio, bool is_sndtimeo, int32_t timeout)
213
void Vio::timeout(bool is_sndtimeo, int32_t t)
204
217
/* POSIX specifies time as struct timeval. */
205
218
struct timeval wait_timeout;
206
wait_timeout.tv_sec= timeout;
219
wait_timeout.tv_sec= t;
207
220
wait_timeout.tv_usec= 0;
209
assert(timeout >= 0 && timeout <= INT32_MAX);
210
assert(vio->sd != -1);
211
error= setsockopt(vio->sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
222
assert(t >= 0 && t <= INT32_MAX);
224
error= setsockopt(sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
213
226
(socklen_t)sizeof(struct timeval));
214
227
if (error == -1 && errno != ENOPROTOOPT)
221
/* Open the socket or TCP/IP connection and read the fnctl() status */
222
Vio *mysql_protocol_vio_new(int sd)
224
Vio *vio = (Vio*) malloc(sizeof(Vio));
228
memset(vio, 0, sizeof(*vio));
231
vio->viodelete= _vio_delete;
232
vio->vioerrno= _vio_errno;
233
vio->read= _vio_read;
234
vio->write= _vio_write;
235
vio->fastsend= _vio_fastsend;
236
vio->viokeepalive= _vio_keepalive;
237
vio->should_retry= _vio_should_retry;
238
vio->was_interrupted= _vio_was_interrupted;
239
vio->vioclose= _vio_close;
240
vio->peer_addr= _vio_peer_addr;
241
vio->vioblocking= _vio_blocking;
242
vio->timeout= _vio_timeout;
245
We call fcntl() to set the flags and then immediately read them back
246
to make sure that we and the system are in agreement on the state of
249
An example of why we need to do this is FreeBSD (and apparently some
250
other BSD-derived systems, like Mac OS X), where the system sometimes
251
reports that the socket is set for non-blocking when it really will
254
fcntl(sd, F_SETFL, 0);
255
vio->fcntl_mode= fcntl(sd, F_GETFL);
234
int Vio::get_errno() const
239
int Vio::get_fd() const
245
char *Vio::get_read_pos() const
250
char *Vio::get_read_end() const