xref: /freebsd-src/contrib/ntp/sntp/libevent/sample/event-read-fifo.c (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1*a466cc55SCy Schubert /*
2*a466cc55SCy Schubert  * This sample code shows how to use Libevent to read from a named pipe.
3*a466cc55SCy Schubert  * XXX This code could make better use of the Libevent interfaces.
4*a466cc55SCy Schubert  *
5*a466cc55SCy Schubert  * XXX This does not work on Windows; ignore everything inside the _WIN32 block.
6*a466cc55SCy Schubert  *
7*a466cc55SCy Schubert  * On UNIX, compile with:
8*a466cc55SCy Schubert  * cc -I/usr/local/include -o event-read-fifo event-read-fifo.c \
9*a466cc55SCy Schubert  *     -L/usr/local/lib -levent
10*a466cc55SCy Schubert  */
11*a466cc55SCy Schubert 
12*a466cc55SCy Schubert #include <event2/event-config.h>
13*a466cc55SCy Schubert 
14*a466cc55SCy Schubert #include <sys/types.h>
15*a466cc55SCy Schubert #include <sys/stat.h>
16*a466cc55SCy Schubert #ifndef _WIN32
17*a466cc55SCy Schubert #include <sys/queue.h>
18*a466cc55SCy Schubert #include <unistd.h>
19*a466cc55SCy Schubert #include <sys/time.h>
20*a466cc55SCy Schubert #include <signal.h>
21*a466cc55SCy Schubert #else
22*a466cc55SCy Schubert #include <winsock2.h>
23*a466cc55SCy Schubert #include <windows.h>
24*a466cc55SCy Schubert #endif
25*a466cc55SCy Schubert #include <fcntl.h>
26*a466cc55SCy Schubert #include <stdlib.h>
27*a466cc55SCy Schubert #include <stdio.h>
28*a466cc55SCy Schubert #include <string.h>
29*a466cc55SCy Schubert #include <errno.h>
30*a466cc55SCy Schubert 
31*a466cc55SCy Schubert #include <event2/event.h>
32*a466cc55SCy Schubert 
33*a466cc55SCy Schubert static void
fifo_read(evutil_socket_t fd,short event,void * arg)34*a466cc55SCy Schubert fifo_read(evutil_socket_t fd, short event, void *arg)
35*a466cc55SCy Schubert {
36*a466cc55SCy Schubert 	char buf[255];
37*a466cc55SCy Schubert 	int len;
38*a466cc55SCy Schubert 	struct event *ev = arg;
39*a466cc55SCy Schubert #ifdef _WIN32
40*a466cc55SCy Schubert 	DWORD dwBytesRead;
41*a466cc55SCy Schubert #endif
42*a466cc55SCy Schubert 
43*a466cc55SCy Schubert 	fprintf(stderr, "fifo_read called with fd: %d, event: %d, arg: %p\n",
44*a466cc55SCy Schubert 	    (int)fd, event, arg);
45*a466cc55SCy Schubert #ifdef _WIN32
46*a466cc55SCy Schubert 	len = ReadFile((HANDLE)fd, buf, sizeof(buf) - 1, &dwBytesRead, NULL);
47*a466cc55SCy Schubert 
48*a466cc55SCy Schubert 	/* Check for end of file. */
49*a466cc55SCy Schubert 	if (len && dwBytesRead == 0) {
50*a466cc55SCy Schubert 		fprintf(stderr, "End Of File");
51*a466cc55SCy Schubert 		event_del(ev);
52*a466cc55SCy Schubert 		return;
53*a466cc55SCy Schubert 	}
54*a466cc55SCy Schubert 
55*a466cc55SCy Schubert 	buf[dwBytesRead] = '\0';
56*a466cc55SCy Schubert #else
57*a466cc55SCy Schubert 	len = read(fd, buf, sizeof(buf) - 1);
58*a466cc55SCy Schubert 
59*a466cc55SCy Schubert 	if (len <= 0) {
60*a466cc55SCy Schubert 		if (len == -1)
61*a466cc55SCy Schubert 			perror("read");
62*a466cc55SCy Schubert 		else if (len == 0)
63*a466cc55SCy Schubert 			fprintf(stderr, "Connection closed\n");
64*a466cc55SCy Schubert 		event_del(ev);
65*a466cc55SCy Schubert 		event_base_loopbreak(event_get_base(ev));
66*a466cc55SCy Schubert 		return;
67*a466cc55SCy Schubert 	}
68*a466cc55SCy Schubert 
69*a466cc55SCy Schubert 	buf[len] = '\0';
70*a466cc55SCy Schubert #endif
71*a466cc55SCy Schubert 	fprintf(stdout, "Read: %s\n", buf);
72*a466cc55SCy Schubert }
73*a466cc55SCy Schubert 
74*a466cc55SCy Schubert /* On Unix, cleanup event.fifo if SIGINT is received. */
75*a466cc55SCy Schubert #ifndef _WIN32
76*a466cc55SCy Schubert static void
signal_cb(evutil_socket_t fd,short event,void * arg)77*a466cc55SCy Schubert signal_cb(evutil_socket_t fd, short event, void *arg)
78*a466cc55SCy Schubert {
79*a466cc55SCy Schubert 	struct event_base *base = arg;
80*a466cc55SCy Schubert 	event_base_loopbreak(base);
81*a466cc55SCy Schubert }
82*a466cc55SCy Schubert #endif
83*a466cc55SCy Schubert 
84*a466cc55SCy Schubert int
main(int argc,char ** argv)85*a466cc55SCy Schubert main(int argc, char **argv)
86*a466cc55SCy Schubert {
87*a466cc55SCy Schubert 	struct event *evfifo;
88*a466cc55SCy Schubert 	struct event_base* base;
89*a466cc55SCy Schubert #ifdef _WIN32
90*a466cc55SCy Schubert 	HANDLE socket;
91*a466cc55SCy Schubert 	/* Open a file. */
92*a466cc55SCy Schubert 	socket = CreateFileA("test.txt",	/* open File */
93*a466cc55SCy Schubert 			GENERIC_READ,		/* open for reading */
94*a466cc55SCy Schubert 			0,			/* do not share */
95*a466cc55SCy Schubert 			NULL,			/* no security */
96*a466cc55SCy Schubert 			OPEN_EXISTING,		/* existing file only */
97*a466cc55SCy Schubert 			FILE_ATTRIBUTE_NORMAL,	/* normal file */
98*a466cc55SCy Schubert 			NULL);			/* no attr. template */
99*a466cc55SCy Schubert 
100*a466cc55SCy Schubert 	if (socket == INVALID_HANDLE_VALUE)
101*a466cc55SCy Schubert 		return 1;
102*a466cc55SCy Schubert 
103*a466cc55SCy Schubert #else
104*a466cc55SCy Schubert 	struct event *signal_int;
105*a466cc55SCy Schubert 	struct stat st;
106*a466cc55SCy Schubert 	const char *fifo = "event.fifo";
107*a466cc55SCy Schubert 	int socket;
108*a466cc55SCy Schubert 
109*a466cc55SCy Schubert 	if (lstat(fifo, &st) == 0) {
110*a466cc55SCy Schubert 		if ((st.st_mode & S_IFMT) == S_IFREG) {
111*a466cc55SCy Schubert 			errno = EEXIST;
112*a466cc55SCy Schubert 			perror("lstat");
113*a466cc55SCy Schubert 			exit(1);
114*a466cc55SCy Schubert 		}
115*a466cc55SCy Schubert 	}
116*a466cc55SCy Schubert 
117*a466cc55SCy Schubert 	unlink(fifo);
118*a466cc55SCy Schubert 	if (mkfifo(fifo, 0600) == -1) {
119*a466cc55SCy Schubert 		perror("mkfifo");
120*a466cc55SCy Schubert 		exit(1);
121*a466cc55SCy Schubert 	}
122*a466cc55SCy Schubert 
123*a466cc55SCy Schubert 	socket = open(fifo, O_RDONLY | O_NONBLOCK, 0);
124*a466cc55SCy Schubert 
125*a466cc55SCy Schubert 	if (socket == -1) {
126*a466cc55SCy Schubert 		perror("open");
127*a466cc55SCy Schubert 		exit(1);
128*a466cc55SCy Schubert 	}
129*a466cc55SCy Schubert 
130*a466cc55SCy Schubert 	fprintf(stderr, "Write data to %s\n", fifo);
131*a466cc55SCy Schubert #endif
132*a466cc55SCy Schubert 	/* Initialize the event library */
133*a466cc55SCy Schubert 	base = event_base_new();
134*a466cc55SCy Schubert 
135*a466cc55SCy Schubert 	/* Initialize one event */
136*a466cc55SCy Schubert #ifdef _WIN32
137*a466cc55SCy Schubert 	evfifo = event_new(base, (evutil_socket_t)socket, EV_READ|EV_PERSIST, fifo_read,
138*a466cc55SCy Schubert                            event_self_cbarg());
139*a466cc55SCy Schubert #else
140*a466cc55SCy Schubert 	/* catch SIGINT so that event.fifo can be cleaned up */
141*a466cc55SCy Schubert 	signal_int = evsignal_new(base, SIGINT, signal_cb, base);
142*a466cc55SCy Schubert 	event_add(signal_int, NULL);
143*a466cc55SCy Schubert 
144*a466cc55SCy Schubert 	evfifo = event_new(base, socket, EV_READ|EV_PERSIST, fifo_read,
145*a466cc55SCy Schubert                            event_self_cbarg());
146*a466cc55SCy Schubert #endif
147*a466cc55SCy Schubert 
148*a466cc55SCy Schubert 	/* Add it to the active events, without a timeout */
149*a466cc55SCy Schubert 	event_add(evfifo, NULL);
150*a466cc55SCy Schubert 
151*a466cc55SCy Schubert 	event_base_dispatch(base);
152*a466cc55SCy Schubert 	event_base_free(base);
153*a466cc55SCy Schubert #ifdef _WIN32
154*a466cc55SCy Schubert 	CloseHandle(socket);
155*a466cc55SCy Schubert #else
156*a466cc55SCy Schubert 	close(socket);
157*a466cc55SCy Schubert 	unlink(fifo);
158*a466cc55SCy Schubert #endif
159*a466cc55SCy Schubert 	libevent_global_shutdown();
160*a466cc55SCy Schubert 	return (0);
161*a466cc55SCy Schubert }
162*a466cc55SCy Schubert 
163