summaryrefslogtreecommitdiff
path: root/pnotify/pnotify-0.2/pnotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'pnotify/pnotify-0.2/pnotify.c')
-rw-r--r--pnotify/pnotify-0.2/pnotify.c869
1 files changed, 0 insertions, 869 deletions
diff --git a/pnotify/pnotify-0.2/pnotify.c b/pnotify/pnotify-0.2/pnotify.c
deleted file mode 100644
index 1c748a8..0000000
--- a/pnotify/pnotify-0.2/pnotify.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/* $Id: $ */
-
-/*
- * Copyright (c) 2007 Mark Heily <devel@heily.com>
- *
- * Permission to use, copy, modify, and 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 <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include "pnotify.h"
-#include "queue.h"
-
-#if defined(__linux__)
-# define HAVE_INOTIFY 1
-# include <sys/inotify.h>
-#else
-# define HAVE_KQUEUE 1
-# include <sys/event.h>
-#endif
-
-/* The 'dprintf' macro is used for printf() debugging */
-#if PNOTIFY_DEBUG
-# define dprintf printf
-# define dprint_event(e) (void) pnotify_print_event(e)
-#else
-# define dprintf(...) do { ; } while (0)
-# define dprint_event(e) do { ; } while (0)
-#endif
-
-/** The maximum number of watches that a single controller can have */
-static const int WATCH_MAX = 20000;
-
-/** An entire directory that is under watch */
-struct directory {
-
- /** The full pathname of the directory */
- char *path;
- size_t path_len;
-
- /** A directory handle returned by opendir(3) */
- DIR *dirp;
-
- /* All entries in the directory (struct dirent) */
- LIST_HEAD(, dentry) all;
-};
-
-/** A directory entry list element */
-struct dentry {
-
- /** The directory entry from readdir(3) */
- struct dirent ent;
-
- /** A file descriptor used by kqueue(4) to monitor the entry */
- int fd;
-
- /** The file status from stat(2) */
- struct stat st;
-
- /** All event(s) that occurred on this file */
- int mask;
-
- /** Pointer to the next directory entry */
- LIST_ENTRY(dentry) entries;
-};
-
-
-/** An internal watch entry */
-struct pnotify_watch {
- int fd; /**< kqueue(4) watched file descriptor */
- int wd; /**< Unique 'watch descriptor' */
- char path[PATH_MAX + 1]; /**< Path associated with fd */
- uint32_t mask; /**< Mask of monitored events */
-
- bool is_dir; /**< TRUE, if the file is a directory */
-
- /* A list of directory entries (only used if is_dir is true) */
- struct directory dir;
-
- /* The parent watch descriptor, for watches that are
- automatically added on files within a monitored
- directory. If zero, there is no parent.
- */
- int parent_wd;
-
-#if HAVE_KQUEUE
-
- /* The associated kernel event structure */
- struct kevent kev;
-
-#endif
-
- /* Pointer to the next watch */
- LIST_ENTRY(pnotify_watch) entries;
-};
-
-/* Forward declarations */
-#if HAVE_KQUEUE
-static int directory_scan(struct pnotify_cb *ctl, struct pnotify_watch * watch);
-static int directory_open(struct pnotify_cb *ctl, struct pnotify_watch * watch);
-static int kq_directory_event_handler(struct kevent kev, struct pnotify_cb * ctl, struct pnotify_watch * watch);
-
-# define sys_create_event_queue kqueue
-# define sys_add_watch kq_add_watch
-# define sys_rm_watch kq_rm_watch
-# define sys_get_event kq_get_event
-#elif HAVE_INOTIFY
-# define sys_create_event_queue inotify_init
-# define sys_add_watch in_add_watch
-# define sys_rm_watch in_rm_watch
-# define sys_get_event in_get_event
-#endif
-
-
-#if HAVE_KQUEUE
-
-static inline int
-kq_add_watch(struct pnotify_cb *ctl, struct pnotify_watch *watch)
-{
- struct stat st;
- struct kevent *kev = &watch->kev;
- int mask = watch->mask;
-
- /* Open the file */
- if ((watch->fd = open(watch->path, O_RDONLY)) < 0) {
- warn("opening path `%s' failed", watch->path);
- return -1;
- }
-
- /* Test if the file is a directory */
- if (fstat(watch->fd, &st) < 0) {
- warn("fstat(2) failed");
- return -1;
- }
- watch->is_dir = S_ISDIR(st.st_mode);
-
- /* Initialize the directory structure, if needed */
- if (watch->is_dir)
- directory_open(ctl, watch);
-
- /* Generate a new watch ID */
- /* FIXME - this never decreases and might fail */
- if ((watch->wd = ++ctl->next_wd) > WATCH_MAX) {
- warn("watch_max exceeded");
- return -1;
- }
-
- /* Create and populate a kevent structure */
- EV_SET(kev, watch->fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, 0, 0, watch);
- if (mask & PN_ACCESS || mask & PN_MODIFY)
- kev->fflags |= NOTE_ATTRIB;
- if (mask & PN_CREATE)
- kev->fflags |= NOTE_WRITE;
- if (mask & PN_DELETE)
- kev->fflags |= NOTE_DELETE | NOTE_WRITE;
- if (mask & PN_MODIFY)
- kev->fflags |= NOTE_WRITE | NOTE_TRUNCATE | NOTE_EXTEND;
- if (mask & PN_ONESHOT)
- kev->flags |= EV_ONESHOT;
-
- /* Add the kevent to the kernel event queue */
- if (kevent(ctl->fd, kev, 1, NULL, 0, NULL) < 0) {
- perror("kevent(2)");
- return -1;
- }
-
- return 0;
-}
-
-
-static inline int
-kq_rm_watch(struct pnotify_cb *ctl, struct pnotify_watch *watch)
-{
- /* Close the file descriptor.
- The kernel will automatically delete the kevent
- and any pending events.
- */
- if (close(watch->fd) < 0) {
- perror("unable to close watch fd");
- return -1;
- }
-
- /* Close the directory handle */
- if (watch->dir.dirp != NULL) {
- if (closedir(watch->dir.dirp) != 0) {
- perror("closedir(3)");
- return -1;
- }
- }
-
- return 0;
-}
-
-static inline int
-kq_get_event(struct pnotify_event *evt, struct pnotify_cb *ctl)
-{
- struct pnotify_watch *watch;
- struct pnotify_event *evp;
- struct kevent kev;
- int rc;
-
-retry:
-
- /* Wait for an event notification from the kernel */
- dprintf("waiting for kernel event..\n");
- rc = kevent(ctl->fd, NULL, 0, &kev, 1, NULL);
- if ((rc < 0) || (kev.flags & EV_ERROR)) {
- warn("kevent(2) failed");
- return -1;
- }
-
- /* Find the matching watch structure */
- watch = (struct pnotify_watch *) kev.udata;
-
- /* Workaround:
-
- Deleting a file in a watched directory causes two events:
- NOTE_MODIFY on the directory
- NOTE_DELETE on the file
-
- We ignore the NOTE_DELETE on the file.
- */
- if (watch->parent_wd && kev.fflags & NOTE_DELETE) {
- dprintf("ignoring NOTE_DELETE on a watched file\n");
- goto retry;
- }
-
- /* Convert the kqueue(4) flags to pnotify_event flags */
- if (!watch->is_dir) {
- if (kev.fflags & NOTE_WRITE)
- evt->mask |= PN_MODIFY;
- if (kev.fflags & NOTE_TRUNCATE)
- evt->mask |= PN_MODIFY;
- if (kev.fflags & NOTE_EXTEND)
- evt->mask |= PN_MODIFY;
-#if TODO
- // not implemented yet
- if (kev.fflags & NOTE_ATTRIB)
- evt->mask |= PN_ATTRIB;
-#endif
- if (kev.fflags & NOTE_DELETE)
- evt->mask |= PN_DELETE;
-
- /* Construct a pnotify_event structure */
- if ((evp = calloc(1, sizeof(*evp))) == NULL) {
- warn("malloc failed");
- return -1;
- }
-
- /* If the event happened within a watched directory,
- add the filename and the parent watch descriptor.
- */
- if (watch->parent_wd) {
-
- /* KLUDGE: remove the leading basename */
- char *fn = strrchr(watch->path, '/') ;
- if (!fn) {
- fn = watch->path;
- } else {
- fn++;
- }
-
- evt->wd = watch->parent_wd;
- /* FIXME: more error handling */
- (void) strncpy(evt->name, fn, strlen(fn));
- }
-
- /* Add the event to the list of pending events */
- memcpy(evp, evt, sizeof(*evp));
- STAILQ_INSERT_TAIL(&ctl->event, evp, entries);
-
- dprint_event(evt);
-
- /* Handle events on directories */
- } else {
-
- /* When a file is added or deleted, NOTE_WRITE is set */
- if (kev.fflags & NOTE_WRITE) {
- if (kq_directory_event_handler(kev, ctl, watch) < 0) {
- warn("error processing diretory");
- return -1;
- }
- }
- /* FIXME: Handle the deletion of a watched directory */
- else if (kev.fflags & NOTE_DELETE) {
- warn("unimplemented - TODO");
- return -1;
- } else {
- warn("unknown event recieved");
- return -1;
- }
-
- }
-
- return 0;
-}
-
-#endif /* HAVE_KQUEUE */
-
-/* ------------------------ inotify(7) wrappers -------------------- */
-
-#if HAVE_INOTIFY
-
-static inline int
-in_add_watch(struct pnotify_cb *ctl, struct pnotify_watch *watch)
-{
- int mask = watch->mask;
- uint32_t imask = 0;
-
- /* Generate the mask */
- if (mask & PN_ACCESS || mask & PN_MODIFY)
- imask |= IN_ACCESS | IN_ATTRIB;
- if (mask & PN_CREATE)
- imask |= IN_CREATE;
- if (mask & PN_DELETE)
- imask |= IN_DELETE | IN_DELETE_SELF;
- if (mask & PN_MODIFY)
- imask |= IN_MODIFY;
- if (mask & PN_ONESHOT)
- imask |= IN_ONESHOT;
-
- /* Add the event to the kernel event queue */
- watch->wd = inotify_add_watch(ctl->fd, watch->path, imask);
- if (watch->wd < 0) {
- perror("inotify_add_watch(2) failed");
- return -1;
- }
-
- return 0;
-}
-
-static inline int
-in_rm_watch(struct pnotify_cb *ctl, struct pnotify_watch *watch)
-{
- // FIXME - this causes an IN_IGNORE event to be generated;
- // need to handle
- if (inotify_rm_watch(ctl->fd, watch->wd) < 0) {
- perror("inotify_rm_watch(2)");
- return -1;
- }
-
- return 0;
-}
-
-static inline int
-in_get_event(struct pnotify_event *evt, struct pnotify_cb *ctl)
-{
- struct pnotify_watch *watch;
- struct pnotify_event *evp;
- struct inotify_event *iev, *endp;
- ssize_t bytes;
- char buf[4096];
-
-retry:
-
- /* Read the event structure */
- bytes = read(ctl->fd, &buf, sizeof(buf));
- if (bytes <= 0) {
- if (errno == EINTR)
- goto retry;
- else
- perror("read(2)");
-
- return -1;
- }
-
- /* Compute the beginning and end of the event list */
- iev = (struct inotify_event *) & buf;
- endp = iev + bytes;
-
- /* Process each pending event */
- while (iev < endp) {
-
- /* XXX-WORKAROUND */
- if (iev->wd == 0)
- break;
-
- /* Find the matching watch structure */
- LIST_FOREACH(watch, &ctl->watch, entries) {
- if (watch->wd == iev->wd)
- break;
- }
- if (!watch) {
- warn("watch # %d not found", iev->wd);
- return -1;
- }
- /* Construct a pnotify_event structure */
- if ((evp = calloc(1, sizeof(*evp))) == NULL) {
- warn("malloc failed");
- return -1;
- }
- evp->wd = watch->wd;
- (void) strncpy(evp->name, iev->name, iev->len);
- if (iev->mask & IN_ACCESS)
- evp->mask |= PN_ACCESS;
-#if TODO
- // not implemented
- if (iev->mask & IN_ATTRIB)
- evp->mask |= PN_ATTRIB;
-#endif
- if (iev->mask & IN_MODIFY)
- evp->mask |= PN_MODIFY;
- if (iev->mask & IN_CREATE)
- evp->mask |= PN_CREATE;
- if (iev->mask & IN_DELETE)
- evp->mask |= PN_DELETE;
- if (iev->mask & IN_DELETE_SELF) {
- evp->mask |= PN_DELETE;
- (void) strncpy(evp->name, "", 0);
- }
-
- /* Add the event to the list of pending events */
- STAILQ_INSERT_TAIL(&ctl->event, evp, entries);
-
- /* Go to the next event */
- iev += sizeof(*iev) + iev->len;
- }
-
- return 0;
-}
-
-#endif /* HAVE_INOTIFY */
-
-/* ----------------------- pnotify(3) interface -------------------- */
-
-int
-pnotify_init(struct pnotify_cb *ctl)
-{
- assert(ctl != NULL);
-
- memset(ctl, 0, sizeof(*ctl));
-
- /* Create a kernel event queue */
- ctl->fd = sys_create_event_queue();
- if (ctl->fd < 0) {
- warn("unable to create event descriptor");
- return -1;
- }
-
- LIST_INIT(&ctl->watch);
- STAILQ_INIT(&ctl->event);
-
- return 0;
-}
-
-
-int
-pnotify_add_watch(struct pnotify_cb *ctl, const char *pathname, int mask)
-{
- struct pnotify_watch *watch;
-
- assert(ctl && pathname);
-
- /* Allocate a new entry */
- if ((watch = malloc(sizeof(*watch))) == NULL) {
- warn("malloc error");
- return -1;
- }
- (void) strncpy((char *) &watch->path, pathname, sizeof(watch->path));
- watch->mask = mask;
-
- /* Register the watch with the kernel */
- if (sys_add_watch(ctl, watch) < 0) {
- warn("adding watch failed");
- free(watch);
- return -1;
- }
-
- /* Update the control block */
- LIST_INSERT_HEAD(&ctl->watch, watch, entries);
-
- dprintf("added watch: wd=%d mask=%d path=%s\n",
- watch->wd, watch->mask, watch->path);
-
- return watch->wd;
-}
-
-
-/**
- Remove a watch.
-
- @param ctl a pnotify control block
- @param wd FIXME --- WONT WORK
- @return 0 if successful, or -1 if an error occurred.
-*/
-int
-pnotify_rm_watch(struct pnotify_cb * ctl, int wd)
-{
- struct pnotify_watch *watchp, *wtmp;
- int found = 0;
-
- assert(ctl && wd >= 0);
-
- /* Find the matching watch structure(s) */
- LIST_FOREACH_SAFE(watchp, &ctl->watch, entries, wtmp) {
-
- /* Remove the parent watch and it's children */
- if ((watchp->wd == wd) || (watchp->parent_wd == wd)) {
- if (sys_rm_watch(ctl, watchp) < 0)
- return -1;
- LIST_REMOVE(watchp, entries);
- free(watchp);
- found++;
- }
- }
-
- if (found == 0) {
- warn("watch # %d not found", wd);
- return -1;
- } else {
- return 0;
- }
-}
-
-
-int
-pnotify_get_event(struct pnotify_event * evt,
- struct pnotify_cb * ctl
- )
-{
- struct pnotify_event *evp;
-
- assert(evt && ctl);
-
- /* If there are pending events in the queue, return the first one */
- if (!STAILQ_EMPTY(&ctl->event))
- goto next_event;
-
-retry_wait:
-
- /* Reset the event structure to be empty */
- memset(evt, 0, sizeof(*evt));
-
- /* Wait for a kernel event */
- if (sys_get_event(evt, ctl) < 0)
- return -1;
-
-next_event:
-
- /* Shift the first element off of the pending event queue */
- if (!STAILQ_EMPTY(&ctl->event)) {
- evp = STAILQ_FIRST(&ctl->event);
- STAILQ_REMOVE_HEAD(&ctl->event, entries);
- memcpy(evt, evp, sizeof(*evt));
- free(evp);
-
- /* If the event mask is zero, get the next event */
- if (evt->mask == 0)
- goto next_event;
- } else {
- //warn("spurious wakeup");
- goto retry_wait;
- }
-
- return 0;
-}
-
-
-int
-pnotify_print_event(struct pnotify_event * evt)
-{
- assert(evt);
-
- return printf("event: wd=%d mask=(%s%s%s%s%s) name=`%s'\n",
- evt->wd,
- evt->mask & PN_ACCESS ? "access," : "",
- evt->mask & PN_CREATE ? "create," : "",
- evt->mask & PN_DELETE ? "delete," : "",
- evt->mask & PN_MODIFY ? "modify," : "",
- evt->mask & PN_ERROR ? "error," : "",
- evt->name);
-}
-
-
-void
-pnotify_dump(struct pnotify_cb *ctl)
-{
- struct pnotify_event *evt;
-
- printf("\npending events:\n");
- STAILQ_FOREACH(evt, &ctl->event, entries) {
- printf("\t");
- (void) pnotify_print_event(evt);
- }
- printf("/* end: pending events */\n");
-}
-
-
-int
-pnotify_free(struct pnotify_cb *ctl)
-{
- struct pnotify_watch *watch;
- struct pnotify_event *evt, *nxt;
-
- assert(ctl != NULL);
-
- /* Delete all watches */
- while (!LIST_EMPTY(&ctl->watch)) {
- watch = LIST_FIRST(&ctl->watch);
- if (pnotify_rm_watch(ctl, watch->wd) < 0) {
- warn("error removing watch");
- return -1;
- }
- }
-
- /* Delete all pending events */
- evt = STAILQ_FIRST(&ctl->event);
- while (evt != NULL) {
- nxt = STAILQ_NEXT(evt, entries);
- free(evt);
- evt = nxt;
- }
-
- /* Close the event descriptor */
- if (close(ctl->fd) < 0) {
- perror("close(2)");
- return -1;
- }
-
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------------*/
-/*-------------------------------------------------------------------------------*/
-/*-------------------------------------------------------------------------------*/
-
-#if HAVE_KQUEUE
-
-/**
- Open a watched directory.
-*/
-static int
-directory_open(struct pnotify_cb *ctl, struct pnotify_watch * watch)
-{
- struct directory * dir;
-
- dir = &watch->dir;
-
- /* Initialize the li_directory structure */
- LIST_INIT(&dir->all);
- if ((dir->dirp = opendir(watch->path)) == NULL) {
- perror("opendir(2)");
- return -1;
- }
-
- /* Store the pathname */
- dir->path_len = strlen(watch->path);
- if ((dir->path_len >= PATH_MAX) ||
- ((dir->path = malloc(dir->path_len + 1)) == NULL)) {
- perror("malloc(3)");
- return -1;
- }
- strncpy(dir->path, watch->path, dir->path_len);
-
- /* Scan the directory */
- if (directory_scan(ctl, watch) < 0) {
- warn("directory_scan failed");
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- Scan a directory looking for new, modified, and deleted files.
- */
-static int
-directory_scan(struct pnotify_cb *ctl, struct pnotify_watch * watch)
-{
- struct pnotify_watch *wtmp;
- struct directory *dir;
- struct dirent ent, *entp;
- struct dentry *dptr;
- bool found;
- char path[PATH_MAX + 1];
- char *cp;
- struct stat st;
-
- assert(watch != NULL);
-
- dir = &watch->dir;
-
- dprintf("scanning directory\n");
-
- /* Generate the basename */
- (void) snprintf((char *) &path, PATH_MAX, "%s/", dir->path);
- cp = path + dir->path_len + 1;
-
- /*
- * Invalidate the status mask for all entries.
- * This is used to detect entries that have been deleted.
- */
- LIST_FOREACH(dptr, &dir->all, entries) {
- dptr->mask = PN_DELETE;
- }
-
- /* Skip the initial '.' and '..' entries */
- /* XXX-FIXME doesnt work with chroot(2) when '..' doesn't exist */
- rewinddir(dir->dirp);
- if (readdir_r(dir->dirp, &ent, &entp) != 0) {
- perror("readdir_r(3)");
- return -1;
- }
- if (strcmp(ent.d_name, ".") == 0) {
- if (readdir_r(dir->dirp, &ent, &entp) != 0) {
- perror("readdir_r(3)");
- return -1;
- }
- }
-
- /* Read all entries in the directory */
- for (;;) {
-
- /* Read the next entry */
- if (readdir_r(dir->dirp, &ent, &entp) != 0) {
- perror("readdir_r(3)");
- return -1;
- }
-
- /* Check for the end-of-directory condition */
- if (entp == NULL)
- break;
-
- /* Perform a linear search for the dentry */
- found = false;
- LIST_FOREACH(dptr, &dir->all, entries) {
-
- /*
- * BUG - this doesnt handle hardlinks which
- * have the same d_fileno but different
- * dirent structs
- */
- //should compare the entire dirent struct...
- if (dptr->ent.d_fileno != ent.d_fileno)
- continue;
-
- dprintf("old entry: %s\n", ent.d_name);
- dptr->mask = 0;
-
- /* Generate the full pathname */
- // BUG: name_max is not precise enough
- strncpy(cp, ent.d_name, NAME_MAX);
-
- /* Check the mtime and atime */
- if (stat((char *) &path, &st) < 0) {
- perror("stat(2)");
- return -1;
- }
-
- found = true;
- break;
- }
-
- /* Add the entry to the list, if needed */
- if (!found) {
- dprintf("new entry: %s\n", ent.d_name);
-
- /* Allocate a new dentry structure */
- if ((dptr = malloc(sizeof(*dptr))) == NULL) {
- perror("malloc(3)");
- return -1;
- }
-
- /* Copy the dirent structure */
- memcpy(&dptr->ent, &ent, sizeof(ent));
- dptr->mask = PN_CREATE;
-
- /* Generate the full pathname */
- // BUG: name_max is not precise enough
- strncpy(cp, ent.d_name, NAME_MAX);
-
- /* Get the file status */
- if (stat((char *) &path, &st) < 0) {
- perror("stat(2)");
- return -1;
- }
-
- /* Add a watch if it is a regular file */
- if (S_ISREG(st.st_mode)) {
- if (pnotify_add_watch(ctl, path,
- watch->mask) < 0)
- return -1;
- wtmp = LIST_FIRST(&ctl->watch);
- wtmp->parent_wd = watch->wd;
- }
-
- LIST_INSERT_HEAD(&dir->all, dptr, entries);
- }
- }
-
- return 0;
-}
-
-
-
-/**
- Handle an event inside a directory (kqueue version)
-*/
-static int
-kq_directory_event_handler(struct kevent kev,
- struct pnotify_cb * ctl,
- struct pnotify_watch * watch)
-{
- struct pnotify_event *ev;
- struct dentry *dptr, *dtmp;
-
- assert(ctl && watch);
-
- /* Re-scan the directory to find new and deleted files */
- if (directory_scan(ctl, watch) < 0) {
- warn("directory_scan failed");
- return -1;
- }
-
- /* Generate an event for each changed directory entry */
- LIST_FOREACH_SAFE(dptr, &watch->dir.all, entries, dtmp) {
-
- /* Skip files that have not changed */
- if (dptr->mask == 0)
- continue;
-
- /* Construct a pnotify_event structure */
- if ((ev = calloc(1, sizeof(*ev))) == NULL) {
- warn("malloc failed");
- return -1;
- }
- ev->wd = watch->wd;
- ev->mask = dptr->mask;
- (void) strlcpy(ev->name, dptr->ent.d_name, sizeof(ev->name));
- dprint_event(ev);
-
- /* Add the event to the list of pending events */
- STAILQ_INSERT_TAIL(&ctl->event, ev, entries);
-
- /* Remove the directory entry for a deleted file */
- if (dptr->mask & PN_DELETE) {
- LIST_REMOVE(dptr, entries);
- free(dptr);
- }
- }
-
- return 0;
-}
-#endif