diff options
author | Andrew Shadura <andrew@shadura.me> | 2014-01-28 15:21:50 +0100 |
---|---|---|
committer | Andrew Shadura <andrew@shadura.me> | 2014-01-28 15:21:50 +0100 |
commit | 51addbcf27d7b06dae80a0e39e5f5f83e94dd8ae (patch) | |
tree | 3d00bef2d26f97257ec6f4835505cd300054a1e3 /src/examples | |
parent | 1ed00f1a2893b43195f3fc747988da0bf6006797 (diff) |
Update to libmowgli 2.0.0
Diffstat (limited to 'src/examples')
30 files changed, 1169 insertions, 100 deletions
diff --git a/src/examples/Makefile b/src/examples/Makefile index d56d9ad..8512305 100644 --- a/src/examples/Makefile +++ b/src/examples/Makefile @@ -1,3 +1,3 @@ -SUBDIRS = randomtest listsort formattertest dicttest patriciatest patriciatest2 +SUBDIRS = echoserver vio-udplistener async_resolver formattertest helpertest libevent-bench linetest listsort memslice-bench patriciatest patriciatest2 randomtest timertest futuretest include ../../buildsys.mk diff --git a/src/examples/async_resolver/Makefile b/src/examples/async_resolver/Makefile new file mode 100644 index 0000000..2c664bc --- /dev/null +++ b/src/examples/async_resolver/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = async_resolver${PROG_SUFFIX} +SRCS = async_resolver.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/async_resolver/async_resolver.c b/src/examples/async_resolver/async_resolver.c new file mode 100644 index 0000000..1a05236 --- /dev/null +++ b/src/examples/async_resolver/async_resolver.c @@ -0,0 +1,151 @@ +/* This code is in the public domain. */ + +#include <mowgli.h> + +typedef struct +{ + char *domain; + mowgli_dns_query_t query; +} dns_query; + +static void resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr) +{ + char buf[2048]; + dns_query *dnsquery = vptr; + const void *sockptr; + + if (reply == NULL) + { + printf("Got null reply for %s\n", dnsquery->domain); + switch (reason) + { + case MOWGLI_DNS_RES_NXDOMAIN: + printf("Nonexistent domain\n"); + break; + case MOWGLI_DNS_RES_INVALID: + printf("Invalid domain\n"); + break; + case MOWGLI_DNS_RES_TIMEOUT: + printf("Timed out\n"); + break; + } + goto end; + } + + printf("Finished %s\n", dnsquery->domain); + printf("Hostname: %s\n", reply->h_name); + + if (reply->addr.addr.ss_family == AF_INET) + { + const struct sockaddr_in *saddr = (const struct sockaddr_in *)&reply->addr.addr; + sockptr = &saddr->sin_addr; + } + else if (reply->addr.addr.ss_family == AF_INET6) + { + const struct sockaddr_in6 *saddr = (const struct sockaddr_in6 *)&reply->addr.addr; + sockptr = &saddr->sin6_addr; + } + else + { + printf("Invalid Address family %d\n", reply->addr.addr.ss_family); + return; + } + + inet_ntop(reply->addr.addr.ss_family, sockptr, buf, sizeof(buf)); + printf("Resolved: %s\n", buf); + +end: + mowgli_free(dnsquery->domain); + mowgli_free(vptr); +} + +static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); + mowgli_dns_t *dns = userdata; + char buf[2048]; + char *ch; + int ret; + + return_if_fail(pollable->fd == STDIN_FILENO); + + if ((ret = read(pollable->fd, buf, sizeof(buf))) < 0) + { + perror("read"); + mowgli_pollable_destroy(eventloop, io); + return; + } + else if (ret == 0) + return; + + buf[--ret] = '\0'; + + ch = strtok(buf, " "); + while (ch != NULL) + { + dns_query *dnsquery = mowgli_alloc(sizeof(dns_query)); + mowgli_dns_query_t *query = &dnsquery->query; + + printf("Domain input: %s\n", ch); + printf("End domain input\n"); + + query->callback = resolve_cb; + query->ptr = dnsquery; + dnsquery->domain = mowgli_strdup(ch); + + if (*ch == '+') + { + int type; + void *addrptr; + struct sockaddr_storage addr; + + if(strchr(++ch, ':') != NULL) + { + struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr; + type = AF_INET6; + addrptr = &saddr->sin6_addr; + } + else + { + struct sockaddr_in *saddr = (struct sockaddr_in *)&addr; + type = AF_INET; + addrptr = &saddr->sin_addr; + } + + addr.ss_family = type; + + if ((ret = inet_pton(type, ch, addrptr)) != 1) + { + if (ret == -1) + perror("inet_pton"); + else + printf("Invalid address %s\n", ch); + + return; + } + + mowgli_dns_gethost_byaddr(dns, &addr, query); + } + else + mowgli_dns_gethost_byname(dns, ch, query, MOWGLI_DNS_T_A); + + dnsquery->domain = mowgli_strdup(ch); + ch = strtok(NULL, " "); + } +} + +int main (void) +{ + mowgli_eventloop_t *evloop = mowgli_eventloop_create(); + mowgli_dns_t *dns = mowgli_dns_create(evloop, MOWGLI_DNS_TYPE_ASYNC); + mowgli_eventloop_pollable_t *stdin_pollable = mowgli_pollable_create(evloop, STDIN_FILENO, dns); + mowgli_pollable_set_nonblocking(stdin_pollable, true); + + mowgli_pollable_setselect(evloop, stdin_pollable, MOWGLI_EVENTLOOP_IO_READ, read_data); + + mowgli_eventloop_run(evloop); + + mowgli_eventloop_destroy(evloop); + + return 0; +} diff --git a/src/examples/dicttest/Makefile b/src/examples/dicttest/Makefile deleted file mode 100644 index f018538..0000000 --- a/src/examples/dicttest/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -PROG_NOINST = dicttest${PROG_SUFFIX} -SRCS = dicttest.c - -include ../../../buildsys.mk - -CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli diff --git a/src/examples/dicttest/dicttest.c b/src/examples/dicttest/dicttest.c deleted file mode 100644 index c5eaec5..0000000 --- a/src/examples/dicttest/dicttest.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * libmowgli: A collection of useful routines for programming. - * dicttest.c: Testing of the mowgli.dictionary engine. - * - * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <mowgli.h> - -#ifdef _WIN32 -#define strcasecmp _stricmp -#define snprintf _snprintf -#endif - -int main(int argc, const char *argv[]) -{ - mowgli_dictionary_t *test_dict; - mowgli_random_t *r; - char key[10]; - long ans[100], i; - int pass = 0, fail = 0; - - mowgli_init(); - - test_dict = mowgli_dictionary_create(strcasecmp); - r = mowgli_random_create(); - - for (i = 0; i < 100; i++) - { - ans[i] = mowgli_random_int(r); - snprintf(key, 10, "%ldkey%ld", i, i); - mowgli_dictionary_add(test_dict, key, (void *) ans[i]); - } - - for (i = 0; i < 100; i++) - { - snprintf(key, 10, "%ldkey%ld", i, i); - - if ( (long) mowgli_dictionary_retrieve(test_dict, key) != ans[i]) - { - printf("FAIL %ld %p[%p]\n", i, mowgli_dictionary_retrieve(test_dict, key), (void*) ans[i]); - fail++; - } - else - { - printf("PASS %ld %p[%p]\n", i, mowgli_dictionary_retrieve(test_dict, key), (void*) ans[i]); - pass++; - } - } - - printf("%d tests failed, %d tests passed.\n", fail, pass); - return 0; -} diff --git a/src/examples/echoserver/Makefile b/src/examples/echoserver/Makefile new file mode 100644 index 0000000..c0fa0f2 --- /dev/null +++ b/src/examples/echoserver/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = echoserver${PROG_SUFFIX} +SRCS = echoserver.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/echoserver/echoserver.c b/src/examples/echoserver/echoserver.c new file mode 100644 index 0000000..dd1fc05 --- /dev/null +++ b/src/examples/echoserver/echoserver.c @@ -0,0 +1,139 @@ +/* + * libmowgli: A collection of useful routines for programming. + * echoserver.c: Testing of the I/O system + * + * Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <mowgli.h> + +mowgli_eventloop_t *base_eventloop; +mowgli_eventloop_pollable_t *listener; + +typedef struct { + mowgli_eventloop_io_t *io; + char buf[1024]; +} client_t; + +#ifdef DEBUG +static void timer_tick(void *unused) +{ + static int ticks = 0; + + printf("tick: %d\n", ++ticks); +} +#endif + +static int setup_listener(void) +{ + struct sockaddr_in in = {}; + int fd = socket(AF_INET, SOCK_STREAM, 0); + + in.sin_family = AF_INET; + in.sin_port = htons(1337); + + if (bind(fd, (struct sockaddr *) &in, sizeof(struct sockaddr_in)) < 0) + { + in.sin_port = htons(31337); + bind(fd, (struct sockaddr *) &in, sizeof(struct sockaddr_in)); + } + + listen(fd, 5); + + return fd; +} + +static void write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); + client_t *client = userdata; + + if (*client->buf) + send(pollable->fd, client->buf, strlen(client->buf), 0); + + memset(client->buf, '\0', sizeof(client->buf)); + + mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_WRITE, NULL); +} + +static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); + int ret; + + client_t *client = userdata; + + if ((ret = recv(pollable->fd, client->buf, sizeof(client->buf), 0)) <= 0) + { + mowgli_free(client); + mowgli_pollable_destroy(eventloop, io); + + return; + } + + mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_WRITE, write_data); +} + +static void client_error(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + mowgli_free(userdata); + mowgli_pollable_destroy(eventloop, io); +} + +static void accept_client(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); + client_t *client; + mowgli_descriptor_t new_fd, listener_fd; + + listener_fd = pollable->fd; + + new_fd = accept(listener_fd, NULL, NULL); + + client = mowgli_alloc(sizeof(client_t)); + + client->io = mowgli_pollable_create(eventloop, new_fd, client); + mowgli_pollable_set_nonblocking(client->io, true); + + mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_READ, read_data); + mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_ERROR, client_error); +} + +int main(int argc, char *argv[]) +{ + int fd; + + base_eventloop = mowgli_eventloop_create(); + +#ifdef DEBUG + mowgli_timer_add(base_eventloop, "timer_tick", timer_tick, NULL, 1); +#endif + + fd = setup_listener(); + + listener = mowgli_pollable_create(base_eventloop, fd, NULL); + mowgli_pollable_set_nonblocking(listener, true); + mowgli_pollable_setselect(base_eventloop, listener, MOWGLI_EVENTLOOP_IO_READ, accept_client); + + mowgli_eventloop_run(base_eventloop); + + mowgli_eventloop_destroy(base_eventloop); + + return EXIT_SUCCESS; +} diff --git a/src/examples/formattertest/Makefile b/src/examples/formattertest/Makefile index 23c4517..63cf463 100644 --- a/src/examples/formattertest/Makefile +++ b/src/examples/formattertest/Makefile @@ -4,4 +4,4 @@ SRCS = formattertest.c include ../../../buildsys.mk CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/formattertest/formattertest.c b/src/examples/formattertest/formattertest.c index 26a6e4b..9ec014c 100644 --- a/src/examples/formattertest/formattertest.c +++ b/src/examples/formattertest/formattertest.c @@ -36,7 +36,6 @@ int main(int argc, char *argv[]) { char buf[65535]; - mowgli_init(); mowgli_formatter_format(buf, 65535, "%1! %2 %3 %4.", "sdpb", "Hello World", 1, 0xDEADBEEF, TRUE); diff --git a/src/examples/futuretest/Makefile b/src/examples/futuretest/Makefile new file mode 100644 index 0000000..3be7e23 --- /dev/null +++ b/src/examples/futuretest/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = futuretest${PROG_SUFFIX} +SRCS = futuretest.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/futuretest/futuretest.c b/src/examples/futuretest/futuretest.c new file mode 100644 index 0000000..e426733 --- /dev/null +++ b/src/examples/futuretest/futuretest.c @@ -0,0 +1,89 @@ +/* + * libmowgli: A collection of useful routines for programming. + * futuretest: Combustable lemons + * + * Copyright (c) 2012 Patrick McFarland <pmcfarland@adterrasperaspera.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> + +#include <mowgli.h> + +int main(int argc, char *argv[]) { + char *text = "hello world"; + + printf("create future: "); + mowgli_future_t *future = mowgli_future_create(); + if(future != NULL) + printf("correctly created future\n"); + else + printf("error: abandon all hope\n"); + + printf("get state manually of waiting future: "); + if(mowgli_future_state(future) == MOWGLI_FUTURE_STATE_WAITING) + printf("correctly waiting\n"); + else + printf("error: %i\n", mowgli_future_state(future)); + + printf("finish future: "); + if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_FINISHED) + printf("correctly finished\n"); + else + printf("error: %i\n", mowgli_future_state(future)); + + printf("get result of finished future: "); + if(mowgli_future_result(future) == text) + printf("correct: %s\n", text); + else + printf("error: %s\n", (char *)mowgli_future_result(future)); + + printf("get state of finished future: "); + if(mowgli_future_state(future) == MOWGLI_FUTURE_STATE_FINISHED) + printf("correctly finished\n"); + else + printf("error: %i\n", mowgli_future_state(future)); + + printf("reinit then cancel: "); + if(mowgli_future_init(future) == 0) { + if(mowgli_future_cancel(future) == MOWGLI_FUTURE_STATE_CANCELED) + printf("correctly canceled\n"); + else + printf("error: failed to cancel: %i\n", mowgli_future_state(future)); + + printf("try to finish on canceled future: "); + if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_CANCELED) + printf("correctly caught cancel\n"); + else + printf("error: failed to cancel: %s\n", text); + } else { + printf("error: failed to reinit\n"); + } + + printf("reinit then finish twice: "); + if(mowgli_future_init(future) == 0) { + mowgli_future_finish(future, text); + + if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_CONSISTENCY_FAILURE) + printf("correctly raised consistency failure\n"); + else + printf("error: finished twice: %s\n", text); + } else { + printf("error: failed to reinit\n"); + } +} diff --git a/src/examples/helpertest/Makefile b/src/examples/helpertest/Makefile new file mode 100644 index 0000000..2a37715 --- /dev/null +++ b/src/examples/helpertest/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = helpertest${PROG_SUFFIX} +SRCS = helpertest.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/helpertest/helpertest.c b/src/examples/helpertest/helpertest.c new file mode 100644 index 0000000..9106000 --- /dev/null +++ b/src/examples/helpertest/helpertest.c @@ -0,0 +1,109 @@ +/* + * libmowgli: A collection of useful routines for programming. + * echoserver.c: Testing of the I/O system + * + * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <mowgli.h> + +int helper_count = 0; + +void timer_oneshot(mowgli_eventloop_helper_proc_t *helper) +{ + mowgli_writef(helper->out_fd, "oneshot timer hit\n"); +} + +void timer_tick(mowgli_eventloop_helper_proc_t *helper) +{ + static int ticks = 0; + + mowgli_writef(helper->out_fd, "tick: %d\n", ++ticks); + + if (ticks > 10) + mowgli_eventloop_break(helper->eventloop); +} + +void helper_start(mowgli_eventloop_helper_proc_t *helper, void *userdata) +{ + mowgli_eventloop_t *eventloop = helper->eventloop; + + mowgli_writef(helper->out_fd, "hi from pid %d\n", getpid()); + + mowgli_timer_add(eventloop, "timer_tick", (mowgli_event_dispatch_func_t *) timer_tick, helper, 1); + mowgli_timer_add_once(eventloop, "timer_oneshot", (mowgli_event_dispatch_func_t *) timer_oneshot, helper, 5); + + mowgli_eventloop_run(eventloop); + + mowgli_writef(helper->out_fd, "eventloop halted\n"); + + mowgli_eventloop_destroy(eventloop); +} + +void helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata); + +void helper_spawn(mowgli_eventloop_t *eventloop) +{ + mowgli_eventloop_helper_proc_t *helper; + + if (helper_count >= 100) + return; + + helper = mowgli_helper_create(eventloop, helper_start, "Spawned helper", NULL); + mowgli_helper_set_read_cb(eventloop, helper, helper_read); + + helper_count++; +} + +void helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) +{ + size_t r; + char buf[16384]; + mowgli_eventloop_helper_proc_t *helper = mowgli_eventloop_io_helper(io); + + bzero(buf, sizeof buf); + r = read(helper->in_fd, buf, sizeof buf); + + if (r > 0) + printf("helper %p [%d/%d]: %s", helper, helper->child->pid, helper->in_fd, buf); + else if (r <= 0) + { + helper_count--; + mowgli_helper_destroy(eventloop, helper); + } + + if ((rand() % helper_count) == 0) + helper_spawn(eventloop); +} + +int main(int argc, char *argv[]) +{ + mowgli_eventloop_t *base_eventloop; + + /* Bleh this is needed to ensure some systems can set the process title */ + argv = mowgli_proctitle_init(argc, argv); + + base_eventloop = mowgli_eventloop_create(); + + helper_spawn(base_eventloop); + + mowgli_eventloop_run(base_eventloop); + + return EXIT_SUCCESS; +} diff --git a/src/examples/libevent-bench/Makefile b/src/examples/libevent-bench/Makefile new file mode 100644 index 0000000..c420102 --- /dev/null +++ b/src/examples/libevent-bench/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = bench${PROG_SUFFIX} +SRCS = bench.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/libevent-bench/bench.c b/src/examples/libevent-bench/bench.c new file mode 100644 index 0000000..0e2cb08 --- /dev/null +++ b/src/examples/libevent-bench/bench.c @@ -0,0 +1,230 @@ +/* + * Copyright 2012 William Pitcock <nenolod@dereferenced.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright 2003 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org> + * + * Added chain event propagation to improve the sensitivity of + * the measure respect to the event loop efficency. + * + * + */ + +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) + +#include <mowgli.h> + + +static int count, writes, fired; +static mowgli_eventloop_t *base_eventloop; +static mowgli_descriptor_t *pipes; +static int num_pipes, num_active, num_writes; +static mowgli_eventloop_pollable_t **events; +static int timers; + +void +timer_cb(void *unused) +{ + /* nop */ +} + +void +read_cb(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *arg) +{ + mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io); + int idx = (int) (long) arg, widx = idx + 1; + u_char ch; + + count += read(pollable->fd, &ch, sizeof(ch)); + if (writes) { + if (widx >= num_pipes) + widx -= num_pipes; + write(pipes[2 * widx + 1], "e", 1); + writes--; + fired++; + } +} + +#if NATIVE +void +read_thunk(struct ev_io *w, int revents) +{ + read_cb (w->fd, revents, w->data); +} + +void +timer_cb (struct ev_timer *w, int revents) +{ + /* nop */ +} +#endif + +struct timeval * +run_once(void) +{ + int *cp, i, space; + static struct timeval ta, ts, te; + + gettimeofday(&ta, NULL); + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { + if (events[i] != NULL) + mowgli_pollable_destroy(base_eventloop, events[i]); + + events[i] = mowgli_pollable_create(base_eventloop, cp[0], (void *) (long) i); + mowgli_pollable_setselect(base_eventloop, events[i], MOWGLI_EVENTLOOP_IO_READ, read_cb); + } + + fired = 0; + space = num_pipes / num_active; + space = space * 2; + for (i = 0; i < num_active; i++, fired++) + write(pipes[i * space + 1], "e", 1); + + count = 0; + writes = num_writes; + + int xcount = 0; + gettimeofday(&ts, NULL); + do { + mowgli_eventloop_run_once(base_eventloop); + xcount++; + } while (count != fired); + + gettimeofday(&te, NULL); + + timersub(&te, &ta, &ta); + timersub(&te, &ts, &ts); + fprintf(stdout, "%ld\t%ld\n", + ta.tv_sec * 1000000L + ta.tv_usec, + ts.tv_sec * 1000000L + ts.tv_usec + ); + + return (&te); +} + +int +main (int argc, char **argv) +{ + struct rlimit rl; + int i, c; + int *cp; + extern char *optarg; + + num_pipes = 100; + num_active = 1; + num_writes = num_pipes; + while ((c = getopt(argc, argv, "n:a:w:te")) != -1) { + switch (c) { + case 'n': + num_pipes = atoi(optarg); + break; + case 'a': + num_active = atoi(optarg); + break; + case 'w': + num_writes = atoi(optarg); + break; + case 't': + timers = 1; + break; + default: + fprintf(stderr, "Illegal argument \"%c\"\n", c); + exit(1); + } + } + +#if 1 + rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; + if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { + perror("setrlimit"); + } +#endif + + events = calloc(num_pipes * 2, sizeof(mowgli_eventloop_pollable_t *)); + pipes = calloc(num_pipes * 2, sizeof(mowgli_descriptor_t)); + if (events == NULL || pipes == NULL) { + perror("malloc"); + exit(1); + } + + mowgli_thread_set_policy(MOWGLI_THREAD_POLICY_DISABLED); + base_eventloop = mowgli_eventloop_create(); + + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { +#ifdef USE_PIPES + if (pipe(cp) == -1) { +#else + if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { +#endif + perror("pipe"); + exit(1); + } + } + + for (i = 0; i < 2; i++) { + run_once(); + } + + exit(0); +} diff --git a/src/examples/linetest/Makefile b/src/examples/linetest/Makefile new file mode 100644 index 0000000..cb9b030 --- /dev/null +++ b/src/examples/linetest/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = linetest${PROG_SUFFIX} +SRCS = linetest.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/linetest/linetest.c b/src/examples/linetest/linetest.c new file mode 100644 index 0000000..98b8064 --- /dev/null +++ b/src/examples/linetest/linetest.c @@ -0,0 +1,162 @@ +/* + * libmowgli: A collection of useful routines for programming. + * linetest.c: Testing of the linebuffer + * + * Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org> + * Copyright (c) 2012 Elizabeth J. Myers <elizabeth@sporksmoo.net> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <mowgli.h> + +mowgli_eventloop_t *base_eventloop; +char buf[512]; + +typedef struct { + mowgli_linebuf_t *linebuf; +} client_t; + +void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata); + +void write_line(mowgli_linebuf_t *linebuf, char *buf, size_t len) +{ + printf("> %s\n", buf); + mowgli_linebuf_write(linebuf, buf, len); +} + +client_t * create_client(const char *server, const char *port, const char *nick, const char *user, const char *realname) +{ + client_t *client; + struct addrinfo hints, *res; + bool use_ssl = false; + mowgli_vio_sockaddr_t addr; + int ret; + + mowgli_linebuf_t *linebuf; + + if (*port == '+') + { + port++; + use_ssl = true; + } + + client = mowgli_alloc(sizeof(client_t)); + + linebuf = mowgli_linebuf_create(eat_line, client); + client->linebuf = linebuf; + + /* Do name res */ + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((ret = getaddrinfo(server, port, &hints, &res)) != 0) + { + linebuf->vio->error.op = MOWGLI_VIO_ERR_OP_OTHER; + linebuf->vio->error.type = MOWGLI_VIO_ERR_ERRCODE; + linebuf->vio->error.code = ret; + mowgli_strlcpy(linebuf->vio->error.string, gai_strerror(ret), sizeof(linebuf->vio->error.string)); + mowgli_vio_error(linebuf->vio); + return NULL; + } + + /* Wrap the VIO object */ + if (use_ssl) + { + if (mowgli_vio_openssl_setssl(linebuf->vio, NULL) != 0) + return NULL; + } + + /* We have to have a socket before starting the linebuf */ + if (mowgli_vio_socket(linebuf->vio, res->ai_family, res->ai_socktype, res->ai_protocol) != 0) + return NULL; + + /* Attach the linebuf */ + mowgli_linebuf_attach_to_eventloop(linebuf, base_eventloop); + + /* Do the connect */ + if (mowgli_vio_connect(linebuf->vio, mowgli_vio_sockaddr_from_struct(&addr, res->ai_addr, res->ai_addrlen)) != 0) + return NULL; + + /* Write IRC handshake */ + snprintf(buf, 512, "USER %s * 8 :%s", user, realname); + write_line(client->linebuf, buf, strlen(buf)); + + snprintf(buf, 512, "NICK %s", nick); + write_line(client->linebuf, buf, strlen(buf)); + + return client; +} + +void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata) +{ + char str[512]; + + /* Avoid malicious lines -- servers shouldn't send them */ + if (linebuf->flags & MOWGLI_LINEBUF_LINE_HASNULLCHAR) + return; + + strncpy(str, line, sizeof(str)); + str[len + 1] = '\0'; + + printf("-> %s\n", str); + + /* Since this is just a basic example, we don't have a real dispatcher :p */ + if (strstr(str, "PING")) + { + char *pos = strpbrk(str, ":"); + if (pos) + { + char buf[512]; + snprintf(buf, 512, "PONG %s", pos); + mowgli_linebuf_write(linebuf, buf, strlen(buf)); + } + } + + return; +} + +int main(int argc, const char *argv[]) +{ + client_t *client; + const char *serv, *port; + + if (argc < 3) + { + fprintf(stderr, "Not enough arguments\n"); + fprintf(stderr, "Usage: %s [server] [(+)port]\n", argv[0]); + fprintf(stderr, "For SSL, put a + in front of port\n"); + return EXIT_FAILURE; + } + + base_eventloop = mowgli_eventloop_create(); + + serv = argv[1]; + port = argv[2]; + + client = create_client(serv, port, "Mowglibot", "Mowglibot", "The libmowgli example bot that does nothing useful"); + if (client == NULL) + return EXIT_FAILURE; + + mowgli_eventloop_run(base_eventloop); + + mowgli_free(client); + mowgli_eventloop_destroy(base_eventloop); + + return EXIT_SUCCESS; +} diff --git a/src/examples/listsort/Makefile b/src/examples/listsort/Makefile index 2517a77..b3e59b4 100644 --- a/src/examples/listsort/Makefile +++ b/src/examples/listsort/Makefile @@ -4,4 +4,4 @@ SRCS = listsort.c include ../../../buildsys.mk CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/listsort/listsort.c b/src/examples/listsort/listsort.c index 43b9745..7aa44c2 100644 --- a/src/examples/listsort/listsort.c +++ b/src/examples/listsort/listsort.c @@ -109,9 +109,7 @@ void test_integers(void) int main(int argc, char *argv[]) { - mowgli_init(); - test_strings(); test_integers(); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/src/examples/memslice-bench/Makefile b/src/examples/memslice-bench/Makefile new file mode 100644 index 0000000..8648d93 --- /dev/null +++ b/src/examples/memslice-bench/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = memslice-bench${PROG_SUFFIX} +SRCS = memslice-bench.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/memslice-bench/memslice-bench.c b/src/examples/memslice-bench/memslice-bench.c new file mode 100644 index 0000000..3fb05d5 --- /dev/null +++ b/src/examples/memslice-bench/memslice-bench.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) + +#include <mowgli.h> + +mowgli_allocation_policy_t *memslice; +mowgli_allocation_policy_t *sysmalloc; + +int +main(int argc, char *argv[]) +{ + size_t i; + size_t objects; + size_t *obj_sizes; + void **ptrs; + struct timeval ts, te; + + mowgli_thread_set_policy(MOWGLI_THREAD_POLICY_DISABLED); + + objects = 128000; + ptrs = mowgli_alloc_array(sizeof(void *), objects); + obj_sizes = mowgli_alloc_array(sizeof(size_t), objects); + + memslice = mowgli_allocation_policy_lookup("memslice"); + sysmalloc = mowgli_allocation_policy_lookup("malloc"); + + if (sysmalloc == NULL) + { + printf("Couldn't find a sysmalloc component which implements contract 'mowgli.core.allocation_policy' :(\n"); + return EXIT_FAILURE; + } + + if (memslice == NULL) + { + printf("Couldn't find a memslice component which implements contract 'mowgli.core.allocation_policy' :(\n"); + return EXIT_FAILURE; + } + + printf("Going to allocate %zu objects of random sizes < 256\n", objects); + + printf("Assigning sizes...\n"); + for (i = 0; i < objects; i++) { + obj_sizes[i] = rand() % 256; + } + printf("Done! Lets benchmark.\n"); + + /* allocate using sysmalloc */ + gettimeofday(&ts, NULL); + for (i = 0; i < objects; i++) { + ptrs[i] = mowgli_alloc_using_policy(sysmalloc, obj_sizes[i]); + } + gettimeofday(&te, NULL); + timersub(&te, &ts, &ts); + + printf("sysmalloc alloc time: %ld usec\n", + ts.tv_sec * 1000000L + ts.tv_usec); + + gettimeofday(&ts, NULL); + for (i = 0; i < objects; i++) { + mowgli_free(ptrs[i]); + } + gettimeofday(&te, NULL); + timersub(&te, &ts, &ts); + + printf("sysmalloc free time: %ld usec\n", + ts.tv_sec * 1000000L + ts.tv_usec); + + /* allocate using memslice */ + gettimeofday(&ts, NULL); + for (i = 0; i < objects; i++) { + ptrs[i] = mowgli_alloc_using_policy(memslice, obj_sizes[i]); + } + gettimeofday(&te, NULL); + timersub(&te, &ts, &ts); + + printf("memslice alloc time: %ld usec\n", + ts.tv_sec * 1000000L + ts.tv_usec); + + gettimeofday(&ts, NULL); + for (i = 0; i < objects; i++) { + mowgli_free(ptrs[i]); + } + gettimeofday(&te, NULL); + timersub(&te, &ts, &ts); + + printf("memslice free time: %ld usec\n", + ts.tv_sec * 1000000L + ts.tv_usec); + + return EXIT_SUCCESS; +} diff --git a/src/examples/patriciatest/Makefile b/src/examples/patriciatest/Makefile index 6669293..5c454e2 100644 --- a/src/examples/patriciatest/Makefile +++ b/src/examples/patriciatest/Makefile @@ -4,4 +4,4 @@ SRCS = patriciatest.c include ../../../buildsys.mk CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/patriciatest/patriciatest.c b/src/examples/patriciatest/patriciatest.c index bf5f641..98c5f65 100644 --- a/src/examples/patriciatest/patriciatest.c +++ b/src/examples/patriciatest/patriciatest.c @@ -149,8 +149,6 @@ void test_patricia(void) int main(int argc, char *argv[]) { - mowgli_init(); - test_patricia(); return errors == 0 ? 0 : 1; diff --git a/src/examples/patriciatest2/Makefile b/src/examples/patriciatest2/Makefile index cb7ce12..de50339 100644 --- a/src/examples/patriciatest2/Makefile +++ b/src/examples/patriciatest2/Makefile @@ -4,4 +4,4 @@ SRCS = patriciatest2.c include ../../../buildsys.mk CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/patriciatest2/patriciatest2.c b/src/examples/patriciatest2/patriciatest2.c index de70ac2..d73b1ee 100644 --- a/src/examples/patriciatest2/patriciatest2.c +++ b/src/examples/patriciatest2/patriciatest2.c @@ -145,8 +145,6 @@ void test_patricia(void) int main(int argc, char *argv[]) { - mowgli_init(); - test_patricia(); return errors == 0 ? 0 : 1; diff --git a/src/examples/randomtest/Makefile b/src/examples/randomtest/Makefile index b64193e..9b49184 100644 --- a/src/examples/randomtest/Makefile +++ b/src/examples/randomtest/Makefile @@ -4,4 +4,4 @@ SRCS = randomtest.c include ../../../buildsys.mk CPPFLAGS += -I../../libmowgli -LIBS += -L../../libmowgli -lmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/timertest/Makefile b/src/examples/timertest/Makefile new file mode 100644 index 0000000..968f2d1 --- /dev/null +++ b/src/examples/timertest/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = timertest${PROG_SUFFIX} +SRCS = timertest.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/timertest/timertest.c b/src/examples/timertest/timertest.c new file mode 100644 index 0000000..242b8a9 --- /dev/null +++ b/src/examples/timertest/timertest.c @@ -0,0 +1,57 @@ +/* + * libmowgli: A collection of useful routines for programming. + * echoserver.c: Testing of the I/O system + * + * Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <mowgli.h> + +mowgli_eventloop_t *eventloop; + +void timer_oneshot(void *unused) +{ + printf("oneshot timer hit\n"); +} + +void timer_tick(void *unused) +{ + static int ticks = 0; + + printf("tick: %d\n", ++ticks); + + if (ticks > 20) + mowgli_eventloop_break(eventloop); +} + +int main(int argc, char *argv[]) +{ + eventloop = mowgli_eventloop_create(); + + mowgli_timer_add(eventloop, "timer_tick", timer_tick, NULL, 1); + mowgli_timer_add_once(eventloop, "timer_oneshot", timer_oneshot, NULL, 5); + + mowgli_eventloop_run(eventloop); + + printf("eventloop halted\n"); + + mowgli_eventloop_destroy(eventloop); + + return EXIT_SUCCESS; +} diff --git a/src/examples/vio-udplistener/Makefile b/src/examples/vio-udplistener/Makefile new file mode 100644 index 0000000..1be3936 --- /dev/null +++ b/src/examples/vio-udplistener/Makefile @@ -0,0 +1,7 @@ +PROG_NOINST = vio-udplistener${PROG_SUFFIX} +SRCS = vio-udplistener.c + +include ../../../buildsys.mk + +CPPFLAGS += -I../../libmowgli +LIBS += -L../../libmowgli -lmowgli-2 diff --git a/src/examples/vio-udplistener/vio-udplistener.c b/src/examples/vio-udplistener/vio-udplistener.c new file mode 100644 index 0000000..9de4e69 --- /dev/null +++ b/src/examples/vio-udplistener/vio-udplistener.c @@ -0,0 +1,45 @@ +/* vio-udplistener.c - An example of the VIO API + * To use: nc -u localhost, and then type stuff and hit enter. :p + * This example is public domain. + */ + +#include <mowgli.h> + +#define BUFSIZE 2048 + +#define PROTO AF_INET6 +#define LISTEN "::ffff:127.0.0.1" /* 6to4 mapping */ +#define PORT 31337 + +#define ECHOBACK "Echo: " + +int main (void) +{ + mowgli_vio_t *vio = mowgli_vio_create(NULL); + mowgli_vio_sockaddr_t addr; + + mowgli_vio_sockaddr_create(&addr, PROTO, LISTEN, 31337); + + if (mowgli_vio_socket(vio, PROTO, SOCK_DGRAM, 0)) + return EXIT_FAILURE; + + if (mowgli_vio_bind(vio, &addr)) + return EXIT_FAILURE; + + while (true) + { + char buf[BUFSIZE] = ""; + mowgli_vio_sockdata_t sockinfo; + + mowgli_vio_recvfrom(vio, buf, sizeof(buf), &addr); + + mowgli_vio_sockaddr_info(&addr, &sockinfo); + + printf("Recieved bytes from addr [%s]:%hu: %s", sockinfo.host, sockinfo.port, buf); + + mowgli_vio_sendto(vio, ECHOBACK, sizeof(ECHOBACK), &addr); + mowgli_vio_sendto(vio, buf, strlen(buf), &addr); + } + + return EXIT_SUCCESS; /* Not reached */ +} |