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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
Note that we can't have assertion on file descriptors; The reason for
41
42
using namespace std;
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)
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)
96
64
/* Ensure nobody uses vio_read_buff and vio_read simultaneously */
97
assert(read_end == read_pos);
98
r= ::read(sd, buf, size);
65
assert(vio->read_end == vio->read_pos);
66
r= read(vio->sd, buf, size);
103
size_t Vio::write(const unsigned char* buf, size_t size)
71
static size_t _vio_write(Vio * vio, const unsigned char* buf, size_t size)
107
r = ::write(sd, buf, size);
75
r = write(vio->sd, buf, size);
112
int Vio::blocking(bool set_blocking_mode, bool *old_mode)
80
static int _vio_blocking(Vio * vio, bool set_blocking_mode, bool *old_mode)
116
// make sure ptr is not NULL:
117
if (NULL != old_mode)
118
*old_mode= drizzled::test(!(fcntl_mode & O_NONBLOCK));
84
*old_mode= drizzled::test(!(vio->fcntl_mode & O_NONBLOCK));
122
int old_fcntl=fcntl_mode;
88
int old_fcntl=vio->fcntl_mode;
123
89
if (set_blocking_mode)
124
fcntl_mode &= ~O_NONBLOCK; /* clear bit */
90
vio->fcntl_mode &= ~O_NONBLOCK; /* clear bit */
126
fcntl_mode |= O_NONBLOCK; /* set bit */
127
if (old_fcntl != fcntl_mode)
92
vio->fcntl_mode |= O_NONBLOCK; /* set bit */
93
if (old_fcntl != vio->fcntl_mode)
129
r= fcntl(sd, F_SETFL, fcntl_mode);
95
r= fcntl(vio->sd, F_SETFL, vio->fcntl_mode);
132
fcntl_mode= old_fcntl;
98
vio->fcntl_mode= old_fcntl;
106
static int _vio_fastsend(Vio * vio)
145
error= setsockopt(sd, IPPROTO_TCP, TCP_NODELAY,
112
error= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY,
146
113
&nodelay, sizeof(nodelay));
149
116
perror("setsockopt");
155
int32_t Vio::keepalive(bool set_keep_alive)
123
static int32_t _vio_keepalive(Vio* vio, bool set_keep_alive)
173
bool Vio::should_retry() const
141
static bool _vio_should_retry(Vio * vio)
176
145
return (en == EAGAIN || en == EINTR ||
180
bool Vio::was_interrupted() const
149
static bool _vio_was_interrupted(Vio *vio)
183
153
return (en == EAGAIN || en == EINTR ||
184
en == EWOULDBLOCK || en == ETIMEDOUT);
187
bool Vio::peer_addr(char *buf, uint16_t *port, size_t buflen) const
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)
190
177
char port_buf[NI_MAXSERV];
191
socklen_t al = sizeof(remote);
178
socklen_t addrLen = sizeof(vio->remote);
193
if (getpeername(sd, (struct sockaddr *) (&remote),
180
if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
185
vio->addrLen= (int)addrLen;
199
if ((error= getnameinfo((struct sockaddr *)(&remote),
187
if ((error= getnameinfo((struct sockaddr *)(&vio->remote),
202
190
port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
212
void Vio::timeout(bool is_sndtimeo, int32_t t)
200
static void _vio_timeout(Vio *vio, bool is_sndtimeo, int32_t timeout)
216
204
/* POSIX specifies time as struct timeval. */
217
205
struct timeval wait_timeout;
218
wait_timeout.tv_sec= t;
206
wait_timeout.tv_sec= timeout;
219
207
wait_timeout.tv_usec= 0;
221
assert(t >= 0 && t <= INT32_MAX);
223
error= setsockopt(sd, SOL_SOCKET, is_sndtimeo ? SO_SNDTIMEO : SO_RCVTIMEO,
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,
225
213
(socklen_t)sizeof(struct timeval));
226
214
if (error == -1 && errno != ENOPROTOOPT)
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 */
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);