You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.3 KiB
162 lines
3.3 KiB
/* |
|
* 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); |
|
} |
|
|
|
|