lkml.org 
[lkml]   [2003]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: another subtle signals issue

Btw, Roland, instead of your previous patch I would prefer something that
just makes "sig_ignored()" test the state of the signal better. Ie
something like the appended.

This should bring it much closer to the old code, which got this _right_.
For example, a signal that is blocked is _never_ ignored, since even if
the handler is SIG_IGN right now, it may not be by the time it is
unblocked.

I bet the blocked case accounts for some of the new test failures, while
the (SIG_DFL && sig_kernel_ignore(sig)) case will account for a few more.
In general I _think_ this should get us pretty much back to the old
behaviour.

At least this fixes the pipe write() / SIGWINCH testcase for me.

Linus

---
===== kernel/signal.c 1.69 vs edited =====
--- 1.69/kernel/signal.c Tue Feb 11 17:33:52 2003
+++ edited/kernel/signal.c Wed Feb 12 12:03:28 2003
@@ -141,14 +141,34 @@
(((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \
((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))

-#define sig_ignored(t, signr) \
- (!((t)->ptrace & PT_PTRACED) && \
- (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_IGN)
-
#define sig_fatal(t, signr) \
(!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
(t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)

+static inline int sig_ignored(struct task_struct *t, int sig)
+{
+ void * handler;
+
+ /*
+ * Tracers always want to know about signals..
+ */
+ if (t->ptrace & PT_PTRACED)
+ return 0;
+
+ /*
+ * Blocked signals are never ignored, since the
+ * signal handler may change by the time it is
+ * unblocked.
+ */
+ if (sigismember(&t->blocked, sig))
+ return 0;
+
+ /* Is it explicitly or implicitly ignored? */
+ handler = t->sighand->action[sig-1].sa.sa_handler;
+ return handler == SIG_IGN ||
+ (handler == SIG_DFL && sig_kernel_ignore(sig));
+}
+
/*
* Re-calculate pending state from the set of locally pending
* signals, globally pending signals, and blocked signals.
@@ -642,7 +662,7 @@
* TIF_SIGPENDING
*/
state = TASK_STOPPED;
- if (!sigismember(&t->blocked, SIGCONT)) {
+ if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) {
set_tsk_thread_flag(t, TIF_SIGPENDING);
state |= TASK_INTERRUPTIBLE;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:33    [W:0.069 / U:0.100 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site