unix: implement errnos

This commit is contained in:
Ryan Dahl 2011-04-25 17:26:07 -07:00
parent c1a04b6dfd
commit 0a7c19e19e
6 changed files with 66 additions and 23 deletions

View File

@ -24,6 +24,7 @@
#include <stdio.h> /* printf */
#include <stdlib.h>
#include <string.h> /* strerror */
#include <errno.h>
#include <assert.h>
#include <unistd.h>
@ -34,6 +35,9 @@
#include <arpa/inet.h>
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;
}

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* strlen */
static int completed_pingers = 0;
static int64_t start_time;

View File

@ -23,13 +23,13 @@
#include "runner.h"
#include <unistd.h>
#include <string.h> /* strdup */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
#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;
}

View File

@ -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);

View File

@ -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)

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* strlen */
static int completed_pingers = 0;