diff options
Diffstat (limited to 'libs/libevent/docs/sample/event-read-fifo.c')
-rw-r--r-- | libs/libevent/docs/sample/event-read-fifo.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/libs/libevent/docs/sample/event-read-fifo.c b/libs/libevent/docs/sample/event-read-fifo.c new file mode 100644 index 0000000000..27b0b530d5 --- /dev/null +++ b/libs/libevent/docs/sample/event-read-fifo.c @@ -0,0 +1,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); +} + |