diff options
author | jdike <jdike> | 2003-03-26 20:28:05 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-03-26 20:28:05 +0000 |
commit | 180144c3992a88a8a4ab16bec2b2f9e1785071f0 (patch) | |
tree | c28240b0f5c110188ed714ffe784d76f353d343f | |
parent | aa3e2addefe9cca93dfe720042ffc953cc312268 (diff) | |
download | uml-history-180144c3992a88a8a4ab16bec2b2f9e1785071f0.tar.gz |
Added SIGWINCH support to skas mode.
-rw-r--r-- | arch/um/drivers/chan_user.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 29 | ||||
-rw-r--r-- | arch/um/include/kern_util.h | 1 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 12 | ||||
-rw-r--r-- | arch/um/kernel/skas/include/mode.h | 1 | ||||
-rw-r--r-- | arch/um/kernel/skas/process.c | 16 | ||||
-rw-r--r-- | arch/um/kernel/trap_kern.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/trap_user.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/tt/tracer.c | 2 |
9 files changed, 52 insertions, 21 deletions
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 714bace..e1e46e8 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -188,8 +188,8 @@ void register_winch(int fd, void *device_data) if(!isatty(fd)) return; pid = tcgetpgrp(fd); - if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && - (pid == -1)){ + if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, + device_data) && (pid == -1)){ thread = winch_tramp(fd, device_data, &thread_fd); if(fd != -1){ register_winch_irq(thread_fd, fd, thread, device_data); diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1cac81e..1421341 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -486,17 +486,18 @@ void winch_interrupt(int irq, void *data, struct pt_regs *unused) int err; char c; - err = generic_read(winch->fd, &c, NULL); - if(err < 0){ - if(err != -EAGAIN){ - printk("winch_interrupt : read failed, errno = %d\n", - -err); - printk("fd %d is losing SIGWINCH support\n", - winch->tty_fd); - free_irq(irq, data); - return; + if(winch->fd != -1){ + err = generic_read(winch->fd, &c, NULL); + if(err < 0){ + if(err != -EAGAIN){ + printk("winch_interrupt : read failed, " + "errno = %d\n", -err); + printk("fd %d is losing SIGWINCH support\n", + winch->tty_fd); + return; + } + goto out; } - goto out; } tty = winch->line->tty; if(tty != NULL){ @@ -506,7 +507,8 @@ void winch_interrupt(int irq, void *data, struct pt_regs *unused) kill_pg(tty->pgrp, SIGWINCH, 1); } out: - reactivate_fd(winch->fd, WINCH_IRQ); + if(winch->fd != -1) + reactivate_fd(winch->fd, WINCH_IRQ); } DECLARE_MUTEX(winch_handler_sem); @@ -543,7 +545,10 @@ static void winch_cleanup(void) list_for_each(ele, &winch_handlers){ winch = list_entry(ele, struct winch, list); - close(winch->fd); + if(winch->fd != -1){ + deactivate_fd(winch->fd, WINCH_IRQ); + close(winch->fd); + } if(winch->pid != -1) os_kill_process(winch->pid, 1); } diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index b895293..3ba5db8 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -97,6 +97,7 @@ extern int clear_user_proc(void *buf, int size); extern int copy_to_user_proc(void *to, void *from, int size); extern int copy_from_user_proc(void *to, void *from, int size); extern void bus_handler(int sig, union uml_pt_regs *regs); +extern void winch(int sig, union uml_pt_regs *regs); extern long execute_syscall(void *r); extern int smp_sigio_handler(void); extern void *get_current(void); diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 037cbcf..6791d1f 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -423,11 +423,15 @@ int um_request_irq(unsigned int irq, int fd, int type, unsigned long irqflags, const char * devname, void *dev_id) { - int retval; + int err; + + err = request_irq(irq, handler, irqflags, devname, dev_id); + if(err) + return(err); - retval = request_irq(irq, handler, irqflags, devname, dev_id); - if(retval) return(retval); - return(activate_fd(irq, fd, type, dev_id)); + if(fd != -1) + err = activate_fd(irq, fd, type, dev_id); + return(err); } /* this was setup_x86_irq but it seems pretty generic */ diff --git a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h index 7516206..99563cd 100644 --- a/arch/um/kernel/skas/include/mode.h +++ b/arch/um/kernel/skas/include/mode.h @@ -20,6 +20,7 @@ extern void sig_handler_common_skas(int sig, void *sc_ptr); extern void halt_skas(void); extern void reboot_skas(void); extern void kill_off_processes_skas(void); +extern int is_skas_winch(int pid, int fd, void *data); #endif diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index cb91f8c..9e279ee 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -4,6 +4,7 @@ */ #include <stdlib.h> +#include <unistd.h> #include <errno.h> #include <signal.h> #include <setjmp.h> @@ -24,6 +25,16 @@ #include "os.h" #include "proc_mm.h" #include "skas_ptrace.h" +#include "chan_user.h" + +int is_skas_winch(int pid, int fd, void *data) +{ + if(pid != getpid()) + return(0); + + register_winch_irq(-1, fd, -1, data); + return(1); +} unsigned long exec_regs[FRAME_SIZE]; unsigned long exec_fp_regs[HOST_FP_SIZE]; @@ -72,8 +83,6 @@ static void handle_trap(int pid, union uml_pt_regs *regs) handle_syscall(regs); } -int userspace_pid; - static int userspace_tramp(void *arg) { init_new_thread_signals(0); @@ -83,6 +92,8 @@ static int userspace_tramp(void *arg) return(0); } +int userspace_pid; + void start_userspace(void) { void *stack; @@ -149,6 +160,7 @@ void userspace(union uml_pt_regs *regs) case SIGILL: case SIGBUS: case SIGFPE: + case SIGWINCH: user_signal(WSTOPSIG(status), regs); break; default: diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 6bc8088..187456b 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -14,6 +14,7 @@ #include "asm/pgalloc.h" #include "asm/a.out.h" #include "asm/current.h" +#include "asm/irq.h" #include "user_util.h" #include "kern_util.h" #include "kern.h" @@ -154,6 +155,11 @@ void bus_handler(int sig, union uml_pt_regs *regs) else relay_signal(sig, regs); } +void winch(int sig, union uml_pt_regs *regs) +{ + do_IRQ(WINCH_IRQ, regs); +} + void trap_init(void) { } diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c index 63812e5..93d4e61 100644 --- a/arch/um/kernel/trap_user.c +++ b/arch/um/kernel/trap_user.c @@ -82,6 +82,8 @@ struct signal_info sig_info[] = { .is_irq = 0 }, [ SIGILL ] { .handler = relay_signal, .is_irq = 0 }, + [ SIGWINCH ] { .handler = winch, + .is_irq = 1 }, [ SIGBUS ] { .handler = bus_handler, .is_irq = 0 }, [ SIGSEGV] { .handler = segv_handler, diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 70989f0..51502e1 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -39,7 +39,7 @@ int is_tracer_winch(int pid, int fd, void *data) return(0); register_winch_irq(tracer_winch[0], fd, -1, data); - return(0); + return(1); } static void tracer_winch_handler(int sig) |