--- a/src/sock_tcp.c Sat Feb 28 17:39:37 2009 +0200
+++ b/src/sock_tcp.c Sat Feb 28 18:48:10 2009 +0200
@@ -18,11 +18,7 @@
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);
+ sock_stream_invoke_callbacks(SOCK_TCP_BASE(sock), what);
}
/*
@@ -33,14 +29,26 @@
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)
- // errno
+ // read(), and detect non-EAGAIN or EOF
+ if ((ret = read(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
+ // unexpected error
RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
+
+ else if (ret == 0)
+ // EOF
+ return SET_ERROR(SOCK_TCP_ERR(sock), ERR_READ_EOF);
- // bytes read
- *len = ret;
+ if (ret < 0) {
+ // EAGAIN -> zero bytes
+ *len = 0;
+
+ } else {
+ // normal -> bytes read
+ *len = ret;
+ }
+
+ // ok
return SUCCESS;
}
@@ -52,13 +60,24 @@
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)
- // errno
+ // write(), and detect non-EAGAIN or EOF
+ if ((ret = write(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
+ // unexpected error
RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
+
+ else if (ret == 0)
+ // EOF
+ return SET_ERROR(SOCK_TCP_ERR(sock), ERR_WRITE_EOF);
- // bytes read
- *len = ret;
+
+ if (ret < 0) {
+ // EAGAIN -> zero bytes
+ *len = 0;
+
+ } else {
+ // normal -> bytes read
+ *len = ret;
+ }
return SUCCESS;
}
@@ -83,16 +102,9 @@
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);
-
- // just add the appropraite events
- if (mask & EV_READ && event_add(sock->ev_read, NULL))
- return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
-
- if (mask & EV_WRITE && event_add(sock->ev_write, NULL))
- return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
- // done
- return SUCCESS;
+ // implemented in sock_tcp_add_event
+ return sock_tcp_add_event(sock, mask);
}
/*
@@ -149,6 +161,19 @@
return SUCCESS;
}
+err_t sock_tcp_add_event (struct sock_tcp *sock, short mask)
+{
+ // just add the appropraite events
+ if (mask & EV_READ && event_add(sock->ev_read, NULL))
+ return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
+
+ if (mask & EV_WRITE && event_add(sock->ev_write, NULL))
+ return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
+
+ // done
+ return SUCCESS;
+}
+
err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service)
{
struct addrinfo hints, *res, *r;