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 33 static void 34 fifo_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 76 static void 77 signal_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 84 int 85 main(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