Skip to content

Instantly share code, notes, and snippets.

@bnoordhuis
Created November 22, 2011 14:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnoordhuis/1385726 to your computer and use it in GitHub Desktop.
Save bnoordhuis/1385726 to your computer and use it in GitHub Desktop.
file watching + event ports = disaster
/*
* Copyright (c) 2011, Ben Noordhuis <info@bnoordhuis.nl>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <port.h>
#include <poll.h>
#define streq(a, b) (strcmp((a), (b)) == 0)
#define E(expr) \
do { \
errno = 0; \
(expr); \
if (errno) die(#expr); \
} \
while (0)
static char *path = ".";
static int portfd = -1;
static port_event_t pe;
static struct file_obj fo;
static void die(const char *prefix)
{
perror(prefix);
exit(42);
}
static void rearm(void)
{
if (portfd == -1) {
fo.fo_name = path;
E(portfd = port_create());
}
E(port_associate(portfd,
PORT_SOURCE_FILE,
(uintptr_t) &fo,
FILE_ACCESS|FILE_MODIFIED|FILE_ATTRIB,
fo.fo_name));
}
static void report(void)
{
printf("events for '%s' -> %08x\n",
(const char *) pe.portev_user,
pe.portev_events);
}
static void receive_direct(void)
{
E(port_get(portfd, &pe, NULL));
}
static void receive_port(void)
{
int pfd;
E(pfd = port_create());
E(port_associate(pfd, PORT_SOURCE_FD, portfd, POLLIN, "outer poll"));
E(port_get(pfd, &pe, NULL));
report();
receive_direct();
}
static void receive_poll(void)
{
struct pollfd pfd;
pfd.fd = portfd;
pfd.events = POLLIN;
pfd.revents = 0;
E(poll(&pfd, 1, -1));
printf("portfd events: %08x\n", pfd.revents);
receive_direct();
}
int main(int argc, char **argv)
{
void (*receive)(void) = receive_direct;
if (argc > 1) {
if (streq(argv[1], "--poll"))
receive = receive_poll;
else if (streq(argv[1], "--port"))
receive = receive_port;
else
goto skip;
argv++, argc--;
skip: (void) 0;
}
if (argc > 1)
path = argv[1];
while (1) {
rearm();
receive();
report();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment