--- a/src/error.h Sun Feb 22 10:16:28 2009 +0200
+++ b/src/error.h Sat Feb 28 17:39:37 2009 +0200
@@ -64,6 +64,7 @@
/* Libevent errors */
_ERROR_CODE( ERR_EVENT_NEW, 0x010201, NONE ),
+ _ERROR_CODE( ERR_EVENT_ADD, 0x010202, NONE ),
// mask of bits used for the error_code value
_ERROR_CODE_MASK = 0xffffff,
--- a/src/line_proto.c Sun Feb 22 10:16:28 2009 +0200
+++ b/src/line_proto.c Sat Feb 28 17:39:37 2009 +0200
@@ -56,7 +56,7 @@
// got a line?
if (line)
- lp->cb_read(lp, line, lp->cb_arg);
+ lp->cb_read(line, lp->cb_arg);
} while (line);
@@ -104,6 +104,7 @@
// initialize event-based stuff
sock_stream_event_init(sock, &line_proto_sock_stream_callbacks, lp);
+ line_proto_schedule_events(lp, EV_READ);
// return
*lp_ptr = lp;
--- a/src/line_proto.h Sun Feb 22 10:16:28 2009 +0200
+++ b/src/line_proto.h Sat Feb 28 17:39:37 2009 +0200
@@ -15,7 +15,7 @@
/*
* The callback for receiving lines
*/
-typedef void (*line_proto_read_cb)(struct line_proto *lp, const char *line, void *arg);
+typedef void (*line_proto_read_cb)(const char *line, void *arg);
/*
* Create a new line_proto off the the given sock_stream. The newly allocated line_proto will be returned via *lp_ptr.
@@ -28,10 +28,9 @@
line_proto_read_cb cb_func, void *cb_arg, struct error_info *err);
/*
- * Receive one line into the given buffer. The line will be terminated with '\r\n', and said terminator will be
- * NUL'd out, so the buffer is safe for use as a C-string after succesfull return.
- *
- * Note: currently this uses the buffer to store intermediate state, so always pass the same buffer (for now).
+ * Runs the socket recv() into our internal buffer. If a full line was received, a pointer to our internal bufffer is
+ * returned via *line_ptr, and we return SUCCESS. If we don't yet have a full line, and receiving more would block,
+ * NULL is returned via *line_ptr instead. Otherwise, nonzero error return code.
*/
err_t line_proto_read (struct line_proto *lp, const char **line_ptr);
--- a/src/nexus.c Sun Feb 22 10:16:28 2009 +0200
+++ b/src/nexus.c Sat Feb 28 17:39:37 2009 +0200
@@ -13,14 +13,17 @@
#include "line_proto.h"
#define CONNECT_HOST "irc.fixme.fi"
-#define CONNECT_SERV "6697"
+#define CONNECT_SERV "6667"
#define LINE_LENGTH 512
+void on_line (const char *line, void *arg) {
+ printf("<<< %s\n", line);
+}
+
int main (int argc, char **argv) {
struct event_base *ev_base;
struct sock_stream *sock;
struct line_proto *lp;
- char *line;
struct error_info _err;
// initialize libevent
@@ -32,25 +35,18 @@
errx(1, "sock_init: %s", error_msg(&_err));
// over-simplified connect
- if (sock_gnutls_connect(&sock, CONNECT_HOST, CONNECT_SERV, &_err))
+ if (sock_tcp_connect(&sock, CONNECT_HOST, CONNECT_SERV, &_err))
errx(1, "sock_gnutls_connect: %s", error_msg(&_err));
// line protocol
- if (line_proto_create(&lp, sock, LINE_LENGTH, NULL, NULL, &_err))
+ if (line_proto_create(&lp, sock, LINE_LENGTH, on_line, NULL, &_err))
errx(1, "line_proto_create: %s", error_msg(&_err));
- // read lines and dump them out
- do {
- // recv
- if (line_proto_read(lp, &line))
- errx(1, "line_proto_read: %s", error_msg(line_proto_error(lp)));
-
- // printf
- printf("<<< %s\n", line);
-
- } while (1);
+ // run event loop
+ if (event_base_dispatch(ev_base))
+ errx(1, "event_base_dispatch");
- // ok
+ // ok, no cleanup
return 0;
}
--- a/src/sock.c Sun Feb 22 10:16:28 2009 +0200
+++ b/src/sock.c Sat Feb 28 17:39:37 2009 +0200
@@ -35,7 +35,7 @@
// proxy off to method handler
if ((err = sock->type->methods.read(sock, buf, &len)))
- return err;
+ return -err;
// return updated bytes-read len
return len;
@@ -47,7 +47,7 @@
// proxy off to method handler
if ((err = sock->type->methods.write(sock, buf, &len)))
- return err;
+ return -err;
// return updated bytes-written len
return len;
--- a/src/sock_tcp.c Sun Feb 22 10:16:28 2009 +0200
+++ b/src/sock_tcp.c Sat Feb 28 17:39:37 2009 +0200
@@ -11,6 +11,21 @@
#include <assert.h>
/*
+ * Our basic socket event handler for driving our callbacks
+ */
+static void sock_tcp_event_handler (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);
+}
+
+/*
* Our sock_stream_methods.read method
*/
static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len)
@@ -51,14 +66,32 @@
static err_t sock_tcp_event_init (struct sock_stream *base_sock)
{
struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
+ err_t err;
+
+ // set nonblocking
+ if ((err = sock_tcp_set_nonblock(sock, 1)))
+ return err;
+
+ // add ourselves as the event handler
+ if ((err = sock_tcp_init_ev(sock, &sock_tcp_event_handler, sock)))
+ return err;
+ // done
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);
+
+ // 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;
}
@@ -72,21 +105,6 @@
.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
@@ -116,9 +134,15 @@
{
// require valid fd
assert(sock->fd >= 0);
+
+ // this is initialization
+ assert(sock->ev_read == NULL && sock->ev_write == NULL);
// create new event
- if ((sock->ev = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL)
+ if ((sock->ev_read = 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);
+
+ if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL)
return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
// ok
--- a/src/sock_tcp.h Sun Feb 22 10:16:28 2009 +0200
+++ b/src/sock_tcp.h Sat Feb 28 17:39:37 2009 +0200
@@ -16,8 +16,8 @@
/* The OS file descriptor */
int fd;
- /* The libevent struct */
- struct event *ev;
+ /* The IO events */
+ struct event *ev_read, *ev_write;
};
#define SOCK_TCP_BASE(sock_ptr) (&(sock_ptr)->base)
@@ -34,8 +34,7 @@
err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd);
/*
- * Initialize sock_tcp.ev to use the socket's fd with the given callback. By default, this is created with EV_READ
- * flags, but is not added.
+ * Initialize sock_tcp.ev_* to use the socket's fd with the given callback. The ev's are not activated yet.
*/
err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb) (evutil_socket_t, short, void *), void *arg);