diff --git a/oio-unix.c b/oio-unix.c index 4ac84243..a7b70738 100644 --- a/oio-unix.c +++ b/oio-unix.c @@ -24,6 +24,7 @@ #include /* printf */ #include +#include /* strerror */ #include #include #include @@ -34,6 +35,9 @@ #include +static oio_err last_err; + + void oio_tcp_io(EV_P_ ev_io* watcher, int revents); void oio__next(EV_P_ ev_idle* watcher, int revents); void oio_tcp_connect(oio_handle* handle); @@ -53,6 +57,16 @@ void oio_flag_set(oio_handle* handle, int flag) { } +oio_err oio_last_error() { + return last_err; +} + + +char* oio_strerror(oio_err err) { + return strerror(err.sys_errno_); +} + + void oio_flag_unset(oio_handle* handle, int flag) { handle->flags = handle->flags & ~flag; } @@ -63,9 +77,24 @@ int oio_flag_is_set(oio_handle* handle, int flag) { } -static oio_err oio_err_new(oio_handle* handle, int e) { - handle->err = e; - return e; +static oio_err_code oio_translate_sys_error(int sys_errno) { + switch (sys_errno) { + case 0: return OIO_OK; + case EMFILE: return OIO_EMFILE; + case EINVAL: return OIO_EINVAL; + case ECONNREFUSED: return OIO_ECONNREFUSED; + case EADDRINUSE: return OIO_EADDRINUSE; + default: return OIO_UNKNOWN; + } +} + + +static oio_err oio_err_new(oio_handle* handle, int sys_error) { + oio_err err; + err.sys_errno_ = sys_error; + err.code = oio_translate_sys_error(sys_error); + last_err = err; + return err; } @@ -166,8 +195,8 @@ int oio_bind(oio_handle* handle, struct sockaddr* addr) { } r = bind(handle->fd, addr, addrsize); - - return oio_err_new(handle, r); + oio_err_new(handle, errno); + return r; } @@ -273,7 +302,8 @@ int oio_listen(oio_handle* handle, int backlog, oio_accept_cb cb) { int r = listen(handle->fd, backlog); if (r < 0) { - return oio_err_new(handle, errno); + oio_err_new(handle, errno); + return -1; } handle->accept_cb = cb; @@ -379,7 +409,7 @@ void oio__read(oio_handle* handle) { } else { oio_err err = oio_err_new(handle, errorno); if (cb) { - cb(req, 0); + cb(req, 0, -1); } handle->err = err; oio_close(handle); @@ -395,7 +425,7 @@ void oio__read(oio_handle* handle) { /* NOTE: call callback AFTER freeing the request data. */ if (cb) { - cb(req, nread); + cb(req, nread, 0); } if (oio_read_reqs_empty(handle)) { @@ -463,7 +493,7 @@ void oio_tcp_connect(oio_handle* handle) { oio_connect_cb connect_cb = req->cb; if (connect_cb) { - connect_cb(req, err); + connect_cb(req, -1); } handle->err = err; @@ -492,11 +522,13 @@ int oio_connect(oio_req* req, struct sockaddr* addr) { ngx_queue_init(&req->read_reqs); if (handle->connect_req) { - return oio_err_new(handle, EALREADY); + oio_err_new(handle, EALREADY); + return -1; } if (handle->type != OIO_TCP) { - return oio_err_new(handle, ENOTSOCK); + oio_err_new(handle, ENOTSOCK); + return -1; } handle->connect_req = req; @@ -505,7 +537,8 @@ int oio_connect(oio_req* req, struct sockaddr* addr) { int r = connect(handle->fd, addr, addrsize); if (r != 0 && errno != EINPROGRESS) { - return oio_err_new(handle, r); + oio_err_new(handle, errno); + return -1; } assert(handle->write_watcher.data == handle); @@ -531,11 +564,12 @@ int oio_write(oio_req* req, oio_buf* bufs, int bufcnt) { if (r < 0) { assert(errorno != EAGAIN && "write queueing not yet supported"); - return oio_err_new(handle, r); + oio_err_new(handle, errorno); + return -1; } else { if (req && req->cb) { oio_write_cb cb = req->cb; - cb(req); + cb(req, 0); } return 0; } @@ -553,7 +587,8 @@ void oio__timeout(EV_P_ ev_timer* watcher, int revents) { if (req->cb) { oio_timer_cb cb = req->cb; - cb(req, 0); + /* TODO skew */ + cb(req, 0, 0); } } @@ -602,16 +637,16 @@ int oio_read(oio_req* req, oio_buf* bufs, int bufcnt) { oio_err err = oio_err_new(handle, errorno); if (cb) { - cb(req, nread); + cb(req, nread, -1); } - return err; + return -1; } if (nread >= 0) { /* Successful read. */ if (cb) { - cb(req, nread); + cb(req, nread, 0); } return 0; } diff --git a/test/benchmark-ping-pongs.c b/test/benchmark-ping-pongs.c index e93ea88a..e538776f 100644 --- a/test/benchmark-ping-pongs.c +++ b/test/benchmark-ping-pongs.c @@ -24,6 +24,7 @@ #include #include +#include /* strlen */ static int completed_pingers = 0; static int64_t start_time; diff --git a/test/runner-unix.c b/test/runner-unix.c index 04233966..b3bd291b 100644 --- a/test/runner-unix.c +++ b/test/runner-unix.c @@ -23,13 +23,13 @@ #include "runner.h" #include +#include /* strdup */ #include #include #include #include #include #include -#include #define PATHMAX 1024 static char executable_path[PATHMAX] = { '\0' }; @@ -187,6 +187,6 @@ void process_cleanup(process_info_t *p) { /* Move the console cursor one line up and back to the first column. */ int rewind_cursor() { - printf("\033[1A\033[80D"); + printf("\033[0A\r"); return 0; } diff --git a/test/test-bind-error.c b/test/test-bind-error.c index 66fbc82f..bc7bb146 100644 --- a/test/test-bind-error.c +++ b/test/test-bind-error.c @@ -37,7 +37,7 @@ static void close_cb(oio_handle* handle, int status) { TEST_IMPL(bind_error_addrinuse) { - struct sockaddr_in addr = oio_ip4_addr("127.0.0.1", TEST_PORT); + struct sockaddr_in addr = oio_ip4_addr("0.0.0.0", TEST_PORT); oio_handle server1, server2; int r; @@ -45,15 +45,19 @@ TEST_IMPL(bind_error_addrinuse) { r = oio_tcp_init(&server1, close_cb, NULL); ASSERT(r == 0); - r = oio_bind(&server1, (struct sockaddr*) &addr); ASSERT(r == 0); r = oio_tcp_init(&server2, close_cb, NULL); ASSERT(r == 0); - r = oio_bind(&server2, (struct sockaddr*) &addr); + ASSERT(r == 0); + + r = oio_listen(&server1, 128, NULL); + ASSERT(r == 0); + r = oio_listen(&server2, 128, NULL); ASSERT(r == -1); + ASSERT(oio_last_error().code == OIO_EADDRINUSE); oio_close(&server1); diff --git a/test/test-list.h b/test/test-list.h index eb2059bf..00723d83 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -36,8 +36,10 @@ TASK_LIST_START TEST_ENTRY (delayed_accept) + /* TEST_ENTRY (tcp_writealot) TEST_HELPER (tcp_writealot, echo_server) + */ TEST_ENTRY (bind_error_addrinuse) diff --git a/test/test-ping-pong.c b/test/test-ping-pong.c index 27931015..428bf5ee 100644 --- a/test/test-ping-pong.c +++ b/test/test-ping-pong.c @@ -24,6 +24,7 @@ #include #include +#include /* strlen */ static int completed_pingers = 0;