#include #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_QUEUE_DIR "." void run_job(char *queuedir, int fd) { char *run; switch(fork()) { case -1: return; case 0: asprintf(&run, "%s/run", queuedir); dup2(fd, STDIN_FILENO); close(fd); execl(run, "run", (char*)NULL); perror("execle()"); _exit(1); default: wait(NULL); } } void process_queue(char *queuedir, int dfd) { int fd; DIR *dir; struct dirent *de; char *name; dir = fdopendir(dfd); while ((de = readdir(dir))) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; asprintf(&name, "new/%s", de->d_name); fd = open(name, O_RDONLY); if (fd == -1) { free(name); continue; } unlink(name); run_job(queuedir, fd); close(fd); free(name); } rewinddir(dir); fdclosedir(dir); } int main(int argc, char **argv) { int kq, dfd, ret; struct kevent kv; char *queuedir = NULL, *newdir = NULL; if (argc > 1) { queuedir = strdup(argv[1]); } else { queuedir = strdup(DEFAULT_QUEUE_DIR); } asprintf(&newdir, "%s/new", queuedir); dfd = open(newdir, O_RDONLY | O_DIRECTORY); if (dfd == -1) err(1, "open()"); kq = kqueue(); if (kq == -1) err(1, "kqueue()"); EV_SET(&kv, dfd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, NULL); if (kevent(kq, &kv, 1, NULL, 0, NULL) == -1) err(1, "kevent()"); process_queue(queuedir, dfd); for (;;) { ret = kevent(kq, NULL, 0, &kv, 1, NULL); if (ret == 0) continue; else if (ret == -1) { if (errno == EINTR) continue; else break; } process_queue(queuedir, dfd); } return 0; }