Created
December 4, 2012 07:22
-
-
Save hroptatyr/4201517 to your computer and use it in GitHub Desktop.
some snippets to watch directories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.o | |
watchdir | |
watchdir-clo.[ch] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RM = rm -f | |
CC = icc -static-intel -static-libgcc -std=c99 | |
CFLAGS = -g -O3 | |
all: watchdir | |
clean: | |
$(RM) watchdir *.o watchdir-clo.c watchdir-clo.h | |
watchdir: watchdir-clo.c watchdir.o | |
$(CC) $(CFLAGS) -o $@ $@.o | |
.SUFFIXES: .c .o .h .ggo | |
.c.o: | |
$(CC) $(CFLAGS) -c -o $@ $< -DVERSION='"0.0"' -D_POSIX_C_SOURCE=200112L -D_BSD_SOURCE | |
.ggo.c: | |
gengetopt -F $* -i $< |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
args "--unamed-opts --no-help --long-help --no-handle-error -a wd_args_info -f wd_parser" | |
package "watchdir" | |
usage "watchdir DIR..." | |
description "Watch directory for creation/deletion." | |
option "help" h | |
"Show this help message." | |
optional | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <time.h> | |
#include <sys/time.h> | |
#include <sys/inotify.h> | |
#include <sys/epoll.h> | |
static void | |
fputt(FILE *where) | |
{ | |
static char buf[64]; | |
struct timeval tv[1]; | |
struct tm *tm; | |
char *p = buf; | |
#define R(p) (sizeof(buf) - ((p) - buf)) | |
(void)gettimeofday(tv, NULL); | |
tm = gmtime(&tv->tv_sec); | |
p += strftime(p, R(p), "%FT%T", tm); | |
snprintf(p, R(p), ".%06lu", tv->tv_usec); | |
fputs(buf, where); | |
#undef R | |
return; | |
} | |
static int | |
got_beef(int fd, const char *const *dirs) | |
{ | |
static uint8_t buf[4096]; | |
struct inotify_event *restrict inev = (void*)buf; | |
ssize_t nrd; | |
while ((nrd = read(fd, buf, sizeof(buf))) >= 0) { | |
if (nrd < sizeof(*inev)) { | |
return -1; | |
} | |
/* prepend time stamp */ | |
fputt(stdout); | |
fputc('\t', stdout); | |
fputs(dirs[inev->wd - 1], stdout); | |
fputc('\t', stdout); | |
if (inev->mask & (IN_CREATE | IN_MOVED_TO)) { | |
fputc('c', stdout); | |
} | |
if (inev->mask & IN_MOVED_TO) { | |
fputc('i', stdout); | |
} | |
if (inev->mask & (IN_DELETE | IN_MOVED_FROM)) { | |
fputc('x', stdout); | |
} | |
if (inev->mask & IN_MOVED_FROM) { | |
fputc('o', stdout); | |
} | |
if (inev->len > 0) { | |
fputc('\t', stdout); | |
fputs(inev->name, stdout); | |
} | |
fputc('\n', stdout); | |
} | |
return 0; | |
} | |
static int | |
watchdir(int inofd, const char *dir) | |
{ | |
int dirfd = inotify_add_watch( | |
inofd, dir, | |
IN_CREATE | IN_DELETE | | |
IN_MOVED_FROM | IN_MOVED_TO); | |
return dirfd; | |
} | |
#include "watchdir-clo.h" | |
#include "watchdir-clo.c" | |
int | |
main(int argc, char *argv[]) | |
{ | |
struct wd_args_info argi[1]; | |
struct epoll_event ev[1]; | |
int inofd; | |
int epfd; | |
if (wd_parser(argc, argv, argi)) { | |
return 1; | |
} else if (argi->help_given) { | |
wd_parser_print_help(); | |
return 0; | |
} else if (argi->inputs_num == 0) { | |
wd_parser_print_help(); | |
return 1; | |
} | |
/* prepare watches */ | |
inofd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK); | |
for (unsigned int i = 0; i < argi->inputs_num; i++) { | |
watchdir(inofd, argi->inputs[i]); | |
} | |
/* prepare main loop */ | |
epfd = epoll_create1(EPOLL_CLOEXEC); | |
ev->events = EPOLLIN | EPOLLHUP | EPOLLET; | |
ev->data.fd = inofd; | |
epoll_ctl(epfd, EPOLL_CTL_ADD, inofd, ev); | |
/* main loop */ | |
while (epoll_wait(epfd, ev, 1, -1)) { | |
if (ev->events & EPOLLIN && | |
got_beef(ev->data.fd, argi->inputs) < 0) { | |
break; | |
} else if (ev->events & EPOLLHUP) { | |
break; | |
} | |
} | |
/* clean up */ | |
epoll_ctl(epfd, EPOLL_CTL_DEL, inofd, ev); | |
close(epfd); | |
close(inofd); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment