diff -r 4c4c906cc649 -r 9fe218576d13 src/sock_tcp.c --- a/src/sock_tcp.c Sun Feb 22 08:48:21 2009 +0200 +++ b/src/sock_tcp.c Sun Feb 22 10:16:28 2009 +0200 @@ -6,53 +6,87 @@ #include #include #include +#include #include #include /* * Our sock_stream_methods.read method */ -static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t len) +static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len) { struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); int ret; // map directly to read(2) - if ((ret = read(sock->fd, buf, len)) < 0) + if ((ret = read(sock->fd, buf, *len)) < 0) // errno RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ); - else - // bytes read - return ret; + // bytes read + *len = ret; + + return SUCCESS; } /* * Our sock_stream_methods.write method */ -static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t len) +static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len) { struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); int ret; // map directly to write(2) - if ((ret = write(sock->fd, buf, len)) < 0) + if ((ret = write(sock->fd, buf, *len)) < 0) // errno RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE); - else - // bytes read - return ret; + // bytes read + *len = ret; + + return SUCCESS; +} + +static err_t sock_tcp_event_init (struct sock_stream *base_sock) +{ + struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); + + return SUCCESS; +} + +static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask) +{ + struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); + + return SUCCESS; } /* * Our sock_stream_type */ struct sock_stream_type sock_tcp_type = { - .methods.read = &sock_tcp_read, - .methods.write = &sock_tcp_write, + .methods.read = &sock_tcp_read, + .methods.write = &sock_tcp_write, + .methods.event_init = &sock_tcp_event_init, + .methods.event_enable = &sock_tcp_event_enable, }; +/* + * Our basic socket event handler for driving our callbacks + */ +static void sock_tcp_event (evutil_socket_t fd, short what, void *arg) +{ + struct sock_tcp *sock = arg; + + // invoke appropriate callback + if (what & EV_READ && SOCK_TCP_BASE(sock)->cb_info->on_read) + SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); + + if (what & EV_WRITE && SOCK_TCP_BASE(sock)->cb_info->on_write) + SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); +} + err_t sock_tcp_alloc (struct sock_tcp **sock_ptr) { // alloc @@ -78,6 +112,19 @@ return SUCCESS; } +err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg) +{ + // require valid fd + assert(sock->fd >= 0); + + // create new event + if ((sock->ev = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL) + return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW); + + // ok + return SUCCESS; +} + err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service) { struct addrinfo hints, *res, *r; @@ -137,6 +184,26 @@ return 0; } +err_t sock_tcp_set_nonblock (struct sock_tcp *sock, int nonblock) +{ + // fcntl it + // XXX: maintain old flags? + if (fcntl(sock->fd, F_SETFL, nonblock ? O_NONBLOCK : 0) < 0) + RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_FCNTL); + + // ok + return SUCCESS; +} + +void sock_tcp_release (struct sock_tcp *sock) +{ + // must not be connected + assert(sock->fd < 0); + + // free + free(sock); +} + err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err_info) { struct sock_tcp *sock; @@ -164,11 +231,4 @@ return 0; } -void sock_tcp_release (struct sock_tcp *sock) -{ - // must not be connected - assert(sock->fd < 0); - // free - free(sock); -}