aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2005-05-05 19:15:32 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-05 19:36:36 -0400
commitcd2ee4a30cc0775d8b54e5b958613361a7cacfec (patch)
treeedea72ea7d723a1c35675632850916d77084581b /arch/um/drivers
parentc578455a3eccf4dd7bd111e77129c301d6d67914 (diff)
[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>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/line.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d0f97127adf6..025d3be8aca4 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -462,12 +462,15 @@ out:
462 return err; 462 return err;
463} 463}
464 464
465static void unregister_winch(struct tty_struct *tty);
466
465void line_close(struct tty_struct *tty, struct file * filp) 467void line_close(struct tty_struct *tty, struct file * filp)
466{ 468{
467 struct line *line = tty->driver_data; 469 struct line *line = tty->driver_data;
468 470
469 /* XXX: I assume this should be called in process context, not with interrupt 471 /* XXX: I assume this should be called in process context, not with
470 * disabled!*/ 472 * interrupts disabled!
473 */
471 spin_lock_irq(&line->lock); 474 spin_lock_irq(&line->lock);
472 475
473 /* We ignore the error anyway! */ 476 /* We ignore the error anyway! */
@@ -478,6 +481,12 @@ void line_close(struct tty_struct *tty, struct file * filp)
478 line_disable(tty, -1); 481 line_disable(tty, -1);
479 tty->driver_data = NULL; 482 tty->driver_data = NULL;
480 } 483 }
484
485 if((line->count == 0) && line->sigio){
486 unregister_winch(tty);
487 line->sigio = 0;
488 }
489
481 spin_unlock_irq(&line->lock); 490 spin_unlock_irq(&line->lock);
482} 491}
483 492
@@ -729,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
729 up(&winch_handler_sem); 738 up(&winch_handler_sem);
730} 739}
731 740
741static void unregister_winch(struct tty_struct *tty)
742{
743 struct list_head *ele;
744 struct winch *winch, *found = NULL;
745
746 down(&winch_handler_sem);
747 list_for_each(ele, &winch_handlers){
748 winch = list_entry(ele, struct winch, list);
749 if(winch->tty == tty){
750 found = winch;
751 break;
752 }
753 }
754
755 if(found == NULL)
756 goto out;
757
758 if(winch->pid != -1)
759 os_kill_process(winch->pid, 1);
760
761 free_irq_by_irq_and_dev(WINCH_IRQ, winch);
762 free_irq(WINCH_IRQ, winch);
763 list_del(&winch->list);
764 kfree(winch);
765 out:
766 up(&winch_handler_sem);
767}
768
732static void winch_cleanup(void) 769static void winch_cleanup(void)
733{ 770{
734 struct list_head *ele; 771 struct list_head *ele;