aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-29 08:25:23 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-06-01 01:10:43 +0300
commit0dceaeba116b220c690ebef5880a38d521ce76a9 (patch)
treea9ce84750e31a1a12ce0af034732c15d5ce0f743
parentc3cc06dd839c99cacb365eb95d5b0b413990c67b (diff)
downloaddirevent-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.c1
-rw-r--r--dircond.h10
-rw-r--r--ev_inotify.c16
-rw-r--r--ev_kqueue.c20
-rw-r--r--progman.c14
-rw-r--r--watcher.c25
6 files changed, 60 insertions, 26 deletions
diff --git a/dircond.c b/dircond.c
index c2c1235..471e0a7 100644
--- a/dircond.c
+++ b/dircond.c
@@ -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
diff --git a/dircond.h b/dircond.h
index 1f89a0a..e17d64b 100644
--- a/dircond.h
+++ b/dircond.h
@@ -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);
diff --git a/progman.c b/progman.c
index e785d57..1dc648e 100644
--- a/progman.c
+++ b/progman.c
@@ -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);
diff --git a/watcher.c b/watcher.c
index 1bc070a..724f940 100644
--- a/watcher.c
+++ b/watcher.c
@@ -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;
+ }
+}
+

Return to:

Send suggestions and report system problems to the System administrator.