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