--- 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 <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
+#include <fcntl.h>
#include <string.h>
#include <assert.h>
/*
* 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);
-}