[PATCH] uml: Fix SIGWINCH relaying

This makes SIGWINCH work again, and fixes a couple of SIGWINCH-associated
crashes.  First, the sigio thread disables SIGWINCH because all hell breaks
loose if it ever gets one and tries to call the signal handling code.  Second,
there was a problem with deferencing tty structs after they were freed.  The
SIGWINCH support for a tty wasn't being turned off or freed after the tty went
away.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d71e8f0..d44fb52 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -163,7 +163,6 @@
 		irq_desc[i].handler = &SIGIO_irq_type;
 		enable_irq(i);
 	}
-	init_irq_signals(0);
 }
 
 /*
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index f76a269..51f8e5a 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -65,8 +65,6 @@
 		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
 	set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
 		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
-	set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
-		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
 	set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
 		    flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
 	signal(SIGHUP, SIG_IGN);
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 668df13..e892189 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -182,6 +182,7 @@
 	int i, n, respond_fd;
 	char c;
 
+        signal(SIGWINCH, SIG_IGN);
 	fds = &current_poll;
 	while(1){
 		n = poll(fds->poll, fds->used, -1);
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index c0b3051..4dc13bc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -28,10 +28,11 @@
 #include "chan_user.h"
 #include "signal_user.h"
 #include "registers.h"
+#include "process.h"
 
 int is_skas_winch(int pid, int fd, void *data)
 {
-	if(pid != os_getpid())
+        if(pid != os_getpgrp())
 		return(0);
 
 	register_winch_irq(-1, fd, -1, data);
@@ -259,6 +260,10 @@
 	sigjmp_buf **switch_buf = switch_buf_ptr;
 	int n;
 
+	set_handler(SIGWINCH, (__sighandler_t) sig_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
+		    SIGVTALRM, -1);
+
 	*fork_buf_ptr = &initial_jmpbuf;
 	n = sigsetjmp(initial_jmpbuf, 1);
 	if(n == 0)
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index f7b1753..d11e739 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -26,6 +26,7 @@
 #include "kern_util.h"
 #include "chan_user.h"
 #include "ptrace_user.h"
+#include "irq_user.h"
 #include "mode.h"
 #include "tt.h"
 
@@ -33,7 +34,7 @@
 
 int is_tracer_winch(int pid, int fd, void *data)
 {
-	if(pid != tracing_pid)
+	if(pid != os_getpgrp())
 		return(0);
 
 	register_winch_irq(tracer_winch[0], fd, -1, data);
@@ -119,6 +120,7 @@
 	signal(SIGSEGV, (__sighandler_t) sig_handler);
 	set_cmdline("(idle thread)");
 	set_init_pid(os_getpid());
+	init_irq_signals(0);
 	proc = arg;
 	return((*proc)(NULL));
 }