diff options
-rw-r--r-- | sys/alpha/linux/linux.h | 8 | ||||
-rw-r--r-- | sys/alpha/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/compat/linux/linux_signal.c | 58 | ||||
-rw-r--r-- | sys/i386/linux/linux.h | 8 | ||||
-rw-r--r-- | sys/i386/linux/linux_dummy.c | 1 | ||||
-rw-r--r-- | sys/i386/linux/linux_proto.h | 5 | ||||
-rw-r--r-- | sys/i386/linux/linux_signal.c | 58 | ||||
-rw-r--r-- | sys/i386/linux/linux_syscall.h | 2 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysent.c | 4 |
9 files changed, 116 insertions, 29 deletions
diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h index 5499abd..d3ba6cc 100644 --- a/sys/alpha/linux/linux.h +++ b/sys/alpha/linux/linux.h @@ -48,6 +48,7 @@ typedef struct { } linux_fsid_t; typedef int linux_pid_t; typedef int linux_key_t; +typedef unsigned int linux_size_t; /* * Signal stuff... @@ -74,6 +75,13 @@ typedef struct { linux_sigset_t lsa_mask; } linux_sigaction_t; +typedef struct +{ + void *ss_sp; + int ss_flags; + linux_size_t ss_size; +} linux_stack_t; + /* * The Linux sigcontext, pretty much a standard 386 trapframe. */ diff --git a/sys/alpha/linux/linux_dummy.c b/sys/alpha/linux/linux_dummy.c index 518e781..b9335f4 100644 --- a/sys/alpha/linux/linux_dummy.c +++ b/sys/alpha/linux/linux_dummy.c @@ -104,7 +104,6 @@ DUMMY(pread); DUMMY(pwrite); DUMMY(capget); DUMMY(capset); -DUMMY(sigaltstack); DUMMY(sendfile); DUMMY(getpmsg); DUMMY(putpmsg); diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 39334a7..d47dd4f 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -123,7 +123,7 @@ static int linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, linux_sigaction_t *linux_osa) { - struct sigaction *nsa, *osa, sa; + struct sigaction *nsa, *osa; struct sigaction_args sa_args; int error; caddr_t sg = stackgap_init(); @@ -138,10 +138,7 @@ linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, if (linux_nsa != NULL) { nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - linux_to_bsd_sigaction(linux_nsa, &sa); - error = copyout(&sa, nsa, sizeof(struct sigaction)); - if (error) - return (error); + linux_to_bsd_sigaction(linux_nsa, nsa); } else nsa = NULL; @@ -157,12 +154,8 @@ linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, if (error) return (error); - if (linux_osa != NULL) { - error = copyin(osa, &sa, sizeof(struct sigaction)); - if (error) - return (error); - bsd_to_linux_sigaction(&sa, linux_osa); - } + if (linux_osa != NULL) + bsd_to_linux_sigaction(osa, linux_osa); return (0); } @@ -517,3 +510,46 @@ linux_kill(struct proc *p, struct linux_kill_args *args) tmp.pid = args->pid; return (kill(p, &tmp)); } + +int +linux_sigaltstack(p, uap) + struct proc *p; + struct linux_sigaltstack_args *uap; +{ + struct sigaltstack_args bsd; + stack_t *ss, *oss; + linux_stack_t lss; + int error; + caddr_t sg = stackgap_init(); + +#ifdef DEBUG + printf("Linux-emul(%ld): sigaltstack(%p, %p)\n", + (long)p->p_pid, args->uss, args->uoss); +#endif + + error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); + if (error) + return (error); + + ss = stackgap_alloc(&sg, sizeof(stack_t)); + ss->ss_sp = lss.ss_sp; + ss->ss_size = lss.ss_size; + ss->ss_flags = lss.ss_flags; + + oss = (uap->uoss != NULL) + ? stackgap_alloc(&sg, sizeof(stack_t)) + : NULL; + + bsd.ss = ss; + bsd.oss = oss; + error = sigaltstack(p, &bsd); + + if (!error && oss != NULL) { + lss.ss_sp = oss->ss_sp; + lss.ss_size = oss->ss_size; + lss.ss_flags = oss->ss_flags; + error = copyout(&lss, uap->uoss, sizeof(linux_stack_t)); + } + + return (error); +} diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 5499abd..d3ba6cc 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -48,6 +48,7 @@ typedef struct { } linux_fsid_t; typedef int linux_pid_t; typedef int linux_key_t; +typedef unsigned int linux_size_t; /* * Signal stuff... @@ -74,6 +75,13 @@ typedef struct { linux_sigset_t lsa_mask; } linux_sigaction_t; +typedef struct +{ + void *ss_sp; + int ss_flags; + linux_size_t ss_size; +} linux_stack_t; + /* * The Linux sigcontext, pretty much a standard 386 trapframe. */ diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index 518e781..b9335f4 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -104,7 +104,6 @@ DUMMY(pread); DUMMY(pwrite); DUMMY(capget); DUMMY(capset); -DUMMY(sigaltstack); DUMMY(sendfile); DUMMY(getpmsg); DUMMY(putpmsg); diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h index 0b2f86c..2753475 100644 --- a/sys/i386/linux/linux_proto.h +++ b/sys/i386/linux/linux_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.27 1999/11/27 16:50:54 marcel Exp + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.28 1999/11/30 15:00:17 marcel Exp */ #ifndef _LINUX_SYSPROTO_H_ @@ -505,7 +505,8 @@ struct linux_capset_args { register_t dummy; }; struct linux_sigaltstack_args { - register_t dummy; + const linux_stack_t * uss; char uss_[PAD_(const linux_stack_t *)]; + linux_stack_t * uoss; char uoss_[PAD_(linux_stack_t *)]; }; struct linux_sendfile_args { register_t dummy; diff --git a/sys/i386/linux/linux_signal.c b/sys/i386/linux/linux_signal.c index 39334a7..d47dd4f 100644 --- a/sys/i386/linux/linux_signal.c +++ b/sys/i386/linux/linux_signal.c @@ -123,7 +123,7 @@ static int linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, linux_sigaction_t *linux_osa) { - struct sigaction *nsa, *osa, sa; + struct sigaction *nsa, *osa; struct sigaction_args sa_args; int error; caddr_t sg = stackgap_init(); @@ -138,10 +138,7 @@ linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, if (linux_nsa != NULL) { nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - linux_to_bsd_sigaction(linux_nsa, &sa); - error = copyout(&sa, nsa, sizeof(struct sigaction)); - if (error) - return (error); + linux_to_bsd_sigaction(linux_nsa, nsa); } else nsa = NULL; @@ -157,12 +154,8 @@ linux_do_sigaction(struct proc *p, int linux_sig, linux_sigaction_t *linux_nsa, if (error) return (error); - if (linux_osa != NULL) { - error = copyin(osa, &sa, sizeof(struct sigaction)); - if (error) - return (error); - bsd_to_linux_sigaction(&sa, linux_osa); - } + if (linux_osa != NULL) + bsd_to_linux_sigaction(osa, linux_osa); return (0); } @@ -517,3 +510,46 @@ linux_kill(struct proc *p, struct linux_kill_args *args) tmp.pid = args->pid; return (kill(p, &tmp)); } + +int +linux_sigaltstack(p, uap) + struct proc *p; + struct linux_sigaltstack_args *uap; +{ + struct sigaltstack_args bsd; + stack_t *ss, *oss; + linux_stack_t lss; + int error; + caddr_t sg = stackgap_init(); + +#ifdef DEBUG + printf("Linux-emul(%ld): sigaltstack(%p, %p)\n", + (long)p->p_pid, args->uss, args->uoss); +#endif + + error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); + if (error) + return (error); + + ss = stackgap_alloc(&sg, sizeof(stack_t)); + ss->ss_sp = lss.ss_sp; + ss->ss_size = lss.ss_size; + ss->ss_flags = lss.ss_flags; + + oss = (uap->uoss != NULL) + ? stackgap_alloc(&sg, sizeof(stack_t)) + : NULL; + + bsd.ss = ss; + bsd.oss = oss; + error = sigaltstack(p, &bsd); + + if (!error && oss != NULL) { + lss.ss_sp = oss->ss_sp; + lss.ss_size = oss->ss_size; + lss.ss_flags = oss->ss_flags; + error = copyout(&lss, uap->uoss, sizeof(linux_stack_t)); + } + + return (error); +} diff --git a/sys/i386/linux/linux_syscall.h b/sys/i386/linux/linux_syscall.h index 4db0368..8ec782e 100644 --- a/sys/i386/linux/linux_syscall.h +++ b/sys/i386/linux/linux_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.27 1999/11/27 16:50:54 marcel Exp + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.28 1999/11/30 15:00:17 marcel Exp */ #define LINUX_SYS_linux_setup 0 diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c index fe014ac..465b42f 100644 --- a/sys/i386/linux/linux_sysent.c +++ b/sys/i386/linux/linux_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.27 1999/11/27 16:50:54 marcel Exp + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.28 1999/11/30 15:00:17 marcel Exp */ #include "opt_compat.h" @@ -201,7 +201,7 @@ struct sysent linux_sysent[] = { { 2, (sy_call_t *)linux_getcwd }, /* 183 = linux_getcwd */ { 0, (sy_call_t *)linux_capget }, /* 184 = linux_capget */ { 0, (sy_call_t *)linux_capset }, /* 185 = linux_capset */ - { 0, (sy_call_t *)linux_sigaltstack }, /* 186 = linux_sigaltstack */ + { 2, (sy_call_t *)linux_sigaltstack }, /* 186 = linux_sigaltstack */ { 0, (sy_call_t *)linux_sendfile }, /* 187 = linux_sendfile */ { 0, (sy_call_t *)linux_getpmsg }, /* 188 = linux_getpmsg */ { 0, (sy_call_t *)linux_putpmsg }, /* 189 = linux_putpmsg */ |