summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBo Yang <boyang@samba.org>2010-02-09 17:02:20 +0800
committerKarolin Seeger <kseeger@samba.org>2010-05-06 14:08:34 +0200
commit2b12db6d7d4e88a014af145d68aff7721188d677 (patch)
tree163ac172e44129514e58a4c0dc61dcef3d3a1a3a /lib
parent50e838357dcbc160573e13ca3a61716caa129328 (diff)
downloadsamba-2b12db6d7d4e88a014af145d68aff7721188d677.tar.gz
s3: signals are processed twice in child.
Signed-off-by: Bo Yang <boyang@samba.org> (cherry picked from commit 8c8bb51de1ac2baa46ac0736fae12c034288e5d4) Fix bug #7206 (duplicate signal handler, signals are processed twice in child process). (cherry picked from commit e41d9e75084170fa41a9e313fa79bf351f879840)
Diffstat (limited to 'lib')
-rw-r--r--lib/tevent/tevent.c7
-rw-r--r--lib/tevent/tevent_internal.h1
-rw-r--r--lib/tevent/tevent_signal.c33
3 files changed, 36 insertions, 5 deletions
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 76a6ac1c97f..ae5fdbd08c8 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -176,6 +176,13 @@ int tevent_common_context_destructor(struct tevent_context *ev)
sn = se->next;
se->event_ctx = NULL;
DLIST_REMOVE(ev->signal_events, se);
+ /*
+ * This is important, Otherwise signals
+ * are handled twice in child. eg, SIGHUP.
+ * one added in parent, and another one in
+ * the child. -- BoYang
+ */
+ tevent_cleanup_pending_signal_handlers(se);
}
return 0;
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index aa7c34aa89b..0c15e35a738 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -299,6 +299,7 @@ struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
const char *handler_name,
const char *location);
int tevent_common_check_signal(struct tevent_context *ev);
+void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se);
bool tevent_standard_init(void);
bool tevent_select_init(void);
diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c
index ab170a66cf7..f3e22db287b 100644
--- a/lib/tevent/tevent_signal.c
+++ b/lib/tevent/tevent_signal.c
@@ -133,7 +133,9 @@ static void tevent_common_signal_handler_info(int signum, siginfo_t *info,
static int tevent_common_signal_list_destructor(struct tevent_common_signal_list *sl)
{
- DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl);
+ if (sig_state->sig_handlers[sl->se->signum]) {
+ DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl);
+ }
return 0;
}
@@ -154,12 +156,16 @@ static int tevent_signal_destructor(struct tevent_signal *se)
if (sig_state->sig_handlers[se->signum] == NULL) {
/* restore old handler, if any */
- sigaction(se->signum, sig_state->oldact[se->signum], NULL);
- sig_state->oldact[se->signum] = NULL;
+ if (sig_state->oldact[se->signum]) {
+ sigaction(se->signum, sig_state->oldact[se->signum], NULL);
+ sig_state->oldact[se->signum] = NULL;
+ }
#ifdef SA_SIGINFO
if (se->sa_flags & SA_SIGINFO) {
- talloc_free(sig_state->sig_info[se->signum]);
- sig_state->sig_info[se->signum] = NULL;
+ if (sig_state->sig_info[se->signum]) {
+ talloc_free(sig_state->sig_info[se->signum]);
+ sig_state->sig_info[se->signum] = NULL;
+ }
}
#endif
}
@@ -396,3 +402,20 @@ int tevent_common_check_signal(struct tevent_context *ev)
return 1;
}
+
+void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se)
+{
+ struct tevent_common_signal_list *sl;
+ sl = talloc_get_type(se->additional_data,
+ struct tevent_common_signal_list);
+
+ tevent_common_signal_list_destructor(sl);
+
+ if (sig_state->sig_handlers[se->signum] == NULL) {
+ if (sig_state->oldact[se->signum]) {
+ sigaction(se->signum, sig_state->oldact[se->signum], NULL);
+ sig_state->oldact[se->signum] = NULL;
+ }
+ }
+ return;
+}