From: Nick Mathewson Date: Wed, 27 Jan 2010 06:46:23 +0000 (-0500) Subject: Add a new "hello world" sample program X-Git-Tag: release-2.0.4-alpha~54 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=becb9f9cd320d9b3ac571ffc788a01423568e9d0;p=libevent Add a new "hello world" sample program --- diff --git a/.gitignore b/.gitignore index 9ecd8cd0..82d6c881 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ libevent.pc /sample/dns-example /sample/event-test +/sample/hello-world /sample/le-proxy /sample/signal-test /sample/time-test diff --git a/sample/Makefile.am b/sample/Makefile.am index 8c0531f9..9a376e8c 100644 --- a/sample/Makefile.am +++ b/sample/Makefile.am @@ -3,12 +3,13 @@ AUTOMAKE_OPTIONS = foreign no-dependencies LDADD = ../libevent.la AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -noinst_PROGRAMS = event-test time-test signal-test dns-example +noinst_PROGRAMS = event-test time-test signal-test dns-example hello-world event_test_sources = event-test.c time_test_sources = time-test.c signal_test_sources = signal-test.c dns_example_sources = dns-example.c +hello_world_sources = hello-world.c if OPENSSL noinst_PROGRAMS += le-proxy diff --git a/sample/hello-world.c b/sample/hello-world.c new file mode 100644 index 00000000..773c8589 --- /dev/null +++ b/sample/hello-world.c @@ -0,0 +1,131 @@ +/* + This exmple program provides a trivial server program that listens for TCP + connections on port 9995. When they arrive, it writes a short message to + each client connection, and closes each connection once it is flushed. + + Where possible, it exits cleanly in response to a SIGINT (ctrl-c). +*/ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static const char MESSAGE[] = "Hello, World!\n"; + +static const int PORT = 9995; + +static void listener_cb(struct evconnlistener *, evutil_socket_t, + struct sockaddr *, int socklen, void *); +static void conn_writecb(struct bufferevent *, void *); +static void conn_eventcb(struct bufferevent *, short, void *); +static void signal_cb(evutil_socket_t, short, void *); + +int +main(int argc, char **argv) +{ + struct event_base *base; + struct evconnlistener *listener; + struct event *signal_event; + // struct sockaddr_storage ss; + + struct sockaddr_in sin; + + base = event_base_new(); + if (!base) { + fprintf(stderr, "Could not initialize libevent!\n"); + return 1; + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(PORT); + + listener = evconnlistener_new_bind(base, listener_cb, (void *)base, + LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1, + (struct sockaddr*)&sin, + sizeof(sin)); + + if (!listener) { + fprintf(stderr, "Could not create a listener!\n"); + return 1; + } + + signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base); + + if (!signal_event || event_add(signal_event, NULL)<0) { + fprintf(stderr, "Could not create/add a signal event!\n"); + return 1; + } + + event_base_dispatch(base); + + evconnlistener_free(listener); + event_free(signal_event); + event_base_free(base); + + printf("done\n"); + return 0; +} + +static void +listener_cb(struct evconnlistener *listener, evutil_socket_t fd, + struct sockaddr *sa, int socklen, void *user_data) +{ + struct event_base *base = user_data; + struct bufferevent *bev; + + bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); + if (!bev) { + fprintf(stderr, "Error constructing bufferevent!"); + event_base_loopbreak(base); + return; + } + bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL); + bufferevent_enable(bev, EV_WRITE); + bufferevent_disable(bev, EV_READ); + + bufferevent_write(bev, MESSAGE, strlen(MESSAGE)); +} + +static void +conn_writecb(struct bufferevent *bev, void *user_data) +{ + struct evbuffer *output = bufferevent_get_output(bev); + if (evbuffer_get_length(output) == 0) { + printf("flushed answer\n"); + bufferevent_free(bev); + } +} + +static void +conn_eventcb(struct bufferevent *bev, short events, void *user_data) +{ + if (events & BEV_EVENT_EOF) { + printf("Connection closed.\n"); + } else if (events & BEV_EVENT_ERROR) { + printf("Got an error on the connection: %s\n", + strerror(errno));/*XXX win32*/ + } + /* None of the other events can happen here, since we haven't enabled + * timeouts */ + bufferevent_free(bev); +} + +static void +signal_cb(evutil_socket_t sig, short events, void *user_data) +{ + struct event_base *base = user_data; + struct timeval delay = { 2, 0 }; + + printf("Caught an interrupt signal; exiting cleanly in two seconds.\n"); + + event_base_loopexit(base, &delay); +}