static int cntl_getset_impl(lcb_io_opt_t io, lcb_socket_t sock, int mode, int oslevel, int osopt, int optsize, void *optval) { int rv; #ifndef _WIN32 socklen_t dummy = optsize; #else int dummy = optsize; #endif if (mode == LCB_IO_CNTL_GET) { rv = getsockopt(sock, oslevel, osopt, &dummy, optval); } else { rv = setsockopt(sock, oslevel, osopt, optval, optsize); } if (rv == 0) { return 0; } else { int lasterr; #ifdef _WIN32 lasterr = get_wserr(sock); #else lasterr = errno; #endif LCB_IOPS_ERRNO(io) = lasterr; return -1; } }
static lcb_ssize_t recvv_impl(lcb_io_opt_t iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov) { DWORD flags = 0, nr; WSABUF *bufptr = (WSABUF *)iov; if (WSARecv(sock, bufptr, niov, &nr, &flags, NULL, NULL) == SOCKET_ERROR) { LCB_IOPS_ERRNO(iops) = get_wserr(sock); if (LCB_IOPS_ERRNO(iops) == ECONNRESET) { return 0; } return -1; } (void)iops; return (lcb_ssize_t)nr; }
static int connect_impl(lcb_io_opt_t iops, lcb_socket_t sock, const struct sockaddr *name, unsigned int namelen) { int ret; #ifdef _WIN32 ret = WSAConnect(sock, name, (int)namelen, NULL, NULL, NULL, NULL); if (ret == SOCKET_ERROR) { LCB_IOPS_ERRNO(iops) = get_wserr(sock); } #else ret = connect(sock, name, (socklen_t)namelen); if (ret < 0) { LCB_IOPS_ERRNO(iops) = errno; } #endif return ret; }
static lcb_ssize_t send_impl(lcb_io_opt_t iops, lcb_socket_t sock, const void *buf, lcb_size_t nbuf, int flags) { lcb_ssize_t ret = send(sock, buf, nbuf, flags); if (ret < 0) { LCB_IOPS_ERRNO(iops) = errno; } return ret; }
static lcb_ssize_t sendv_impl(lcb_io_opt_t iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov) { DWORD nw, fl = 0; WSABUF *bufptr = (WSABUF *)iov; if (WSASend(sock, bufptr, niov, &nw, fl, NULL, NULL) == SOCKET_ERROR) { LCB_IOPS_ERRNO(iops) = get_wserr(sock); return -1; } return (lcb_ssize_t)nw; }
static int cntl_impl(lcb_io_opt_t io, lcb_socket_t sock, int mode, int option, void *arg) { switch (option) { case LCB_IO_CNTL_TCP_NODELAY: return cntl_getset_impl(io, sock, mode, IPPROTO_TCP, TCP_NODELAY, sizeof(int), arg); default: LCB_IOPS_ERRNO(io) = ENOTSUP; return -1; } }
static int cntl_socket(lcb_io_opt_t iobase, lcb_sockdata_t *sockbase, int mode, int option, void *arg) { my_sockdata_t *sd = (my_sockdata_t *)sockbase; int rv; switch (option) { case LCB_IO_CNTL_TCP_NODELAY: if (mode == LCB_IO_CNTL_GET) { rv = uv_tcp_nodelay(&sd->tcp.t, *(int *)arg); if (rv != 0) { set_last_error((my_iops_t*)iobase, rv); } return rv; } else { LCB_IOPS_ERRNO(iobase) = ENOTSUP; return -1; } default: LCB_IOPS_ERRNO(iobase) = ENOTSUP; return -1; } }
static lcb_socket_t socket_impl(lcb_io_opt_t iops, int domain, int type, int protocol) { lcb_socket_t sock; #ifdef _WIN32 sock = (lcb_socket_t)WSASocket(domain, type, protocol, NULL, 0, 0); #else sock = socket(domain, type, protocol); #endif if (sock == INVALID_SOCKET) { LCB_IOPS_ERRNO(iops) = errno; } else { if (make_socket_nonblocking(sock) != 0) { #ifdef _WIN32 LCB_IOPS_ERRNO(iops) = get_wserr(sock); #else LCB_IOPS_ERRNO(iops) = errno; #endif close_impl(iops, sock); sock = INVALID_SOCKET; } } return sock; }
static lcb_ssize_t sendv_impl(lcb_io_opt_t iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov) { struct msghdr mh; lcb_ssize_t ret; memset(&mh, 0, sizeof(mh)); mh.msg_iov = (struct iovec *)iov; mh.msg_iovlen = niov; ret = sendmsg(sock, &mh, 0); if (ret < 0) { LCB_IOPS_ERRNO(iops) = errno; } return ret; }