diff options
Diffstat (limited to 'src/libmowgli/vio/vio.c')
-rw-r--r-- | src/libmowgli/vio/vio.c | 133 |
1 files changed, 115 insertions, 18 deletions
diff --git a/src/libmowgli/vio/vio.c b/src/libmowgli/vio/vio.c index ef4fb90..2570e22 100644 --- a/src/libmowgli/vio/vio.c +++ b/src/libmowgli/vio/vio.c @@ -36,11 +36,13 @@ static mowgli_heap_t *vio_heap = NULL; /* Change these to suit your needs for new VIO objects */ -mowgli_vio_ops_t mowgli_vio_default_ops = { +mowgli_vio_ops_t mowgli_vio_default_ops = +{ .socket = mowgli_vio_default_socket, .bind = mowgli_vio_default_bind, .listen = mowgli_vio_default_listen, .accept = mowgli_vio_default_accept, + .reuseaddr = mowgli_vio_default_reuseaddr, .connect = mowgli_vio_default_connect, .read = mowgli_vio_default_read, .write = mowgli_vio_default_write, @@ -52,7 +54,20 @@ mowgli_vio_ops_t mowgli_vio_default_ops = { .tell = mowgli_vio_default_tell, }; -mowgli_vio_t * mowgli_vio_create(void *userdata) +/* Null ops */ +mowgli_vio_evops_t mowgli_vio_default_evops = +{ + .read_cb = NULL, + .write_cb = NULL +}; + +/* mowgli_vio_create - create a VIO object on the heap + * + * inputs - userdata for the VIO object + * outputs - a VIO object + */ +mowgli_vio_t * +mowgli_vio_create(void *userdata) { mowgli_vio_t *vio; @@ -68,59 +83,138 @@ mowgli_vio_t * mowgli_vio_create(void *userdata) return vio; } -void mowgli_vio_init(mowgli_vio_t *vio, void *userdata) +/* mowgli_vio_init - initalise a VIO object previously allocated + * only use this if you know what you're doing, otherwise use mowgli_vio_create + * + * inputs - VIO object, userdata + * outputs - None + */ +void +mowgli_vio_init(mowgli_vio_t *vio, void *userdata) { - vio->fd = -1; + return_if_fail(vio); + + vio->io.fd = -1; vio->flags = 0; /* Default ops */ - vio->ops = mowgli_vio_default_ops; + vio->ops = &mowgli_vio_default_ops; vio->userdata = userdata; } -void mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop) +/* mowgli_vio_eventloop_attach - attach a VIO object to an eventloop + * + * inputs - VIO object, eventloop, ops to use for the eventloop (optional but recommended) + * outputs - None + */ +void +mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop, mowgli_vio_evops_t *evops) { - vio->io = mowgli_pollable_create(eventloop, vio->fd, vio->userdata); - if (vio->io != NULL) + return_if_fail(vio); + return_if_fail(eventloop); + + const int fd = vio->io.fd; + + /* Check for previous attachment */ + if (vio->eventloop) + { + mowgli_log("VIO object [%p] is already attached to eventloop [%p]; attempted to attach new eventloop [%p]", (void *) vio, (void *) vio->eventloop, (void *) eventloop); + return; + } + + if ((vio->io.e = mowgli_pollable_create(eventloop, fd, vio->userdata)) != NULL) { vio->eventloop = eventloop; + /* You're probably going to want this */ - mowgli_pollable_set_nonblocking(vio->io, true); + mowgli_pollable_set_nonblocking(vio->io.e, true); + + if (evops) + vio->evops = evops; + else + /* Default NULL ops */ + vio->evops = &mowgli_vio_default_evops; } else - mowgli_log("Unable to create pollable with VIO object [%p], expect problems.", vio); + { + mowgli_log("Unable to create pollable with VIO object [%p], expect problems.", (void *) vio); + vio->io.fd = fd;/* May have been clobbered */ + } } -void mowgli_vio_eventloop_detach(mowgli_vio_t *vio) +/* mowgli_vio_eventloop_detach - detach VIO object from eventloop + * + * inputs - VIO object + * output - None + */ +void +mowgli_vio_eventloop_detach(mowgli_vio_t *vio) { - return_if_fail(vio->io != NULL); + const int fd = mowgli_vio_getfd(vio); + + return_if_fail(fd != -1); + + return_if_fail(vio != NULL); + return_if_fail(vio->io.e != NULL); return_if_fail(vio->eventloop != NULL); - mowgli_pollable_destroy(vio->eventloop, vio->io); + mowgli_pollable_destroy(vio->eventloop, vio->io.e); + + vio->eventloop = NULL; + vio->io.fd = fd; } -void mowgli_vio_destroy(mowgli_vio_t *vio) +/* mowgli_vio_destroy - eliminate a VIO object + * + * inputs - VIO object + * output - None + */ +void +mowgli_vio_destroy(mowgli_vio_t *vio) { - mowgli_vio_eventloop_detach(vio); + return_if_fail(vio); + + if (vio->eventloop != NULL) + mowgli_vio_eventloop_detach(vio); + + if (!MOWGLI_VIO_IS_CLOSED(vio)) + mowgli_vio_close(vio); if (mowgli_vio_hasflag(vio, MOWGLI_VIO_FLAGS_ISONHEAP)) mowgli_heap_free(vio_heap, vio); } -int mowgli_vio_err_errcode(mowgli_vio_t *vio, char *(*int_to_error)(int), int errcode) +/* mowgli_vio_err_errcode - Signal an error using the specified char *foo(int err) callback + * Usually the callback can be strerror, but it can use anything else that fits the mould. + * + * inputs - VIO object, callback, error code. + * outputs - Error code from mowgli_vio_error function, any output to terminal/log files/etc. + */ +int +mowgli_vio_err_errcode(mowgli_vio_t *vio, char *(*int_to_error)(int), int errcode) { + return_val_if_fail(vio, -255); + vio->error.type = MOWGLI_VIO_ERR_ERRCODE; vio->error.code = errcode; mowgli_strlcpy(vio->error.string, int_to_error(errcode), sizeof(vio->error.string)); return mowgli_vio_error(vio); } +/* mowgli_vio_err_sslerrcode - Signal an SSL error + * + * inputs - VIO object, error code + * outputs - Error code from mowgli_vio_error function, any output to terminal/log files/etc. + */ #ifdef HAVE_OPENSSL -int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode) +int +mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, unsigned long int errcode) { + return_val_if_fail(vio, -255); + vio->error.type = MOWGLI_VIO_ERR_ERRCODE; vio->error.code = errcode; ERR_error_string_n(errcode, vio->error.string, sizeof(vio->error.string)); @@ -129,8 +223,11 @@ int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode) #else -int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode) +int +mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, unsigned long int errcode) { + return_if_fail(vio); + vio->error.type = MOWGLI_VIO_ERR_ERRCODE; vio->error.code = errcode; mowgli_strlcpy(vio->error.string, "Unknown SSL error", sizeof(vio->error.string)); |