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