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)
43
namespace drizzle_plugin
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
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
65
fcntl(sd, F_SETFL, 0);
66
fcntl_mode= fcntl(sd, F_GETFL);
81
if (shutdown(sd, SHUT_RDWR))
92
size_t Vio::read(unsigned char* buf, size_t size)
64
96
/* 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);
97
assert(read_end == read_pos);
98
r= ::read(sd, buf, size);
71
static size_t _vio_write(Vio * vio, const unsigned char* buf, size_t size)
103
size_t Vio::write(const unsigned char* buf, size_t size)
75
r = write(vio->sd, buf, size);
107
r = ::write(sd, buf, size);
80
static int _vio_blocking(Vio * vio, bool set_blocking_mode, bool *old_mode)
112
int Vio::blocking(bool set_blocking_mode, bool *old_mode)
84
*old_mode= drizzled::test(!(vio->fcntl_mode & O_NONBLOCK));
116
// make sure ptr is not NULL:
117
if (NULL != old_mode)
118
*old_mode= drizzled::test(!(fcntl_mode & O_NONBLOCK));
88
int old_fcntl=vio->fcntl_mode;
122
int old_fcntl=fcntl_mode;
89
123
if (set_blocking_mode)
90
vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
124
fcntl_mode &= ~O_NONBLOCK; /* clear bit */
92
vio->fcntl_mode |= O_NONBLOCK; /* set bit */
93
if (old_fcntl != vio->fcntl_mode)
126
fcntl_mode |= O_NONBLOCK; /* set bit */
127
if (old_fcntl != fcntl_mode)
95
r= fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
129
r= fcntl(sd, F_SETFL, fcntl_mode);
98
vio->fcntl_mode= old_fcntl;
132
fcntl_mode= old_fcntl;
106
static int _vio_fastsend(Vio * vio)
112
error= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
145
error= setsockopt(sd, IPPROTO_TCP, TCP_NODELAY,
113
146
&nodelay, sizeof(nodelay));
116
149
perror("setsockopt");
123
static int32_t _vio_keepalive(Vio* vio, bool set_keep_alive)
155
int32_t Vio::keepalive(bool set_keep_alive)
141
static bool _vio_should_retry(Vio * vio)
173
bool Vio::should_retry() const
145
176
return (en == EAGAIN || en == EINTR ||
149
static bool _vio_was_interrupted(Vio *vio)
180
bool Vio::was_interrupted() const
153
183
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)
184
en == EWOULDBLOCK || en == ETIMEDOUT);
187
bool Vio::peer_addr(char *buf, uint16_t *port, size_t buflen) const
177
190
char port_buf[NI_MAXSERV];
178
socklen_t addrLen = sizeof(vio->remote);
191
socklen_t al = sizeof(remote);
180
if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
193
if (getpeername(sd, (struct sockaddr *) (&remote),
185
vio->addrLen= (int)addrLen;
187
if ((error= getnameinfo((struct sockaddr *)(&vio->remote),
199
if ((error= getnameinfo((struct sockaddr *)(&remote),
190
202
port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
200
static void _vio_timeout(Vio *vio, bool is_sndtimeo, int32_t timeout)
212
void Vio::timeout(bool is_sndtimeo, int32_t t)
204
216
/* POSIX specifies time as struct timeval. */
205
217
struct timeval wait_timeout;
206
wait_timeout.tv_sec= timeout;
218
wait_timeout.tv_sec= t;
207
219
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,
221
assert(t >= 0 && t <= INT32_MAX);
223
error= setsockopt(sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
213
225
(socklen_t)sizeof(struct timeval));
214
226
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);
233
int Vio::get_errno() const
238
int Vio::get_fd() const
244
char *Vio::get_read_pos() const
249
char *Vio::get_read_end() const
254
} /* namespace drizzle_plugin */