xref: /aosp_15_r20/external/libevent/sample/hello-world.c (revision 663afb9b963571284e0f0a60f257164ab54f64bf)
1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker   This example program provides a trivial server program that listens for TCP
3*663afb9bSAndroid Build Coastguard Worker   connections on port 9995.  When they arrive, it writes a short message to
4*663afb9bSAndroid Build Coastguard Worker   each client connection, and closes each connection once it is flushed.
5*663afb9bSAndroid Build Coastguard Worker 
6*663afb9bSAndroid Build Coastguard Worker   Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
7*663afb9bSAndroid Build Coastguard Worker */
8*663afb9bSAndroid Build Coastguard Worker 
9*663afb9bSAndroid Build Coastguard Worker 
10*663afb9bSAndroid Build Coastguard Worker #include <string.h>
11*663afb9bSAndroid Build Coastguard Worker #include <errno.h>
12*663afb9bSAndroid Build Coastguard Worker #include <stdio.h>
13*663afb9bSAndroid Build Coastguard Worker #include <signal.h>
14*663afb9bSAndroid Build Coastguard Worker #ifndef _WIN32
15*663afb9bSAndroid Build Coastguard Worker #include <netinet/in.h>
16*663afb9bSAndroid Build Coastguard Worker # ifdef _XOPEN_SOURCE_EXTENDED
17*663afb9bSAndroid Build Coastguard Worker #  include <arpa/inet.h>
18*663afb9bSAndroid Build Coastguard Worker # endif
19*663afb9bSAndroid Build Coastguard Worker #include <sys/socket.h>
20*663afb9bSAndroid Build Coastguard Worker #endif
21*663afb9bSAndroid Build Coastguard Worker 
22*663afb9bSAndroid Build Coastguard Worker #include <event2/bufferevent.h>
23*663afb9bSAndroid Build Coastguard Worker #include <event2/buffer.h>
24*663afb9bSAndroid Build Coastguard Worker #include <event2/listener.h>
25*663afb9bSAndroid Build Coastguard Worker #include <event2/util.h>
26*663afb9bSAndroid Build Coastguard Worker #include <event2/event.h>
27*663afb9bSAndroid Build Coastguard Worker 
28*663afb9bSAndroid Build Coastguard Worker static const char MESSAGE[] = "Hello, World!\n";
29*663afb9bSAndroid Build Coastguard Worker 
30*663afb9bSAndroid Build Coastguard Worker static const int PORT = 9995;
31*663afb9bSAndroid Build Coastguard Worker 
32*663afb9bSAndroid Build Coastguard Worker static void listener_cb(struct evconnlistener *, evutil_socket_t,
33*663afb9bSAndroid Build Coastguard Worker     struct sockaddr *, int socklen, void *);
34*663afb9bSAndroid Build Coastguard Worker static void conn_writecb(struct bufferevent *, void *);
35*663afb9bSAndroid Build Coastguard Worker static void conn_eventcb(struct bufferevent *, short, void *);
36*663afb9bSAndroid Build Coastguard Worker static void signal_cb(evutil_socket_t, short, void *);
37*663afb9bSAndroid Build Coastguard Worker 
38*663afb9bSAndroid Build Coastguard Worker int
main(int argc,char ** argv)39*663afb9bSAndroid Build Coastguard Worker main(int argc, char **argv)
40*663afb9bSAndroid Build Coastguard Worker {
41*663afb9bSAndroid Build Coastguard Worker 	struct event_base *base;
42*663afb9bSAndroid Build Coastguard Worker 	struct evconnlistener *listener;
43*663afb9bSAndroid Build Coastguard Worker 	struct event *signal_event;
44*663afb9bSAndroid Build Coastguard Worker 
45*663afb9bSAndroid Build Coastguard Worker 	struct sockaddr_in sin = {0};
46*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
47*663afb9bSAndroid Build Coastguard Worker 	WSADATA wsa_data;
48*663afb9bSAndroid Build Coastguard Worker 	WSAStartup(0x0201, &wsa_data);
49*663afb9bSAndroid Build Coastguard Worker #endif
50*663afb9bSAndroid Build Coastguard Worker 
51*663afb9bSAndroid Build Coastguard Worker 	base = event_base_new();
52*663afb9bSAndroid Build Coastguard Worker 	if (!base) {
53*663afb9bSAndroid Build Coastguard Worker 		fprintf(stderr, "Could not initialize libevent!\n");
54*663afb9bSAndroid Build Coastguard Worker 		return 1;
55*663afb9bSAndroid Build Coastguard Worker 	}
56*663afb9bSAndroid Build Coastguard Worker 
57*663afb9bSAndroid Build Coastguard Worker 	sin.sin_family = AF_INET;
58*663afb9bSAndroid Build Coastguard Worker 	sin.sin_port = htons(PORT);
59*663afb9bSAndroid Build Coastguard Worker 
60*663afb9bSAndroid Build Coastguard Worker 	listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
61*663afb9bSAndroid Build Coastguard Worker 	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
62*663afb9bSAndroid Build Coastguard Worker 	    (struct sockaddr*)&sin,
63*663afb9bSAndroid Build Coastguard Worker 	    sizeof(sin));
64*663afb9bSAndroid Build Coastguard Worker 
65*663afb9bSAndroid Build Coastguard Worker 	if (!listener) {
66*663afb9bSAndroid Build Coastguard Worker 		fprintf(stderr, "Could not create a listener!\n");
67*663afb9bSAndroid Build Coastguard Worker 		return 1;
68*663afb9bSAndroid Build Coastguard Worker 	}
69*663afb9bSAndroid Build Coastguard Worker 
70*663afb9bSAndroid Build Coastguard Worker 	signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
71*663afb9bSAndroid Build Coastguard Worker 
72*663afb9bSAndroid Build Coastguard Worker 	if (!signal_event || event_add(signal_event, NULL)<0) {
73*663afb9bSAndroid Build Coastguard Worker 		fprintf(stderr, "Could not create/add a signal event!\n");
74*663afb9bSAndroid Build Coastguard Worker 		return 1;
75*663afb9bSAndroid Build Coastguard Worker 	}
76*663afb9bSAndroid Build Coastguard Worker 
77*663afb9bSAndroid Build Coastguard Worker 	event_base_dispatch(base);
78*663afb9bSAndroid Build Coastguard Worker 
79*663afb9bSAndroid Build Coastguard Worker 	evconnlistener_free(listener);
80*663afb9bSAndroid Build Coastguard Worker 	event_free(signal_event);
81*663afb9bSAndroid Build Coastguard Worker 	event_base_free(base);
82*663afb9bSAndroid Build Coastguard Worker 
83*663afb9bSAndroid Build Coastguard Worker 	printf("done\n");
84*663afb9bSAndroid Build Coastguard Worker 	return 0;
85*663afb9bSAndroid Build Coastguard Worker }
86*663afb9bSAndroid Build Coastguard Worker 
87*663afb9bSAndroid Build Coastguard Worker static void
listener_cb(struct evconnlistener * listener,evutil_socket_t fd,struct sockaddr * sa,int socklen,void * user_data)88*663afb9bSAndroid Build Coastguard Worker listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
89*663afb9bSAndroid Build Coastguard Worker     struct sockaddr *sa, int socklen, void *user_data)
90*663afb9bSAndroid Build Coastguard Worker {
91*663afb9bSAndroid Build Coastguard Worker 	struct event_base *base = user_data;
92*663afb9bSAndroid Build Coastguard Worker 	struct bufferevent *bev;
93*663afb9bSAndroid Build Coastguard Worker 
94*663afb9bSAndroid Build Coastguard Worker 	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
95*663afb9bSAndroid Build Coastguard Worker 	if (!bev) {
96*663afb9bSAndroid Build Coastguard Worker 		fprintf(stderr, "Error constructing bufferevent!");
97*663afb9bSAndroid Build Coastguard Worker 		event_base_loopbreak(base);
98*663afb9bSAndroid Build Coastguard Worker 		return;
99*663afb9bSAndroid Build Coastguard Worker 	}
100*663afb9bSAndroid Build Coastguard Worker 	bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
101*663afb9bSAndroid Build Coastguard Worker 	bufferevent_enable(bev, EV_WRITE);
102*663afb9bSAndroid Build Coastguard Worker 	bufferevent_disable(bev, EV_READ);
103*663afb9bSAndroid Build Coastguard Worker 
104*663afb9bSAndroid Build Coastguard Worker 	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
105*663afb9bSAndroid Build Coastguard Worker }
106*663afb9bSAndroid Build Coastguard Worker 
107*663afb9bSAndroid Build Coastguard Worker static void
conn_writecb(struct bufferevent * bev,void * user_data)108*663afb9bSAndroid Build Coastguard Worker conn_writecb(struct bufferevent *bev, void *user_data)
109*663afb9bSAndroid Build Coastguard Worker {
110*663afb9bSAndroid Build Coastguard Worker 	struct evbuffer *output = bufferevent_get_output(bev);
111*663afb9bSAndroid Build Coastguard Worker 	if (evbuffer_get_length(output) == 0) {
112*663afb9bSAndroid Build Coastguard Worker 		printf("flushed answer\n");
113*663afb9bSAndroid Build Coastguard Worker 		bufferevent_free(bev);
114*663afb9bSAndroid Build Coastguard Worker 	}
115*663afb9bSAndroid Build Coastguard Worker }
116*663afb9bSAndroid Build Coastguard Worker 
117*663afb9bSAndroid Build Coastguard Worker static void
conn_eventcb(struct bufferevent * bev,short events,void * user_data)118*663afb9bSAndroid Build Coastguard Worker conn_eventcb(struct bufferevent *bev, short events, void *user_data)
119*663afb9bSAndroid Build Coastguard Worker {
120*663afb9bSAndroid Build Coastguard Worker 	if (events & BEV_EVENT_EOF) {
121*663afb9bSAndroid Build Coastguard Worker 		printf("Connection closed.\n");
122*663afb9bSAndroid Build Coastguard Worker 	} else if (events & BEV_EVENT_ERROR) {
123*663afb9bSAndroid Build Coastguard Worker 		printf("Got an error on the connection: %s\n",
124*663afb9bSAndroid Build Coastguard Worker 		    strerror(errno));/*XXX win32*/
125*663afb9bSAndroid Build Coastguard Worker 	}
126*663afb9bSAndroid Build Coastguard Worker 	/* None of the other events can happen here, since we haven't enabled
127*663afb9bSAndroid Build Coastguard Worker 	 * timeouts */
128*663afb9bSAndroid Build Coastguard Worker 	bufferevent_free(bev);
129*663afb9bSAndroid Build Coastguard Worker }
130*663afb9bSAndroid Build Coastguard Worker 
131*663afb9bSAndroid Build Coastguard Worker static void
signal_cb(evutil_socket_t sig,short events,void * user_data)132*663afb9bSAndroid Build Coastguard Worker signal_cb(evutil_socket_t sig, short events, void *user_data)
133*663afb9bSAndroid Build Coastguard Worker {
134*663afb9bSAndroid Build Coastguard Worker 	struct event_base *base = user_data;
135*663afb9bSAndroid Build Coastguard Worker 	struct timeval delay = { 2, 0 };
136*663afb9bSAndroid Build Coastguard Worker 
137*663afb9bSAndroid Build Coastguard Worker 	printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
138*663afb9bSAndroid Build Coastguard Worker 
139*663afb9bSAndroid Build Coastguard Worker 	event_base_loopexit(base, &delay);
140*663afb9bSAndroid Build Coastguard Worker }
141