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