summaryrefslogtreecommitdiff
path: root/src/libmowgli/vio/vio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmowgli/vio/vio.c')
-rw-r--r--src/libmowgli/vio/vio.c133
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));