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