diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-08-20 12:24:41 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-08-25 22:29:47 +0300 |
commit | 46ae038f21a0bb8b8cfe5361df6439cf572ad2cc (patch) | |
tree | eaf78744a9e023fc8e1baadd8d5fff7f4f664cc3 | |
parent | 4e4bacb23013880c5247ed53e81366f15d2a64ef (diff) | |
download | direvent-46ae038f21a0bb8b8cfe5361df6439cf572ad2cc.tar.gz direvent-46ae038f21a0bb8b8cfe5361df6439cf572ad2cc.tar.bz2 |
Initial preparation for having distinct handler types.
* src/direvent.h (pattern_type): New enum, instead of
PAT_* defines.
(filename_pattern): use enum pattern_type.
(handler_type): New enum.
(handler): Can be of two types: HANDLER_EXTERN, which handles
external programs and is equivalent to the prior content of
the structure, and HANDLER_SENTINEL, which is planned to be
a built-in handler for configuring watchpoints for newly created
directories. All uses changed.
(dirwatcher) <refcnt>: Change type to size_t.
(handler_alloc,handler_add_pattern)
(handler_add_exact_filename): New protos.
* src/hashtab.c: Provisions for safe adding and removing
from the hashtable when iterating over it.
(hashtab) <flags>: Removed.
<itr_level, list_new, list_del>: New members.
(hashtab_remove): When iterating, place pointer to the removed
entry in list_del instead of actually removing it.
(hashtab_lookup_or_install): When iterating, add a pointer to
the newly created entry to the list_new list, instead of adding
it immediately.
(hashtab_foreach): Flush list_del and list_new at the end of
the topmost iteration.
* src/config.c (handler_alloc): Rename to handler_copy
(handler_alloc): New function.
(handler_free): Two types of handlers.
(handler_add_pattern)
(handler_add_exact_filename): New functions.
(file_name_pattern): Takes struct handler * as its
first argument.
(cb_file_pattern): Change accordingly.
* src/fnpat.c (filename_pattern_free): Handle PAT_EXACT.
(filename_pattern_match): Likewise.
* src/progman.c (run_handler): Two types of handlers.
* src/watcher.c (dirwatcher_install): Restore missing gettext
marker.
Allocate handler_list.
(dirwatcher_init): Convert non-directory watchpoints to directory
ones.
-rw-r--r-- | src/config.c | 127 | ||||
-rw-r--r-- | src/direvent.h | 58 | ||||
-rw-r--r-- | src/fnpat.c | 4 | ||||
-rw-r--r-- | src/hashtab.c | 124 | ||||
-rw-r--r-- | src/progman.c | 74 | ||||
-rw-r--r-- | src/watcher.c | 89 |
6 files changed, 378 insertions, 98 deletions
diff --git a/src/config.c b/src/config.c index e98dc0f..3a4878c 100644 --- a/src/config.c +++ b/src/config.c | |||
@@ -146,8 +146,17 @@ static struct grecs_keyword syslog_kw[] = { | |||
146 | { NULL }, | 146 | { NULL }, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | struct handler * | ||
150 | handler_alloc(enum handler_type type) | ||
151 | { | ||
152 | struct handler *hp = ecalloc(1, sizeof(*hp)); | ||
153 | hp->type = type; | ||
154 | hp->refcnt = 0; | ||
155 | return hp; | ||
156 | } | ||
157 | |||
149 | static struct handler * | 158 | static struct handler * |
150 | handler_alloc(struct handler *orig) | 159 | handler_copy(struct handler *orig) |
151 | { | 160 | { |
152 | struct handler *hp = emalloc(sizeof(*hp)); | 161 | struct handler *hp = emalloc(sizeof(*hp)); |
153 | *hp = *orig; | 162 | *hp = *orig; |
@@ -183,15 +192,15 @@ handler_envrealloc(struct handler *hp, size_t count) | |||
183 | { | 192 | { |
184 | size_t i; | 193 | size_t i; |
185 | 194 | ||
186 | if (!hp->env) { | 195 | if (!hp->prog_env) { |
187 | hp->env = ecalloc(count + 1, sizeof(hp->env[0])); | 196 | hp->prog_env = ecalloc(count + 1, sizeof(hp->prog_env[0])); |
188 | i = 0; | 197 | i = 0; |
189 | } else { | 198 | } else { |
190 | for (i = 0; hp->env[i]; i++) | 199 | for (i = 0; hp->prog_env[i]; i++) |
191 | ; | 200 | ; |
192 | hp->env = erealloc(hp->env, | 201 | hp->prog_env = erealloc(hp->prog_env, |
193 | (i + count + 1) * sizeof(hp->env[0])); | 202 | (i + count + 1) * sizeof(hp->prog_env[0])); |
194 | memset(hp->env + i, 0, (count + 1) * sizeof(hp->env[0])); | 203 | memset(hp->prog_env + i, 0, (count + 1) * sizeof(hp->prog_env[0])); |
195 | } | 204 | } |
196 | return i; | 205 | return i; |
197 | } | 206 | } |
@@ -200,9 +209,15 @@ static void | |||
200 | handler_free(struct handler *hp) | 209 | handler_free(struct handler *hp) |
201 | { | 210 | { |
202 | grecs_list_free(hp->fnames); | 211 | grecs_list_free(hp->fnames); |
203 | free(hp->prog); | 212 | switch (hp->type) { |
204 | free(hp->gidv); | 213 | case HANDLER_EXTERN: |
205 | envfree(hp->env); | 214 | free(hp->prog_command); |
215 | free(hp->prog_gidv); | ||
216 | envfree(hp->prog_env); | ||
217 | break; | ||
218 | case HANDLER_SENTINEL: | ||
219 | dirwatcher_unref(hp->sentinel_watcher); | ||
220 | } | ||
206 | } | 221 | } |
207 | 222 | ||
208 | static void | 223 | static void |
@@ -290,7 +305,6 @@ direvent_handler_list_append(direvent_handler_list_t hlist, struct handler *hp) | |||
290 | grecs_list_append(hlist->list, hp); | 305 | grecs_list_append(hlist->list, hp); |
291 | } | 306 | } |
292 | 307 | ||
293 | |||
294 | struct eventconf { | 308 | struct eventconf { |
295 | struct grecs_list *pathlist; | 309 | struct grecs_list *pathlist; |
296 | struct handler handler; | 310 | struct handler handler; |
@@ -301,8 +315,9 @@ static struct eventconf eventconf; | |||
301 | static void | 315 | static void |
302 | eventconf_init(void) | 316 | eventconf_init(void) |
303 | { | 317 | { |
304 | memset(&eventconf, 0, sizeof eventconf); | 318 | memset(&eventconf, 0, sizeof eventconf); |
305 | eventconf.handler.timeout = DEFAULT_TIMEOUT; | 319 | eventconf.handler.type = HANDLER_EXTERN; |
320 | eventconf.handler.prog_timeout = DEFAULT_TIMEOUT; | ||
306 | } | 321 | } |
307 | 322 | ||
308 | static void | 323 | static void |
@@ -316,7 +331,7 @@ void | |||
316 | eventconf_flush(grecs_locus_t *loc) | 331 | eventconf_flush(grecs_locus_t *loc) |
317 | { | 332 | { |
318 | struct grecs_list_entry *ep; | 333 | struct grecs_list_entry *ep; |
319 | struct handler *hp = handler_alloc(&eventconf.handler); | 334 | struct handler *hp = handler_copy(&eventconf.handler); |
320 | 335 | ||
321 | for (ep = eventconf.pathlist->head; ep; ep = ep->next) { | 336 | for (ep = eventconf.pathlist->head; ep; ep = ep->next) { |
322 | struct pathent *pe = ep->data; | 337 | struct pathent *pe = ep->data; |
@@ -331,8 +346,6 @@ eventconf_flush(grecs_locus_t *loc) | |||
331 | _("%s: recursion depth does not match previous definition"), | 346 | _("%s: recursion depth does not match previous definition"), |
332 | pe->path); | 347 | pe->path); |
333 | dwp->depth = pe->depth; | 348 | dwp->depth = pe->depth; |
334 | if (!dwp->handler_list) | ||
335 | dwp->handler_list = direvent_handler_list_create(); | ||
336 | direvent_handler_list_append(dwp->handler_list, hp); | 349 | direvent_handler_list_append(dwp->handler_list, hp); |
337 | } | 350 | } |
338 | grecs_list_free(eventconf.pathlist); | 351 | grecs_list_free(eventconf.pathlist); |
@@ -354,7 +367,7 @@ cb_watcher(enum grecs_callback_command cmd, grecs_node_t *node, | |||
354 | grecs_error(&node->locus, 0, _("no paths configured")); | 367 | grecs_error(&node->locus, 0, _("no paths configured")); |
355 | ++err; | 368 | ++err; |
356 | } | 369 | } |
357 | if (!eventconf.handler.prog) { | 370 | if (!eventconf.handler.prog_command) { |
358 | grecs_error(&node->locus, 0, | 371 | grecs_error(&node->locus, 0, |
359 | _("no command configured")); | 372 | _("no command configured")); |
360 | ++err; | 373 | ++err; |
@@ -605,9 +618,9 @@ cb_user(enum grecs_callback_command cmd, grecs_node_t *node, | |||
605 | } else | 618 | } else |
606 | gid = pw->pw_gid; | 619 | gid = pw->pw_gid; |
607 | 620 | ||
608 | eventconf.handler.uid = pw->pw_uid; | 621 | eventconf.handler.prog_uid = pw->pw_uid; |
609 | get_user_groups(uv->v.string, gid, | 622 | get_user_groups(uv->v.string, gid, |
610 | &eventconf.handler.gidc, &eventconf.handler.gidv); | 623 | &eventconf.handler.prog_gidc, &eventconf.handler.prog_gidv); |
611 | 624 | ||
612 | return 0; | 625 | return 0; |
613 | } | 626 | } |
@@ -630,15 +643,15 @@ cb_option(enum grecs_callback_command cmd, grecs_node_t *node, | |||
630 | GRECS_TYPE_STRING)) | 643 | GRECS_TYPE_STRING)) |
631 | return 1; | 644 | return 1; |
632 | if (strcmp(vp->v.string, "nowait") == 0) | 645 | if (strcmp(vp->v.string, "nowait") == 0) |
633 | eventconf.handler.flags |= HF_NOWAIT; | 646 | eventconf.handler.prog_flags |= HF_NOWAIT; |
634 | else if (strcmp(vp->v.string, "wait") == 0) | 647 | else if (strcmp(vp->v.string, "wait") == 0) |
635 | eventconf.handler.flags &= ~HF_NOWAIT; | 648 | eventconf.handler.prog_flags &= ~HF_NOWAIT; |
636 | else if (strcmp(vp->v.string, "stdout") == 0) | 649 | else if (strcmp(vp->v.string, "stdout") == 0) |
637 | eventconf.handler.flags |= HF_STDOUT; | 650 | eventconf.handler.prog_flags |= HF_STDOUT; |
638 | else if (strcmp(vp->v.string, "stderr") == 0) | 651 | else if (strcmp(vp->v.string, "stderr") == 0) |
639 | eventconf.handler.flags |= HF_STDERR; | 652 | eventconf.handler.prog_flags |= HF_STDERR; |
640 | else if (strcmp(vp->v.string, "shell") == 0) | 653 | else if (strcmp(vp->v.string, "shell") == 0) |
641 | eventconf.handler.flags |= HF_SHELL; | 654 | eventconf.handler.prog_flags |= HF_SHELL; |
642 | else | 655 | else |
643 | grecs_error(&vp->locus, 0, _("unrecognized option")); | 656 | grecs_error(&vp->locus, 0, _("unrecognized option")); |
644 | } | 657 | } |
@@ -661,8 +674,8 @@ cb_environ(enum grecs_callback_command cmd, grecs_node_t *node, | |||
661 | GRECS_TYPE_STRING)) | 674 | GRECS_TYPE_STRING)) |
662 | return 1; | 675 | return 1; |
663 | i = handler_envrealloc(&eventconf.handler, 1); | 676 | i = handler_envrealloc(&eventconf.handler, 1); |
664 | eventconf.handler.env[i] = estrdup(val->v.string); | 677 | eventconf.handler.prog_env[i] = estrdup(val->v.string); |
665 | eventconf.handler.env[i+1] = NULL; | 678 | eventconf.handler.prog_env[i+1] = NULL; |
666 | break; | 679 | break; |
667 | 680 | ||
668 | case GRECS_TYPE_ARRAY: | 681 | case GRECS_TYPE_ARRAY: |
@@ -672,9 +685,9 @@ cb_environ(enum grecs_callback_command cmd, grecs_node_t *node, | |||
672 | val->v.arg.v[i], | 685 | val->v.arg.v[i], |
673 | GRECS_TYPE_STRING)) | 686 | GRECS_TYPE_STRING)) |
674 | return 1; | 687 | return 1; |
675 | eventconf.handler.env[j] = estrdup(val->v.arg.v[i]->v.string); | 688 | eventconf.handler.prog_env[j] = estrdup(val->v.arg.v[i]->v.string); |
676 | } | 689 | } |
677 | eventconf.handler.env[j] = NULL; | 690 | eventconf.handler.prog_env[j] = NULL; |
678 | break; | 691 | break; |
679 | 692 | ||
680 | case GRECS_TYPE_LIST: | 693 | case GRECS_TYPE_LIST: |
@@ -684,15 +697,42 @@ cb_environ(enum grecs_callback_command cmd, grecs_node_t *node, | |||
684 | if (assert_grecs_value_type(&vp->locus, vp, | 697 | if (assert_grecs_value_type(&vp->locus, vp, |
685 | GRECS_TYPE_STRING)) | 698 | GRECS_TYPE_STRING)) |
686 | return 1; | 699 | return 1; |
687 | eventconf.handler.env[j] = estrdup(vp->v.string); | 700 | eventconf.handler.prog_env[j] = estrdup(vp->v.string); |
688 | } | 701 | } |
689 | eventconf.handler.env[j] = NULL; | 702 | eventconf.handler.prog_env[j] = NULL; |
690 | } | 703 | } |
691 | return 0; | 704 | return 0; |
692 | } | 705 | } |
693 | 706 | ||
707 | void | ||
708 | handler_add_pattern(struct handler *hp, struct filename_pattern *pat) | ||
709 | { | ||
710 | if (!hp->fnames) { | ||
711 | hp->fnames = grecs_list_create(); | ||
712 | hp->fnames->free_entry = filename_pattern_free; | ||
713 | } | ||
714 | grecs_list_append(hp->fnames, pat); | ||
715 | } | ||
716 | |||