diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-05-29 08:25:23 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-06-01 01:10:43 +0300 |
commit | 0dceaeba116b220c690ebef5880a38d521ce76a9 (patch) | |
tree | a9ce84750e31a1a12ce0af034732c15d5ce0f743 | |
parent | c3cc06dd839c99cacb365eb95d5b0b413990c67b (diff) | |
download | direvent-0dceaeba116b220c690ebef5880a38d521ce76a9.tar.gz direvent-0dceaeba116b220c690ebef5880a38d521ce76a9.tar.bz2 |
Make sure directory and filename parts are meaningful when calling the handler.
* dircond.h (dirwatcher) <split_p>: New member.
<file_mode>: Change type to mode_t.
(run_handler): Change signature.
(split_pathname,unsplit_pathname): New protos.
* ev_inotify.c (process_event): Use split_pathname
to obtain file and directory parts if the watched
object is not a directory.
* ev_kqueue.c (filename): Remove function.
(check_created): Change call to run_handler.
(process_event): Use split_pathname
to obtain file and directory parts.
* progman.c (run_handler): Change signature and
calling convention.
* watcher.c (watch_subdirs): Fix diagnostics message.
(split_pathname,unsplit_pathname): New functions.
-rw-r--r-- | dircond.c | 1 | ||||
-rw-r--r-- | dircond.h | 10 | ||||
-rw-r--r-- | ev_inotify.c | 16 | ||||
-rw-r--r-- | ev_kqueue.c | 20 | ||||
-rw-r--r-- | progman.c | 14 | ||||
-rw-r--r-- | watcher.c | 25 |
6 files changed, 60 insertions, 26 deletions
@@ -209,6 +209,7 @@ trans_tokfirst(struct transtab *tab, int tok, int *next) return trans_toknext(tab, tok, next); } + /* Command line processing and auxiliary functions */ static void @@ -70,8 +70,9 @@ struct dirwatcher { char *dirname; /* Pathname being watched */ struct handler *handler_list; /* Handlers */ int depth; + char *split_p; #if USE_IFACE == IFACE_KQUEUE - int file_mode; + mode_t file_mode; time_t file_ctime; #endif }; @@ -179,10 +180,13 @@ struct dirwatcher *dirwatcher_install(const char *path, int *pnew); void dirwatcher_destroy(struct dirwatcher *dwp); void watch_pathname(struct dirwatcher *parent, const char *dirname, int isdir); -int run_handler(struct dirwatcher *dp, struct handler *hp, event_mask *event, - const char *file); +char *split_pathname(struct dirwatcher *dp, char **dirname); +void unsplit_pathname(struct dirwatcher *dp); + void ev_log(int flags, struct dirwatcher *dp); struct process *process_lookup(pid_t pid); void process_cleanup(int expect_term); void process_timeouts(void); +int run_handler(struct handler *hp, event_mask *event, + const char *dir, const char *file); diff --git a/ev_inotify.c b/ev_inotify.c index 6181893..5cc919c 100644 --- a/ev_inotify.c +++ b/ev_inotify.c @@ -96,7 +96,8 @@ process_event(struct inotify_event *ep) struct dirwatcher *dp; struct handler *h; event_mask m; - + char *dirname, *filename; + dp = dirwatcher_lookup_wd(ep->wd); if (ep->mask & IN_IGNORED) return; @@ -128,12 +129,19 @@ process_event(struct inotify_event *ep) } ev_log(ep->mask, dp); - + + if (ep->len == 0) + filename = split_pathname(dp, &dirname); + else { + dirname = dp->dirname; + filename = ep->name; + } for (h = dp->handler_list; h; h = h->next) { if (h->ev_mask.sys_mask & ep->mask) - run_handler(dp, h, event_mask_init(&m, ep->mask), - ep->name); + run_handler(h, event_mask_init(&m, ep->mask), + dirname, filename); } + unsplit_pathname(dp); } int diff --git a/ev_kqueue.c b/ev_kqueue.c index 3031f0d..959e68b 100644 --- a/ev_kqueue.c +++ b/ev_kqueue.c @@ -126,14 +126,6 @@ chclosed_elim() chclosed = -1; } -static char const * -filename(struct dirwatcher *dp) -{ - if (!dp->parent) - return dp->dirname; - return dp->dirname + strlen(dp->parent->dirname) + 1; -} - static void check_created(struct dirwatcher *dp) { @@ -175,7 +167,8 @@ check_created(struct dirwatcher *dp) /* Deliver SIE_CREATE event */ for (h = dp->handler_list; h; h = h->next) { if (h->ev_mask.sie_mask & SIE_CREATE) - run_handler(dp, h, &m, ent->d_name); + run_handler(h, &m, + dp->dirname, ent->d_name); } } free(pathname); @@ -189,6 +182,7 @@ process_event(struct kevent *ep) struct dirwatcher *dp = ep->udata; struct handler *h; event_mask m; + char *filename, *dirname; if (!dp) { diag(LOG_NOTICE, "unrecognized event %x", ep->fflags); @@ -204,14 +198,16 @@ process_event(struct kevent *ep) return; } + filename = split_pathname(dp, &dirname); for (h = dp->handler_list; h; h = h->next) { if (h->ev_mask.sys_mask & ep->fflags) { - run_handler(dp->parent, h, + run_handler(h, event_mask_init(&m, ep->fflags), - filename(dp)); + dirname, filename); } } - + unsplit_pathname(dp); + if (ep->fflags & (NOTE_DELETE|NOTE_RENAME)) { debug(1, ("%s deleted", dp->dirname)); dirwatcher_destroy(dp); @@ -381,8 +381,8 @@ event_to_env(event_mask *event) } int -run_handler(struct dirwatcher *dp, struct handler *hp, event_mask *event, - const char *file) +run_handler(struct handler *hp, event_mask *event, + const char *dirname, const char *file) { pid_t pid; int redir_fd[2] = { -1, -1 }; @@ -393,11 +393,11 @@ run_handler(struct dirwatcher *dp, struct handler *hp, event_mask *event, return 0; if (access(hp->prog, X_OK)) { diag(LOG_ERR, "watchpoint %s: cannot execute %s: %s", - dp->dirname, hp->prog, strerror(errno)); + dirname, hp->prog, strerror(errno)); return 1; } - debug(1, ("starting %s, dir=%s, file=%s", hp->prog, dp->dirname, file)); + debug(1, ("starting %s, dir=%s, file=%s", hp->prog, dirname, file)); if (hp->flags & HF_STDERR) redir_fd[REDIR_ERR] = open_redirector(hp->prog, LOG_ERR, &redir_proc[REDIR_ERR]); @@ -425,9 +425,9 @@ run_handler(struct dirwatcher *dp, struct handler *hp, event_mask *event, if (switchpriv(hp)) _exit(127); - if (chdir(dp->dirname)) { + if (chdir(dirname)) { diag(LOG_CRIT, "cannot change to %s: %s", - dp->dirname, strerror(errno)); + dirname, strerror(errno)); _exit(127); } @@ -463,7 +463,7 @@ run_handler(struct dirwatcher *dp, struct handler *hp, event_mask *event, /* master */ debug(1, ("%s running; dir=%s, file=%s, pid=%lu", - hp->prog, dp->dirname, file, (unsigned long)pid)); + hp->prog, dirname, file, (unsigned long)pid)); p = register_process(PROC_HANDLER, pid, time(NULL), hp->timeout); @@ -405,4 +405,29 @@ dirwatcher_destroy(struct dirwatcher *dwp) dirwatcher_remove_wd(dwp->wd); dirwatcher_remove(dwp->dirname); } + +char * +split_pathname(struct dirwatcher *dp, char **dirname) +{ + char *p = strrchr(dp->dirname, '/'); + if (p) { + dp->split_p = p; + *p++ = 0; + *dirname = dp->dirname; + } else { + p = dp->dirname; + *dirname = "."; + } + return p; +} + +void +unsplit_pathname(struct dirwatcher *dp) +{ + if (dp->split_p) { + *dp->split_p = '/'; + dp->split_p = NULL; + } +} + |