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