diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h index e55a3671c70..f581314412f 100644 --- a/sys/alpha/linux/linux.h +++ b/sys/alpha/linux/linux.h @@ -47,35 +47,32 @@ typedef struct { long val[2]; } linux_fsid_t; typedef int linux_pid_t; -typedef unsigned long linux_sigset_t; -typedef void (*linux_handler_t)(int); -typedef struct { - void (*lsa_handler)(int); - linux_sigset_t lsa_mask; - unsigned long lsa_flags; - void (*lsa_restorer)(void); -} linux_sigaction_t; typedef int linux_key_t; -typedef struct { - unsigned long sig[2]; -} linux_new_sigset_t; -typedef struct { - void (*lsa_handler)(int); - unsigned long lsa_flags; - void (*lsa_restorer)(void); - linux_new_sigset_t lsa_mask; -} linux_new_sigaction_t; +/* + * Signal stuff... + */ +typedef void (*linux_handler_t)(int); -#define LINUX_MAX_UTSNAME 65 -struct linux_new_utsname { - char sysname[LINUX_MAX_UTSNAME]; - char nodename[LINUX_MAX_UTSNAME]; - char release[LINUX_MAX_UTSNAME]; - char version[LINUX_MAX_UTSNAME]; - char machine[LINUX_MAX_UTSNAME]; - char domainname[LINUX_MAX_UTSNAME]; -}; +typedef unsigned long linux_osigset_t; + +typedef struct { + unsigned int __bits[2]; +} linux_sigset_t; + +typedef struct { + void (*lsa_handler)(int); + linux_osigset_t lsa_mask; + unsigned long lsa_flags; + void (*lsa_restorer)(void); +} linux_osigaction_t; + +typedef struct { + void (*lsa_handler)(int); + unsigned long lsa_flags; + void (*lsa_restorer)(void); + linux_sigset_t lsa_mask; +} linux_sigaction_t; /* * The Linux sigcontext, pretty much a standard 386 trapframe. @@ -121,20 +118,6 @@ struct linux_sigframe { extern int bsd_to_linux_signal[]; extern int linux_to_bsd_signal[]; -extern char linux_sigcode[]; -extern int linux_szsigcode; -extern const char linux_emul_path[]; - -extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; -extern struct sysentvec linux_sysvec; -extern struct sysentvec elf_linux_sysvec; - -/* dummy struct definitions */ -struct image_params; -struct trapframe; - -/* misc defines */ -#define LINUX_NAME_MAX 255 /* signal numbers */ #define LINUX_SIGHUP 1 @@ -170,7 +153,8 @@ struct trapframe; #define LINUX_SIGPOLL LINUX_SIGIO #define LINUX_SIGPWR 30 #define LINUX_SIGUNUSED 31 -#define LINUX_NSIG 32 +#define LINUX_NSIG 64 +#define LINUX_SIGTBLSZ 31 /* sigaction flags */ #define LINUX_SA_NOCLDSTOP 0x00000001 @@ -188,6 +172,35 @@ struct trapframe; #define LINUX_SIG_UNBLOCK 1 #define LINUX_SIG_SETMASK 2 +#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0 +#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig) +#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) + +extern char linux_sigcode[]; +extern int linux_szsigcode; +extern const char linux_emul_path[]; + +extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; +extern struct sysentvec linux_sysvec; +extern struct sysentvec elf_linux_sysvec; + +/* dummy struct definitions */ +struct image_params; +struct trapframe; + +#define LINUX_MAX_UTSNAME 65 +struct linux_new_utsname { + char sysname[LINUX_MAX_UTSNAME]; + char nodename[LINUX_MAX_UTSNAME]; + char release[LINUX_MAX_UTSNAME]; + char version[LINUX_MAX_UTSNAME]; + char machine[LINUX_MAX_UTSNAME]; + char domainname[LINUX_MAX_UTSNAME]; +}; + +/* misc defines */ +#define LINUX_NAME_MAX 255 + /* resource limits */ #define LINUX_RLIMIT_CPU 0 #define LINUX_RLIMIT_FSIZE 1 diff --git a/sys/alpha/linux/linux_dummy.c b/sys/alpha/linux/linux_dummy.c index 018446d1619..04c3b4a84d5 100644 --- a/sys/alpha/linux/linux_dummy.c +++ b/sys/alpha/linux/linux_dummy.c @@ -102,7 +102,6 @@ DUMMY(rt_sigreturn); DUMMY(rt_sigpending); DUMMY(rt_sigtimedwait); DUMMY(rt_sigqueueinfo); -DUMMY(rt_sigsuspend); DUMMY(pread); DUMMY(pwrite); DUMMY(capget); diff --git a/sys/alpha/linux/linux_sysvec.c b/sys/alpha/linux/linux_sysvec.c index 871ccfbed4c..ecaa359388b 100644 --- a/sys/alpha/linux/linux_sysvec.c +++ b/sys/alpha/linux/linux_sysvec.c @@ -64,7 +64,7 @@ static int elf_linux_fixup __P((long **stack_base, struct image_params *iparams)); static void linux_prepsyscall __P((struct trapframe *tf, int *args, u_int *code, caddr_t *params)); -static void linux_sendsig __P((sig_t catcher, int sig, int mask, +static void linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask, u_long code)); /* @@ -82,22 +82,26 @@ static int bsd_to_linux_errno[ELAST + 1] = { -6, -6, -43, -42, -75, -6, -84 }; -int bsd_to_linux_signal[NSIG] = { - 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, - LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0, - LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, - 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, - LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, - LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, - LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, - LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2 +int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { + LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, + LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, + LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0, + LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, + LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, + LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, + LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, + 0, LINUX_SIGUSR1, LINUX_SIGUSR2 }; -int linux_to_bsd_signal[LINUX_NSIG] = { - 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, - SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, - SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, - SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGURG, 0 +int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { + SIGHUP, SIGINT, SIGQUIT, SIGILL, + SIGTRAP, SIGABRT, SIGBUS, SIGFPE, + SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, + SIGPIPE, SIGALRM, SIGTERM, SIGBUS, + SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, + SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, + SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, + SIGIO, SIGURG, 0 }; /* @@ -185,7 +189,7 @@ extern int _ucodesel, _udatasel; */ static void -linux_sendsig(sig_t catcher, int sig, int mask, u_long code) +linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) { register struct proc *p = curproc; register struct trapframe *regs; @@ -197,14 +201,14 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; #ifdef DEBUG - printf("Linux-emul(%ld): linux_sendsig(%p, %d, %d, %lu)\n", - (long)p->p_pid, catcher, sig, mask, code); + printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n", + (long)p->p_pid, catcher, sig, (void*)mask, code); #endif /* * Allocate space for the signal handler context. */ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { + SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe)); psp->ps_sigstk.ss_flags |= SS_ONSTACK; @@ -224,10 +228,9 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) * instruction to halt it in its tracks. */ SIGACTION(p, SIGILL) = SIG_DFL; - sig = sigmask(SIGILL); - p->p_sigignore &= ~sig; - p->p_sigcatch &= ~sig; - p->p_sigmask &= ~sig; + SIGDELSET(p->p_sigignore, SIGILL); + SIGDELSET(p->p_sigcatch, SIGILL); + SIGDELSET(p->p_sigmask, SIGILL); psignal(p, SIGILL); return; } @@ -235,12 +238,9 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) { - if (sig < p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[sig]; - else - sig = p->p_sysent->sv_sigsize + 1; - } + if (p->p_sysent->sv_sigtbl) + if (sig <= p->p_sysent->sv_sigsize) + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; frame.sf_handler = catcher; frame.sf_sig = sig; @@ -248,7 +248,7 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) /* * Build the signal context to be used by sigreturn. */ - frame.sf_sc.sc_mask = mask; + frame.sf_sc.sc_mask = mask->__bits[0]; frame.sf_sc.sc_gs = rgs(); frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; @@ -355,8 +355,12 @@ linux_sigreturn(p, args) } p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - p->p_sigmask = context.sc_mask &~ - (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); + SIGEMPTYSET(p->p_sigmask); + p->p_sigmask.__bits[0] = context.sc_mask; + SIGDELSET(p->p_sigmask, SIGKILL); + SIGDELSET(p->p_sigmask, SIGCONT); + SIGDELSET(p->p_sigmask, SIGSTOP); + /* * Restore signal context. */ @@ -395,7 +399,7 @@ struct sysentvec linux_sysvec = { LINUX_SYS_MAXSYSCALL, linux_sysent, 0xff, - NSIG, + LINUX_SIGTBLSZ, bsd_to_linux_signal, ELAST + 1, bsd_to_linux_errno, @@ -410,19 +414,19 @@ struct sysentvec linux_sysvec = { }; struct sysentvec elf_linux_sysvec = { - LINUX_SYS_MAXSYSCALL, - linux_sysent, - 0xff, - NSIG, - bsd_to_linux_signal, - ELAST + 1, - bsd_to_linux_errno, - translate_traps, - elf_linux_fixup, - linux_sendsig, - linux_sigcode, - &linux_szsigcode, - linux_prepsyscall, + LINUX_SYS_MAXSYSCALL, + linux_sysent, + 0xff, + LINUX_SIGTBLSZ, + bsd_to_linux_signal, + ELAST + 1, + bsd_to_linux_errno, + translate_traps, + elf_linux_fixup, + linux_sendsig, + linux_sigcode, + &linux_szsigcode, + linux_prepsyscall, "Linux ELF", elf_coredump }; diff --git a/sys/alpha/linux/syscalls.master b/sys/alpha/linux/syscalls.master index ab7c20949f6..e8766a94b97 100644 --- a/sys/alpha/linux/syscalls.master +++ b/sys/alpha/linux/syscalls.master @@ -102,15 +102,16 @@ 65 NOPROTO LINUX { int getpgrp(void); } 66 NOPROTO LINUX { int setsid(void); } 67 STD LINUX { int linux_sigaction(int sig, \ - struct linux_sigaction *nsa, \ - struct linux_sigaction *osa); } + linux_osigaction_t *nsa, \ + linux_osigaction_t *osa); } 68 STD LINUX { int linux_siggetmask(void); } -69 STD LINUX { int linux_sigsetmask(linux_sigset_t mask); } +69 STD LINUX { int linux_sigsetmask(linux_osigset_t mask); } 70 NOPROTO LINUX { int setreuid(int ruid, int euid); } 71 NOPROTO LINUX { int setregid(int rgid, int egid); } 72 STD LINUX { int linux_sigsuspend(int restart, \ - linux_sigset_t oldmask, linux_sigset_t mask); } -73 STD LINUX { int linux_sigpending(linux_sigset_t *mask); } + linux_osigset_t oldmask, \ + linux_osigset_t mask); } +73 STD LINUX { int linux_sigpending(linux_osigset_t *mask); } 74 NOPROTO LINUX { int osethostname(char *hostname, u_int len); } 75 STD LINUX { int linux_setrlimit(u_int resource, \ struct ogetrlimit *rlim); } @@ -186,7 +187,8 @@ 124 STD LINUX { int linux_adjtimex(void); } 125 NOPROTO LINUX { int mprotect(caddr_t addr, int len, int prot); } 126 STD LINUX { int linux_sigprocmask(int how, \ - linux_sigset_t *mask, linux_sigset_t *omask); } + linux_osigset_t *mask, \ + linux_osigset_t *omask); } 127 STD LINUX { int linux_create_module(void); } 128 STD LINUX { int linux_init_module(void); } 129 STD LINUX { int linux_delete_module(void); } @@ -251,17 +253,17 @@ 172 STD LINUX { int linux_prctl(void); } 173 STD LINUX { int linux_rt_sigreturn(void); } 174 STD LINUX { int linux_rt_sigaction(int sig, \ - struct linux_new_sigaction *act, \ - struct linux_new_sigaction *oact, \ + linux_sigaction_t *act, \ + linux_sigaction_t *oact, \ size_t sigsetsize); } 175 STD LINUX { int linux_rt_sigprocmask(int how, \ - struct linux_new_sigset *mask, \ - struct linux_new_sigset *omask, \ + linux_sigset_t *mask, linux_sigset_t *omask, \ size_t sigsetsize); } 176 STD LINUX { int linux_rt_sigpending(void); } 177 STD LINUX { int linux_rt_sigtimedwait(void); } 178 STD LINUX { int linux_rt_sigqueueinfo(void); } -179 STD LINUX { int linux_rt_sigsuspend(void); } +179 STD LINUX { int linux_rt_sigsuspend(linux_sigset_t *newset, \ + size_t sigsetsize); } 180 STD LINUX { int linux_pread(void); } 181 STD LINUX { int linux_pwrite(void); } 182 STD LINUX { int linux_chown(char *path, int uid, int gid); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 919a5e74850..ff5ba447c6c 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,9 @@ #include +#define BSD_TO_LINUX_SIGNAL(sig) \ + (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) + static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, @@ -622,7 +626,9 @@ linux_clone(struct proc *p, struct linux_clone_args *args) exit_signal = args->flags & 0x000000ff; if (exit_signal >= LINUX_NSIG) return EINVAL; - exit_signal = linux_to_bsd_signal[exit_signal]; + + if (exit_signal <= LINUX_SIGTBLSZ) + exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; /* RFTHREAD probably not necessary here, but it shouldn't hurt either */ ff |= RFTHREAD; @@ -979,10 +985,10 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | - bsd_to_linux_signal[WTERMSIG(tmpstat)]; + BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | - (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); return copyout(&tmpstat, args->status, sizeof(int)); } else return 0; @@ -1015,17 +1021,17 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args) if ((error = wait4(p, &tmp)) != 0) return error; - p->p_siglist &= ~sigmask(SIGCHLD); + SIGDELSET(p->p_siglist, SIGCHLD); if (args->status) { if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | - bsd_to_linux_signal[WTERMSIG(tmpstat)]; + BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | - (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); return copyout(&tmpstat, args->status, sizeof(int)); } else return 0; @@ -1312,7 +1318,7 @@ linux_sched_setscheduler(p, uap) #ifdef DEBUG printf("Linux-emul(%ld): sched_setscheduler(%d, %d, %p)\n", - (long)p->p_pid, uap->pid, uap->policy, (void *)uap->param); + (long)p->p_pid, uap->pid, uap->policy, (const void *)uap->param); #endif switch (uap->policy) { diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 9f2200e526a..39334a74640 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -38,382 +38,384 @@ #include #include -static sigset_t -linux_to_bsd_sigset(linux_sigset_t mask) { - int b, l; - sigset_t new = 0; +static void +linux_to_bsd_sigset(linux_sigset_t *lss, sigset_t *bss) +{ + int b, l; - for (l = 1; l < LINUX_NSIG; l++) { - if (mask & (1 << (l - 1))) { - if ((b = linux_to_bsd_signal[l])) - new |= (1 << (b - 1)); + SIGEMPTYSET(*bss); + bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); + bss->__bits[1] = lss->__bits[1]; + for (l = 1; l <= LINUX_SIGTBLSZ; l++) { + if (LINUX_SIGISMEMBER(*lss, l)) { + b = linux_to_bsd_signal[_SIG_IDX(l)]; + if (b) + SIGADDSET(*bss, b); + } } - } - return new; } -static linux_sigset_t -bsd_to_linux_sigset(sigset_t mask) { - int b, l; - sigset_t new = 0; +static void +bsd_to_linux_sigset(sigset_t *bss, linux_sigset_t *lss) +{ + int b, l; - for (b = 1; b < NSIG; b++) { - if (mask & (1 << (b - 1))) { - if ((l = bsd_to_linux_signal[b])) - new |= (1 << (l - 1)); + LINUX_SIGEMPTYSET(*lss); + lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); + lss->__bits[1] = bss->__bits[1]; + for (b = 1; b <= LINUX_SIGTBLSZ; b++) { + if (SIGISMEMBER(*bss, b)) { + l = bsd_to_linux_signal[_SIG_IDX(b)]; + if (l) + LINUX_SIGADDSET(*lss, l); + } } - } - return new; } static void linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa) { - bsa->sa_mask = linux_to_bsd_sigset(lsa->lsa_mask); - bsa->sa_handler = lsa->lsa_handler; - bsa->sa_flags = 0; - if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) - bsa->sa_flags |= SA_NOCLDSTOP; - if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) - bsa->sa_flags |= SA_NOCLDWAIT; - if (lsa->lsa_flags & LINUX_SA_SIGINFO) - bsa->sa_flags |= SA_SIGINFO; - if (lsa->lsa_flags & LINUX_SA_ONSTACK) - bsa->sa_flags |= SA_ONSTACK; - if (lsa->lsa_flags & LINUX_SA_RESTART) - bsa->sa_flags |= SA_RESTART; - if (lsa->lsa_flags & LINUX_SA_ONESHOT) - bsa->sa_flags |= SA_RESETHAND; - if (lsa->lsa_flags & LINUX_SA_NOMASK) - bsa->sa_flags |= SA_NODEFER; + + linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); + bsa->sa_handler = lsa->lsa_handler; + bsa->sa_flags = 0; + if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) + bsa->sa_flags |= SA_NOCLDSTOP; + if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) + bsa->sa_flags |= SA_NOCLDWAIT; + if (lsa->lsa_flags & LINUX_SA_SIGINFO) + bsa->sa_flags |= SA_SIGINFO; + if (lsa->lsa_flags & LINUX_SA_ONSTACK) + bsa->sa_flags |= SA_ONSTACK; + if (lsa->lsa_flags & LINUX_SA_RESTART) + bsa->sa_flags |= SA_RESTART; + if (lsa->lsa_flags & LINUX_SA_ONESHOT) + bsa->sa_flags |= SA_RESETHAND; + if (lsa->lsa_flags & LINUX_SA_NOMASK) + bsa->sa_flags |= SA_NODEFER; } static void bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa) { - lsa->lsa_handler = bsa->sa_handler; - lsa->lsa_restorer = NULL; /* unsupported */ - lsa->lsa_mask = bsd_to_linux_sigset(bsa->sa_mask); - lsa->lsa_flags = 0; - if (bsa->sa_flags & SA_NOCLDSTOP) - lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; - if (bsa->sa_flags & SA_NOCLDWAIT) - lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; - if (bsa->sa_flags & SA_SIGINFO) - lsa->lsa_flags |= LINUX_SA_SIGINFO; - if (bsa->sa_flags & SA_ONSTACK) - lsa->lsa_flags |= LINUX_SA_ONSTACK; - if (bsa->sa_flags & SA_RESTART) - lsa->lsa_flags |= LINUX_SA_RESTART; - if (bsa->sa_flags & SA_RESETHAND) - lsa->lsa_flags |= LINUX_SA_ONESHOT; - if (bsa->sa_flags & SA_NODEFER) - lsa->lsa_flags |= LINUX_SA_NOMASK; + + bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); + lsa->lsa_handler = bsa->sa_handler; + lsa->lsa_restorer = NULL; /* unsupported */ + lsa->lsa_flags = 0; + if (bsa->sa_flags & SA_NOCLDSTOP) + lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; + if (bsa->sa_flags & SA_NOCLDWAIT) + lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; + if (bsa->sa_flags & SA_SIGINFO) + lsa->lsa_flags |= LINUX_SA_SIGINFO; + if (bsa->sa_flags & SA_ONSTACK) + lsa->lsa_flags |= LINUX_SA_ONSTACK; + if (bsa->sa_flags & SA_RESTART) + lsa->lsa_flags |= LINUX_SA_RESTART; + if (bsa->sa_flags & SA_RESETHAND) + lsa->lsa_flags |= LINUX_SA_ONESHOT; + if (bsa->sa_flags & SA_NODEFER) + lsa->lsa_flags |= LINUX_SA_NOMASK; } 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_args sa_args; - int error; - caddr_t sg = stackgap_init(); + struct sigaction *nsa, *osa, sa; + struct sigaction_args sa_args; + int error; + caddr_t sg = stackgap_init(); - if (linux_sig <= 0 || linux_sig >= LINUX_NSIG) - return EINVAL; + if (linux_sig <= 0 || linux_sig > LINUX_NSIG) + return (EINVAL); - if (linux_osa) - osa = stackgap_alloc(&sg, sizeof(struct sigaction)); - else - osa = NULL; + if (linux_osa != NULL) + osa = stackgap_alloc(&sg, sizeof(struct sigaction)); + else + osa = NULL; - if (linux_nsa) { - nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - linux_to_bsd_sigaction(linux_nsa, &sa); - error = copyout(&sa, nsa, sizeof(struct sigaction)); + 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); + } + else + nsa = NULL; + + if (linux_sig <= LINUX_SIGTBLSZ) + sa_args.sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; + else + sa_args.sig = linux_sig; + + sa_args.act = nsa; + sa_args.oact = osa; + error = sigaction(p, &sa_args); if (error) - return error; - } - else - nsa = NULL; + return (error); - sa_args.signum = linux_to_bsd_signal[linux_sig]; - sa_args.nsa = nsa; - sa_args.osa = osa; - error = sigaction(p, &sa_args); - 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) { - error = copyin(osa, &sa, sizeof(struct sigaction)); - if (error) - return error; - bsd_to_linux_sigaction(&sa, linux_osa); - } - - return 0; + return (0); } int linux_sigaction(struct proc *p, struct linux_sigaction_args *args) { - linux_sigaction_t nsa, osa; - int error; + linux_osigaction_t osa; + linux_sigaction_t act, oact; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): sigaction(%d, %p, %p)\n", - (long)p->p_pid, args->sig, (void *)args->nsa, (void *)args->osa); + printf("Linux-emul(%ld): sigaction(%d, %p, %p)\n", (long)p->p_pid, + args->sig, (void *)args->nsa, (void *)args->osa); #endif - if (args->nsa) { - error = copyin(args->nsa, &nsa, sizeof(linux_sigaction_t)); - if (error) - return error; - } + if (args->nsa != NULL) { + error = copyin(args->nsa, &osa, sizeof(linux_osigaction_t)); + if (error) + return (error); + act.lsa_handler = osa.lsa_handler; + act.lsa_flags = osa.lsa_flags; + act.lsa_restorer = osa.lsa_restorer; + LINUX_SIGEMPTYSET(act.lsa_mask); + act.lsa_mask.__bits[0] = osa.lsa_mask; + } - error = linux_do_sigaction(p, args->sig, - args->nsa ? &nsa : NULL, - args->osa ? &osa : NULL); - if (error) - return error; + error = linux_do_sigaction(p, args->sig, + args->nsa ? &act : NULL, + args->osa ? &oact : NULL); - if (args->osa) { - error = copyout(&osa, args->osa, sizeof(linux_sigaction_t)); - if (error) - return error; - } + if (args->osa != NULL && !error) { + osa.lsa_handler = oact.lsa_handler; + osa.lsa_flags = oact.lsa_flags; + osa.lsa_restorer = oact.lsa_restorer; + osa.lsa_mask = oact.lsa_mask.__bits[0]; + error = copyout(&osa, args->osa, sizeof(linux_osigaction_t)); + } - return 0; + return (error); } int linux_signal(struct proc *p, struct linux_signal_args *args) { - linux_sigaction_t nsa, osa; - int error; + linux_sigaction_t nsa, osa; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): signal(%d, %p)\n", - (long)p->p_pid, args->sig, (void *)args->handler); + printf("Linux-emul(%ld): signal(%d, %p)\n", + (long)p->p_pid, args->sig, (void *)args->handler); #endif - nsa.lsa_handler = args->handler; - nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; - nsa.lsa_mask = NULL; + nsa.lsa_handler = args->handler; + nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; + LINUX_SIGEMPTYSET(nsa.lsa_mask); - error = linux_do_sigaction(p, args->sig, &nsa, &osa); + error = linux_do_sigaction(p, args->sig, &nsa, &osa); + p->p_retval[0] = (int)osa.lsa_handler; - p->p_retval[0] = (int)osa.lsa_handler; - - return 0; + return (error); } int linux_rt_sigaction(struct proc *p, struct linux_rt_sigaction_args *args) { - linux_sigaction_t nsa, osa; - linux_new_sigaction_t new_sa; - int error; + linux_sigaction_t nsa, osa; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): rt_sigaction(%d, %p, %p, %d)\n", - (long)p->p_pid, args->sig, (void *)args->act, - (void *)args->oact, args->sigsetsize); + printf("Linux-emul(%ld): rt_sigaction(%d, %p, %p, %d)\n", + (long)p->p_pid, args->sig, (void *)args->act, + (void *)args->oact, args->sigsetsize); #endif - if (args->sigsetsize != sizeof(linux_new_sigset_t)) - return EINVAL; + if (args->sigsetsize != sizeof(linux_sigset_t)) + return (EINVAL); -#ifdef DEBUG - if (args->sig >= LINUX_NSIG) { - printf("LINUX(%ld): rt_sigaction: 64-bit signal (%d)\n", - (long)p->p_pid, args->sig); - } -#endif + if (args->act != NULL) { + error = copyin(args->act, &nsa, sizeof(linux_sigaction_t)); + if (error) + return (error); + } - if (args->act) { - error = copyin(args->act, &new_sa, sizeof(linux_new_sigaction_t)); - if (error) - return error; + error = linux_do_sigaction(p, args->sig, + args->act ? &nsa : NULL, + args->oact ? &osa : NULL); - nsa.lsa_handler = new_sa.lsa_handler; - nsa.lsa_mask = new_sa.lsa_mask.sig[0]; - nsa.lsa_flags = new_sa.lsa_flags; - nsa.lsa_restorer = new_sa.lsa_restorer; + if (args->oact != NULL && !error) { + error = copyout(&osa, args->oact, sizeof(linux_sigaction_t)); + } -#ifdef DEBUG - if (new_sa.lsa_mask.sig[1] != 0) - printf("LINUX(%ld): rt_sigaction: sig[1] = 0x%08lx\n", - (long)p->p_pid, new_sa.lsa_mask.sig[1]); -#endif - } - - error = linux_do_sigaction(p, args->sig, - args->act ? &nsa : NULL, - args->oact ? &osa : NULL); - if (error) - return error; - - if (args->oact) { - new_sa.lsa_handler = osa.lsa_handler; - new_sa.lsa_flags = osa.lsa_flags; - new_sa.lsa_restorer = osa.lsa_restorer; - new_sa.lsa_mask.sig[0] = osa.lsa_mask; - new_sa.lsa_mask.sig[1] = 0; - error = copyout(&osa, args->oact, sizeof(linux_new_sigaction_t)); - if (error) - return error; - } - - return 0; + return (error); } static int linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new, linux_sigset_t *old) { - int error = 0, s; - sigset_t mask; + int error, s; + sigset_t mask; - p->p_retval[0] = 0; + error = 0; + p->p_retval[0] = 0; - if (old != NULL) - *old = bsd_to_linux_sigset(p->p_sigmask); + if (old != NULL) + bsd_to_linux_sigset(&p->p_sigmask, old); - if (new != NULL) { - mask = linux_to_bsd_sigset(*new); + if (new != NULL) { + linux_to_bsd_sigset(new, &mask); - s = splhigh(); + s = splhigh(); - switch (how) { - case LINUX_SIG_BLOCK: - p->p_sigmask |= (mask & ~sigcantmask); - break; - case LINUX_SIG_UNBLOCK: - p->p_sigmask &= ~mask; - break; - case LINUX_SIG_SETMASK: - p->p_sigmask = (mask & ~sigcantmask); - break; - default: - error = EINVAL; - break; + switch (how) { + case LINUX_SIG_BLOCK: + SIGSETOR(p->p_sigmask, mask); + SIG_CANTMASK(p->p_sigmask); + break; + case LINUX_SIG_UNBLOCK: + SIGSETNAND(p->p_sigmask, mask); + break; + case LINUX_SIG_SETMASK: + p->p_sigmask = mask; + SIG_CANTMASK(p->p_sigmask); + break; + default: + error = EINVAL; + break; + } + + splx(s); } - splx(s); - } - - return error; + return (error); } int linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args) { - linux_sigset_t mask; - linux_sigset_t omask; - int error; + linux_osigset_t mask; + linux_sigset_t set, oset; + int error; #ifdef DEBUG - printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); + printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); #endif - if (args->mask != NULL) { - error = copyin(args->mask, &mask, sizeof(linux_sigset_t)); - if (error) - return error; - } + if (args->mask != NULL) { + error = copyin(args->mask, &mask, sizeof(linux_osigset_t)); + if (error) + return (error); + LINUX_SIGEMPTYSET(set); + set.__bits[0] = mask; + } - error = linux_do_sigprocmask(p, args->how, - args->mask ? &mask : NULL, - args->omask ? &omask : NULL); + error = linux_do_sigprocmask(p, args->how, + args->mask ? &set : NULL, + args->omask ? &oset : NULL); - if (!error && args->omask != NULL) { - error = copyout(&omask, args->omask, sizeof(linux_sigset_t)); - } + if (args->omask != NULL && !error) { + mask = oset.__bits[0]; + error = copyout(&mask, args->omask, sizeof(linux_osigset_t)); + } - return error; + return (error); } int linux_rt_sigprocmask(struct proc *p, struct linux_rt_sigprocmask_args *args) { - linux_new_sigset_t new_mask; - linux_sigset_t old_mask; - int error; + linux_sigset_t set, oset; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): rt_sigprocmask(%d, %p, %p, %d)\n", - (long)p->p_pid, args->how, (void *)args->mask, - (void *)args->omask, args->sigsetsize); + printf("Linux-emul(%ld): rt_sigprocmask(%d, %p, %p, %d)\n", + (long)p->p_pid, args->how, (void *)args->mask, + (void *)args->omask, args->sigsetsize); #endif - if (args->sigsetsize != sizeof(linux_new_sigset_t)) - return EINVAL; + if (args->sigsetsize != sizeof(linux_sigset_t)) + return EINVAL; - if (args->mask != NULL) { - error = copyin(args->mask, &new_mask, sizeof(linux_new_sigset_t)); - if (error) - return error; + if (args->mask != NULL) { + error = copyin(args->mask, &set, sizeof(linux_sigset_t)); + if (error) + return (error); + } -#ifdef DEBUG - if (new_mask.sig[1] != 0) - printf("LINUX(%ld): rt_sigprocmask: sig[1] = 0x%08lx\n", - (long)p->p_pid, new_mask.sig[1]); -#endif - } + error = linux_do_sigprocmask(p, args->how, + args->mask ? &set : NULL, + args->omask ? &oset : NULL); - error = linux_do_sigprocmask(p, args->how, - args->mask ? new_mask.sig : NULL, - args->omask ? &old_mask : NULL); + if (args->omask != NULL && !error) { + error = copyout(&oset, args->omask, sizeof(linux_sigset_t)); + } - if (!error && args->omask != NULL) { - new_mask.sig[0] = old_mask; - error = copyout(&new_mask, args->omask, sizeof(linux_new_sigset_t)); - } - - return error; + return (error); } int linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args) { + linux_sigset_t mask; + #ifdef DEBUG - printf("Linux-emul(%d): siggetmask()\n", p->p_pid); + printf("Linux-emul(%d): siggetmask()\n", p->p_pid); #endif - p->p_retval[0] = bsd_to_linux_sigset(p->p_sigmask); - return 0; + + bsd_to_linux_sigset(&p->p_sigmask, &mask); + p->p_retval[0] = mask.__bits[0]; + return (0); } int linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args) { - int s; - sigset_t mask; + linux_sigset_t lset; + sigset_t bset; + int s; #ifdef DEBUG - printf("Linux-emul(%ld): sigsetmask(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); + printf("Linux-emul(%ld): sigsetmask(%08lx)\n", + (long)p->p_pid, (unsigned long)args->mask); #endif - p->p_retval[0] = bsd_to_linux_sigset(p->p_sigmask); - mask = linux_to_bsd_sigset(args->mask); - s = splhigh(); - p->p_sigmask = mask & ~sigcantmask; - splx(s); - return 0; + bsd_to_linux_sigset(&p->p_sigmask, &lset); + p->p_retval[0] = lset.__bits[0]; + LINUX_SIGEMPTYSET(lset); + lset.__bits[0] = args->mask; + linux_to_bsd_sigset(&lset, &bset); + s = splhigh(); + p->p_sigmask = bset; + SIG_CANTMASK(p->p_sigmask); + splx(s); + return (0); } int linux_sigpending(struct proc *p, struct linux_sigpending_args *args) { - linux_sigset_t linux_sig; + sigset_t bset; + linux_sigset_t lset; + linux_osigset_t mask; #ifdef DEBUG - printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); + printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); #endif - linux_sig = bsd_to_linux_sigset(p->p_siglist & p->p_sigmask); - return copyout(&linux_sig, args->mask, sizeof(linux_sig)); + + bset = p->p_siglist; + SIGSETAND(bset, p->p_sigmask); + bsd_to_linux_sigset(&bset, &lset); + mask = lset.__bits[0]; + return (copyout(&mask, args->mask, sizeof(mask))); } /* @@ -424,43 +426,94 @@ linux_sigpending(struct proc *p, struct linux_sigpending_args *args) int linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args) { - struct sigsuspend_args tmp; + struct sigsuspend_args bsd; + sigset_t *sigmask; + linux_sigset_t mask; + caddr_t sg = stackgap_init(); #ifdef DEBUG - printf("Linux-emul(%ld): sigsuspend(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); + printf("Linux-emul(%ld): sigsuspend(%08lx)\n", + (long)p->p_pid, (unsigned long)args->mask); #endif - tmp.mask = linux_to_bsd_sigset(args->mask); - return sigsuspend(p, &tmp); + + sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); + LINUX_SIGEMPTYSET(mask); + mask.__bits[0] = args->mask; + linux_to_bsd_sigset(&mask, sigmask); + bsd.sigmask = sigmask; + return (sigsuspend(p, &bsd)); +} + +int +linux_rt_sigsuspend(p, uap) + struct proc *p; + struct linux_rt_sigsuspend_args *uap; +{ + linux_sigset_t lmask; + sigset_t *bmask; + struct sigsuspend_args bsd; + caddr_t sg = stackgap_init(); + int error; + +#ifdef DEBUG + printf("Linux-emul(%ld): rt_sigsuspend(%p, %d)\n", (long)p->p_pid, + (void *)uap->newset, uap->sigsetsize); +#endif + + if (uap->sigsetsize != sizeof(linux_sigset_t)) + return (EINVAL); + + error = copyin(uap->newset, &lmask, sizeof(linux_sigset_t)); + if (error) + return (error); + + bmask = stackgap_alloc(&sg, sizeof(sigset_t)); + linux_to_bsd_sigset(&lmask, bmask); + bsd.sigmask = bmask; + return (sigsuspend(p, &bsd)); } int linux_pause(struct proc *p, struct linux_pause_args *args) { - struct sigsuspend_args tmp; + struct sigsuspend_args bsd; + sigset_t *sigmask; + caddr_t sg = stackgap_init(); #ifdef DEBUG - printf("Linux-emul(%d): pause()\n", p->p_pid); + printf("Linux-emul(%d): pause()\n", p->p_pid); #endif - tmp.mask = p->p_sigmask; - return sigsuspend(p, &tmp); + + sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); + *sigmask = p->p_sigmask; + bsd.sigmask = sigmask; + return sigsuspend(p, &bsd); } int linux_kill(struct proc *p, struct linux_kill_args *args) { - struct kill_args /* { - int pid; - int signum; - } */ tmp; + struct kill_args /* { + int pid; + int signum; + } */ tmp; #ifdef DEBUG - printf("Linux-emul(%d): kill(%d, %d)\n", - p->p_pid, args->pid, args->signum); + printf("Linux-emul(%d): kill(%d, %d)\n", + p->p_pid, args->pid, args->signum); #endif - if (args->signum < 0 || args->signum >= LINUX_NSIG) - return EINVAL; - tmp.pid = args->pid; - tmp.signum = linux_to_bsd_signal[args->signum]; - return kill(p, &tmp); + + /* + * Allow signal 0 as a means to check for privileges + */ + if (args->signum < 0 || args->signum > LINUX_NSIG) + return EINVAL; + + if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) + tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; + else + tmp.signum = args->signum; + + tmp.pid = args->pid; + return (kill(p, &tmp)); } diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 9535cba8972..9720abca1e5 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -100,7 +100,6 @@ #define BSD_DIRENT(cp) ((struct dirent *)(cp)) -extern int bsd_to_svr4_sig[]; static int svr4_mknod __P((struct proc *, register_t *, char *, svr4_mode_t, svr4_dev_t)); @@ -159,11 +158,11 @@ svr4_sys_wait(p, uap) if (WIFSIGNALED(st)) { sig = WTERMSIG(st); if (sig >= 0 && sig < NSIG) - st = (st & ~0177) | bsd_to_svr4_sig[sig]; + st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig); } else if (WIFSTOPPED(st)) { sig = WSTOPSIG(st); if (sig >= 0 && sig < NSIG) - st = (st & ~0xff00) | (bsd_to_svr4_sig[sig] << 8); + st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8); } /* @@ -1119,7 +1118,7 @@ svr4_setinfo(p, st, s) } else if (WIFSTOPPED(st)) { sig = WSTOPSIG(st); if (sig >= 0 && sig < NSIG) - i.si_status = bsd_to_svr4_sig[sig]; + i.si_status = SVR4_BSD2SVR4_SIG(sig); if (i.si_status == SVR4_SIGCONT) i.si_code = SVR4_CLD_CONTINUED; @@ -1128,7 +1127,7 @@ svr4_setinfo(p, st, s) } else { sig = WTERMSIG(st); if (sig >= 0 && sig < NSIG) - i.si_status = bsd_to_svr4_sig[sig]; + i.si_status = SVR4_BSD2SVR4_SIG(sig); if (WCOREDUMP(st)) i.si_code = SVR4_CLD_DUMPED; diff --git a/sys/compat/svr4/svr4_signal.c b/sys/compat/svr4/svr4_signal.c index b1239871942..5b8838c2572 100644 --- a/sys/compat/svr4/svr4_signal.c +++ b/sys/compat/svr4/svr4_signal.c @@ -47,24 +47,19 @@ #include #include -#define sigemptyset(s) memset((s), 0, sizeof(*(s))) -#define sigismember(s, n) (*(s) & sigmask(n)) -#define sigaddset(s, n) (*(s) |= sigmask(n)) - #define svr4_sigmask(n) (1 << (((n) - 1) & 31)) #define svr4_sigword(n) (((n) - 1) >> 5) #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s))) +#define svr4_sigfillset(s) memset((s), 0xffffffff, sizeof(*(s))) #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n)) #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n)) -static __inline void svr4_sigfillset __P((svr4_sigset_t *)); void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *, struct sigaction *)); void bsd_to_svr4_sigaction __P((const struct sigaction *, struct svr4_sigaction *)); -int bsd_to_svr4_sig[] = { - 0, +int bsd_to_svr4_sig[SVR4_SIGTBLSZ] = { SVR4_SIGHUP, SVR4_SIGINT, SVR4_SIGQUIT, @@ -98,8 +93,7 @@ int bsd_to_svr4_sig[] = { SVR4_SIGUSR2, }; -int svr4_to_bsd_sig[] = { - 0, +int svr4_to_bsd_sig[SVR4_SIGTBLSZ] = { SIGHUP, SIGINT, SIGQUIT, @@ -133,17 +127,6 @@ int svr4_to_bsd_sig[] = { SIGXFSZ, }; -static __inline void -svr4_sigfillset(s) - svr4_sigset_t *s; -{ - int i; - - svr4_sigemptyset(s); - for (i = 1; i < SVR4_NSIG; i++) - svr4_sigaddset(s, i); -} - void svr4_to_bsd_sigset(sss, bss) const svr4_sigset_t *sss; @@ -151,17 +134,20 @@ svr4_to_bsd_sigset(sss, bss) { int i, newsig; - sigemptyset(bss); - for (i = 1; i < SVR4_NSIG; i++) { + SIGEMPTYSET(*bss); + bss->__bits[0] = sss->bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1); + bss->__bits[1] = sss->bits[1]; + bss->__bits[2] = sss->bits[2]; + bss->__bits[3] = sss->bits[3]; + for (i = 1; i <= SVR4_SIGTBLSZ; i++) { if (svr4_sigismember(sss, i)) { - newsig = svr4_to_bsd_sig[i]; + newsig = svr4_to_bsd_sig[_SIG_IDX(i)]; if (newsig) - sigaddset(bss, newsig); + SIGADDSET(*bss, newsig); } } } - void bsd_to_svr4_sigset(bss, sss) const sigset_t *bss; @@ -170,16 +156,19 @@ bsd_to_svr4_sigset(bss, sss) int i, newsig; svr4_sigemptyset(sss); - for (i = 1; i < NSIG; i++) { - if (sigismember(bss, i)) { - newsig = bsd_to_svr4_sig[i]; + sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1); + sss->bits[1] = bss->__bits[1]; + sss->bits[2] = bss->__bits[2]; + sss->bits[3] = bss->__bits[3]; + for (i = 1; i <= SVR4_SIGTBLSZ; i++) { + if (SIGISMEMBER(*bss, i)) { + newsig = bsd_to_svr4_sig[_SIG_IDX(i)]; if (newsig) svr4_sigaddset(sss, newsig); } } } - /* * XXX: Only a subset of the flags is currently implemented. */ @@ -293,9 +282,9 @@ svr4_sys_sigaction(p, uap) } else nbsa = NULL; - SCARG(&sa, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; - SCARG(&sa, nsa) = nbsa; - SCARG(&sa, osa) = obsa; + SCARG(&sa, sig) = SVR4_SVR42BSD_SIG(SCARG(uap, signum)); + SCARG(&sa, act) = nbsa; + SCARG(&sa, oact) = obsa; if ((error = sigaction(p, &sa)) != 0) return error; @@ -342,7 +331,7 @@ svr4_sys_sigaltstack(p, uap) } else nbss = NULL; - SCARG(&sa, nss) = nbss; + SCARG(&sa, ss) = nbss; SCARG(&sa, oss) = obss; if ((error = sigaltstack(p, &sa)) != 0) @@ -367,12 +356,13 @@ svr4_sys_signal(p, uap) register struct proc *p; struct svr4_sys_signal_args *uap; { - int signum = svr4_to_bsd_sig[SVR4_SIGNO(SCARG(uap, signum))]; + int signum; int error, *retval; caddr_t sg = stackgap_init(); + signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(SCARG(uap, signum))); retval = p->p_retval; - if (signum <= 0 || signum >= SVR4_NSIG) + if (signum <= 0 || signum > SVR4_NSIG) return (EINVAL); switch (SVR4_SIGCALL(SCARG(uap, signum))) { @@ -388,12 +378,12 @@ svr4_sys_signal(p, uap) nbsa = stackgap_alloc(&sg, sizeof(struct sigaction)); obsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = nbsa; - SCARG(&sa_args, osa) = obsa; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = nbsa; + SCARG(&sa_args, oact) = obsa; sa.sa_handler = (sig_t) SCARG(uap, handler); - sigemptyset(&sa.sa_mask); + SIGEMPTYSET(sa.sa_mask); sa.sa_flags = 0; if (signum != SIGALRM) @@ -417,18 +407,28 @@ svr4_sys_signal(p, uap) sighold: { struct sigprocmask_args sa; + sigset_t *set; + set = stackgap_alloc(&sg, sizeof(sigset_t)); + SIGEMPTYSET(*set); + SIGADDSET(*set, signum); SCARG(&sa, how) = SIG_BLOCK; - SCARG(&sa, mask) = sigmask(signum); + SCARG(&sa, set) = set; + SCARG(&sa, oset) = NULL; return sigprocmask(p, &sa); } case SVR4_SIGRELSE_MASK: { struct sigprocmask_args sa; + sigset_t *set; + set = stackgap_alloc(&sg, sizeof(sigset_t)); + SIGEMPTYSET(*set); + SIGADDSET(*set, signum); SCARG(&sa, how) = SIG_UNBLOCK; - SCARG(&sa, mask) = sigmask(signum); + SCARG(&sa, set) = set; + SCARG(&sa, oset) = NULL; return sigprocmask(p, &sa); } @@ -438,12 +438,12 @@ sighold: struct sigaction *bsa, sa; bsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = bsa; - SCARG(&sa_args, osa) = NULL; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = bsa; + SCARG(&sa_args, oact) = NULL; sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); + SIGEMPTYSET(sa.sa_mask); sa.sa_flags = 0; if ((error = copyout(&sa, bsa, sizeof(sa))) != 0) return error; @@ -457,8 +457,12 @@ sighold: case SVR4_SIGPAUSE_MASK: { struct sigsuspend_args sa; + sigset_t *set; - SCARG(&sa, mask) = p->p_sigmask & ~sigmask(signum); + set = stackgap_alloc(&sg, sizeof(sigset_t)); + *set = p->p_sigmask; + SIGDELSET(*set, signum); + SCARG(&sa, sigmask) = set; return sigsuspend(p, &sa); } @@ -498,15 +502,17 @@ svr4_sys_sigprocmask(p, uap) switch (SCARG(uap, how)) { case SVR4_SIG_BLOCK: - p->p_sigmask |= bss & ~sigcantmask; + SIGSETOR(p->p_sigmask, bss); + SIG_CANTMASK(p->p_sigmask); break; case SVR4_SIG_UNBLOCK: - p->p_sigmask &= ~bss; + SIGSETNAND(p->p_sigmask, bss); break; case SVR4_SIG_SETMASK: - p->p_sigmask = bss & ~sigcantmask; + p->p_sigmask = bss; + SIG_CANTMASK(p->p_sigmask); break; default: @@ -533,7 +539,8 @@ svr4_sys_sigpending(p, uap) case 1: /* sigpending */ if (SCARG(uap, mask) == NULL) return 0; - bss = p->p_siglist & p->p_sigmask; + bss = p->p_siglist; + SIGSETAND(bss, p->p_sigmask); bsd_to_svr4_sigset(&bss, &sss); break; @@ -554,16 +561,18 @@ svr4_sys_sigsuspend(p, uap) struct svr4_sys_sigsuspend_args *uap; { svr4_sigset_t sss; - sigset_t bss; + sigset_t *bss; struct sigsuspend_args sa; int error; + caddr_t sg = stackgap_init(); if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0) return error; - svr4_to_bsd_sigset(&sss, &bss); + bss = stackgap_alloc(&sg, sizeof(sigset_t)); + svr4_to_bsd_sigset(&sss, bss); - SCARG(&sa, mask) = bss; + SCARG(&sa, sigmask) = bss; return sigsuspend(p, &sa); } @@ -576,7 +585,7 @@ svr4_sys_kill(p, uap) struct kill_args ka; SCARG(&ka, pid) = SCARG(uap, pid); - SCARG(&ka, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; + SCARG(&ka, signum) = SVR4_SVR42BSD_SIG(SCARG(uap, signum)); return kill(p, &ka); } @@ -592,7 +601,7 @@ svr4_sys_context(p, uap) switch (uap->func) { case 0: DPRINTF(("getcontext(%p)\n", uap->uc)); - svr4_getcontext(p, &uc, p->p_sigmask, + svr4_getcontext(p, &uc, &p->p_sigmask, p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK); return copyout(&uc, uap->uc, sizeof(uc)); @@ -620,6 +629,6 @@ svr4_sys_pause(p, uap) { struct sigsuspend_args bsa; - SCARG(&bsa, mask) = p->p_sigmask; + SCARG(&bsa, sigmask) = &p->p_sigmask; return sigsuspend(p, &bsa); } diff --git a/sys/compat/svr4/svr4_signal.h b/sys/compat/svr4/svr4_signal.h index 8fb861d2014..b7bb13269f4 100644 --- a/sys/compat/svr4/svr4_signal.h +++ b/sys/compat/svr4/svr4_signal.h @@ -68,7 +68,8 @@ #define SVR4_SIGPROF 29 #define SVR4_SIGXCPU 30 #define SVR4_SIGXFSZ 31 -#define SVR4_NSIG 32 +#define SVR4_NSIG 128 +#define SVR4_SIGTBLSZ 31 #define SVR4_SIGNO_MASK 0x00FF #define SVR4_SIGNAL_MASK 0x0000 @@ -91,6 +92,14 @@ typedef void (*svr4_sig_t) __P((int, svr4_siginfo_t *, void *)); #define SVR4_SIG_UNBLOCK 2 #define SVR4_SIG_SETMASK 3 +extern int bsd_to_svr4_sig[]; +extern int svr4_to_bsd_sig[]; + +#define SVR4_BSD2SVR4_SIG(sig) \ + (((sig) <= SVR4_SIGTBLSZ) ? bsd_to_svr4_sig[_SIG_IDX(sig)] : sig) +#define SVR4_SVR42BSD_SIG(sig) \ + (((sig) <= SVR4_SIGTBLSZ) ? svr4_to_bsd_sig[_SIG_IDX(sig)] : sig) + typedef struct { u_long bits[4]; } svr4_sigset_t; @@ -127,6 +136,6 @@ void bsd_to_svr4_sigaltstack __P((const struct sigaltstack *, struct svr4_sigalt void bsd_to_svr4_sigset __P((const sigset_t *, svr4_sigset_t *)); void svr4_to_bsd_sigaltstack __P((const struct svr4_sigaltstack *, struct sigaltstack *)); void svr4_to_bsd_sigset __P((const svr4_sigset_t *, sigset_t *)); -void svr4_sendsig(sig_t, int, int, u_long); +void svr4_sendsig(sig_t, int, sigset_t *, u_long); #endif /* !_SVR4_SIGNAL_H_ */ diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 099bb9c4dfa..6a2bc03d9bf 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -72,9 +72,6 @@ #include #include -extern int bsd_to_svr4_sig[]; -extern int svr4_to_bsd_sig[]; - int bsd_to_svr4_errno[ELAST+1] = { 0, SVR4_EPERM, @@ -176,7 +173,7 @@ struct sysentvec svr4_sysvec = { SVR4_SYS_MAXSYSCALL, svr4_sysent, 0xff, - NSIG, + SVR4_SIGTBLSZ, bsd_to_svr4_sig, ELAST, /* ELAST */ bsd_to_svr4_errno, diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index cea6b15ddd4..de67da47087 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -167,9 +167,9 @@ ibcs2_wait(p, uap) /* convert status/signal result */ if(WIFSTOPPED(status)) status = - IBCS2_STOPCODE(bsd_to_ibcs2_sig[WSTOPSIG(status)]); + IBCS2_STOPCODE(bsd_to_ibcs2_sig[_SIG_IDX(WSTOPSIG(status))]); else if(WIFSIGNALED(status)) - status = bsd_to_ibcs2_sig[WTERMSIG(status)]; + status = bsd_to_ibcs2_sig[_SIG_IDX(WTERMSIG(status))]; /* else exit status -- identical */ /* record result/status */ diff --git a/sys/i386/ibcs2/ibcs2_signal.c b/sys/i386/ibcs2/ibcs2_signal.c index fa111fa88f5..8aacade37b1 100644 --- a/sys/i386/ibcs2/ibcs2_signal.c +++ b/sys/i386/ibcs2/ibcs2_signal.c @@ -39,9 +39,9 @@ #include #include -#define sigemptyset(s) bzero((s), sizeof(*(s))) -#define sigismember(s, n) (*(s) & sigmask(n)) -#define sigaddset(s, n) (*(s) |= sigmask(n)) +#define sigemptyset(s) SIGEMPTYSET(*(s)) +#define sigismember(s, n) SIGISMEMBER(*(s), n) +#define sigaddset(s, n) SIGADDSET(*(s), n) #define ibcs2_sigmask(n) (1 << ((n) - 1)) #define ibcs2_sigemptyset(s) bzero((s), sizeof(*(s))) @@ -55,8 +55,7 @@ static void ibcs2_to_bsd_sigaction __P((struct ibcs2_sigaction *, static void bsd_to_ibcs2_sigaction __P((struct sigaction *, struct ibcs2_sigaction *)); -int bsd_to_ibcs2_sig[] = { - 0, /* 0 */ +int bsd_to_ibcs2_sig[IBCS2_SIGTBLSZ] = { IBCS2_SIGHUP, /* 1 */ IBCS2_SIGINT, /* 2 */ IBCS2_SIGQUIT, /* 3 */ @@ -88,10 +87,10 @@ int bsd_to_ibcs2_sig[] = { 0, /* 29 */ IBCS2_SIGUSR1, /* 30 */ IBCS2_SIGUSR2, /* 31 */ + 0 /* 32 */ }; -static int ibcs2_to_bsd_sig[] = { - 0, /* 0 */ +static int ibcs2_to_bsd_sig[IBCS2_SIGTBLSZ] = { SIGHUP, /* 1 */ SIGINT, /* 2 */ SIGQUIT, /* 3 */ @@ -123,6 +122,7 @@ static int ibcs2_to_bsd_sig[] = { SIGPROF, /* 29 */ 0, /* 30 */ 0, /* 31 */ + 0 /* 32 */ }; void @@ -133,9 +133,9 @@ ibcs2_to_bsd_sigset(iss, bss) int i, newsig; sigemptyset(bss); - for (i = 1; i < IBCS2_NSIG; i++) { + for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { if (ibcs2_sigismember(iss, i)) { - newsig = ibcs2_to_bsd_sig[i]; + newsig = ibcs2_to_bsd_sig[_SIG_IDX(i)]; if (newsig) sigaddset(bss, newsig); } @@ -150,9 +150,9 @@ bsd_to_ibcs2_sigset(bss, iss) int i, newsig; ibcs2_sigemptyset(iss); - for (i = 1; i < NSIG; i++) { + for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { if (sigismember(bss, i)) { - newsig = bsd_to_ibcs2_sig[i]; + newsig = bsd_to_ibcs2_sig[_SIG_IDX(i)]; if (newsig) ibcs2_sigaddset(iss, newsig); } @@ -215,9 +215,9 @@ ibcs2_sigaction(p, uap) } else nbsa = NULL; - SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, sig)]; - SCARG(&sa, nsa) = nbsa; - SCARG(&sa, osa) = obsa; + SCARG(&sa, sig) = ibcs2_to_bsd_sig[_SIG_IDX(SCARG(uap, sig))]; + SCARG(&sa, act) = nbsa; + SCARG(&sa, oact) = obsa; if ((error = sigaction(p, &sa)) != 0) return error; @@ -239,7 +239,7 @@ ibcs2_sigsys(p, uap) struct ibcs2_sigsys_args *uap; { struct sigaction sa; - int signum = ibcs2_to_bsd_sig[IBCS2_SIGNO(SCARG(uap, sig))]; + int signum = ibcs2_to_bsd_sig[_SIG_IDX(IBCS2_SIGNO(SCARG(uap, sig)))]; int error; caddr_t sg = stackgap_init(); @@ -265,11 +265,11 @@ ibcs2_sigsys(p, uap) case IBCS2_SIGHOLD_MASK: { - struct sigprocmask_args sa; + struct osigprocmask_args sa; SCARG(&sa, how) = SIG_BLOCK; SCARG(&sa, mask) = sigmask(signum); - return sigprocmask(p, &sa); + return osigprocmask(p, &sa); } case IBCS2_SIGNAL_MASK: @@ -289,9 +289,9 @@ ibcs2_sigsys(p, uap) ibcs2_sigset: nbsa = stackgap_alloc(&sg, sizeof(struct sigaction)); obsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = nbsa; - SCARG(&sa_args, osa) = obsa; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = nbsa; + SCARG(&sa_args, oact) = obsa; sa.sa_handler = SCARG(uap, fp); sigemptyset(&sa.sa_mask); @@ -319,7 +319,7 @@ ibcs2_sigsys(p, uap) if(sigismember(&p->p_sigmask, signum)) { /* return SIG_HOLD and unblock signal*/ p->p_retval[0] = (int)IBCS2_SIG_HOLD; - p->p_sigmask &= ~sigmask(signum); + SIGDELSET(p->p_sigmask, signum); } return 0; @@ -327,11 +327,11 @@ ibcs2_sigsys(p, uap) case IBCS2_SIGRELSE_MASK: { - struct sigprocmask_args sa; + struct osigprocmask_args sa; SCARG(&sa, how) = SIG_UNBLOCK; SCARG(&sa, mask) = sigmask(signum); - return sigprocmask(p, &sa); + return osigprocmask(p, &sa); } case IBCS2_SIGIGNORE_MASK: @@ -340,9 +340,9 @@ ibcs2_sigsys(p, uap) struct sigaction *bsa; bsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = bsa; - SCARG(&sa_args, osa) = NULL; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = bsa; + SCARG(&sa_args, oact) = NULL; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); @@ -358,10 +358,12 @@ ibcs2_sigsys(p, uap) case IBCS2_SIGPAUSE_MASK: { - struct sigsuspend_args sa; + osigset_t mask; + struct osigsuspend_args sa; - SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum); - return sigsuspend(p, &sa); + SIG2OSIG(p->p_sigmask, mask); + SCARG(&sa, mask) = mask &~ sigmask(signum); + return osigsuspend(p, &sa); } default: @@ -398,15 +400,17 @@ ibcs2_sigprocmask(p, uap) switch (SCARG(uap, how)) { case IBCS2_SIG_BLOCK: - p->p_sigmask |= bss & ~sigcantmask; + SIGSETOR(p->p_sigmask, bss); + SIG_CANTMASK(p->p_sigmask); break; case IBCS2_SIG_UNBLOCK: - p->p_sigmask &= ~bss; + SIGSETNAND(p->p_sigmask, bss); break; case IBCS2_SIG_SETMASK: - p->p_sigmask = bss & ~sigcantmask; + p->p_sigmask = bss; + SIG_CANTMASK(p->p_sigmask); break; default: @@ -427,7 +431,8 @@ ibcs2_sigpending(p, uap) sigset_t bss; ibcs2_sigset_t iss; - bss = p->p_siglist & p->p_sigmask; + bss = p->p_siglist; + SIGSETAND(bss, p->p_sigmask); bsd_to_ibcs2_sigset(&bss, &iss); return copyout(&iss, SCARG(uap, mask), sizeof(iss)); @@ -440,16 +445,17 @@ ibcs2_sigsuspend(p, uap) { ibcs2_sigset_t sss; sigset_t bss; - struct sigsuspend_args sa; + osigset_t mask; + struct osigsuspend_args sa; int error; if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0) return error; ibcs2_to_bsd_sigset(&sss, &bss); - - SCARG(&sa, mask) = bss; - return sigsuspend(p, &sa); + SIG2OSIG(bss, mask); + SCARG(&sa, mask) = mask; + return osigsuspend(p, &sa); } int @@ -457,10 +463,12 @@ ibcs2_pause(p, uap) register struct proc *p; struct ibcs2_pause_args *uap; { - struct sigsuspend_args bsa; + struct osigsuspend_args bsa; + osigset_t mask; - SCARG(&bsa, mask) = p->p_sigmask; - return sigsuspend(p, &bsa); + SIG2OSIG(p->p_sigmask, mask); + SCARG(&bsa, mask) = mask; + return osigsuspend(p, &bsa); } int @@ -471,6 +479,6 @@ ibcs2_kill(p, uap) struct kill_args ka; SCARG(&ka, pid) = SCARG(uap, pid); - SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)]; + SCARG(&ka, signum) = ibcs2_to_bsd_sig[_SIG_IDX(SCARG(uap, signo))]; return kill(p, &ka); } diff --git a/sys/i386/ibcs2/ibcs2_signal.h b/sys/i386/ibcs2/ibcs2_signal.h index a81fc7b381d..2eadf6cd72e 100644 --- a/sys/i386/ibcs2/ibcs2_signal.h +++ b/sys/i386/ibcs2/ibcs2_signal.h @@ -28,6 +28,8 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ */ #ifndef _IBCS2_SIGNAL_H @@ -56,6 +58,7 @@ #define IBCS2_SIGWINCH 20 #define IBCS2_SIGPOLL 22 #define IBCS2_NSIG 32 +#define IBCS2_SIGTBLSZ 32 /* * SCO-specific diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c index bed71d6fb9f..b1717f47a3b 100644 --- a/sys/i386/ibcs2/ibcs2_sysvec.c +++ b/sys/i386/ibcs2/ibcs2_sysvec.c @@ -36,9 +36,10 @@ #include #include #include -#include -extern int bsd_to_ibcs2_sig[]; +#include +#include + extern int bsd_to_ibcs2_errno[]; extern struct sysent ibcs2_sysent[IBCS2_SYS_MAXSYSCALL]; extern int szsigcode; @@ -48,7 +49,7 @@ struct sysentvec ibcs2_svr3_sysvec = { sizeof (ibcs2_sysent) / sizeof (ibcs2_sysent[0]), ibcs2_sysent, 0xFF, - NSIG, + IBCS2_SIGTBLSZ, bsd_to_ibcs2_sig, ELAST + 1, bsd_to_ibcs2_errno, diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index e55a3671c70..f581314412f 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -47,35 +47,32 @@ typedef struct { long val[2]; } linux_fsid_t; typedef int linux_pid_t; -typedef unsigned long linux_sigset_t; -typedef void (*linux_handler_t)(int); -typedef struct { - void (*lsa_handler)(int); - linux_sigset_t lsa_mask; - unsigned long lsa_flags; - void (*lsa_restorer)(void); -} linux_sigaction_t; typedef int linux_key_t; -typedef struct { - unsigned long sig[2]; -} linux_new_sigset_t; -typedef struct { - void (*lsa_handler)(int); - unsigned long lsa_flags; - void (*lsa_restorer)(void); - linux_new_sigset_t lsa_mask; -} linux_new_sigaction_t; +/* + * Signal stuff... + */ +typedef void (*linux_handler_t)(int); -#define LINUX_MAX_UTSNAME 65 -struct linux_new_utsname { - char sysname[LINUX_MAX_UTSNAME]; - char nodename[LINUX_MAX_UTSNAME]; - char release[LINUX_MAX_UTSNAME]; - char version[LINUX_MAX_UTSNAME]; - char machine[LINUX_MAX_UTSNAME]; - char domainname[LINUX_MAX_UTSNAME]; -}; +typedef unsigned long linux_osigset_t; + +typedef struct { + unsigned int __bits[2]; +} linux_sigset_t; + +typedef struct { + void (*lsa_handler)(int); + linux_osigset_t lsa_mask; + unsigned long lsa_flags; + void (*lsa_restorer)(void); +} linux_osigaction_t; + +typedef struct { + void (*lsa_handler)(int); + unsigned long lsa_flags; + void (*lsa_restorer)(void); + linux_sigset_t lsa_mask; +} linux_sigaction_t; /* * The Linux sigcontext, pretty much a standard 386 trapframe. @@ -121,20 +118,6 @@ struct linux_sigframe { extern int bsd_to_linux_signal[]; extern int linux_to_bsd_signal[]; -extern char linux_sigcode[]; -extern int linux_szsigcode; -extern const char linux_emul_path[]; - -extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; -extern struct sysentvec linux_sysvec; -extern struct sysentvec elf_linux_sysvec; - -/* dummy struct definitions */ -struct image_params; -struct trapframe; - -/* misc defines */ -#define LINUX_NAME_MAX 255 /* signal numbers */ #define LINUX_SIGHUP 1 @@ -170,7 +153,8 @@ struct trapframe; #define LINUX_SIGPOLL LINUX_SIGIO #define LINUX_SIGPWR 30 #define LINUX_SIGUNUSED 31 -#define LINUX_NSIG 32 +#define LINUX_NSIG 64 +#define LINUX_SIGTBLSZ 31 /* sigaction flags */ #define LINUX_SA_NOCLDSTOP 0x00000001 @@ -188,6 +172,35 @@ struct trapframe; #define LINUX_SIG_UNBLOCK 1 #define LINUX_SIG_SETMASK 2 +#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0 +#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig) +#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) + +extern char linux_sigcode[]; +extern int linux_szsigcode; +extern const char linux_emul_path[]; + +extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; +extern struct sysentvec linux_sysvec; +extern struct sysentvec elf_linux_sysvec; + +/* dummy struct definitions */ +struct image_params; +struct trapframe; + +#define LINUX_MAX_UTSNAME 65 +struct linux_new_utsname { + char sysname[LINUX_MAX_UTSNAME]; + char nodename[LINUX_MAX_UTSNAME]; + char release[LINUX_MAX_UTSNAME]; + char version[LINUX_MAX_UTSNAME]; + char machine[LINUX_MAX_UTSNAME]; + char domainname[LINUX_MAX_UTSNAME]; +}; + +/* misc defines */ +#define LINUX_NAME_MAX 255 + /* resource limits */ #define LINUX_RLIMIT_CPU 0 #define LINUX_RLIMIT_FSIZE 1 diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c index 018446d1619..04c3b4a84d5 100644 --- a/sys/i386/linux/linux_dummy.c +++ b/sys/i386/linux/linux_dummy.c @@ -102,7 +102,6 @@ DUMMY(rt_sigreturn); DUMMY(rt_sigpending); DUMMY(rt_sigtimedwait); DUMMY(rt_sigqueueinfo); -DUMMY(rt_sigsuspend); DUMMY(pread); DUMMY(pwrite); DUMMY(capget); diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index 919a5e74850..ff5ba447c6c 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,9 @@ #include +#define BSD_TO_LINUX_SIGNAL(sig) \ + (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) + static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, @@ -622,7 +626,9 @@ linux_clone(struct proc *p, struct linux_clone_args *args) exit_signal = args->flags & 0x000000ff; if (exit_signal >= LINUX_NSIG) return EINVAL; - exit_signal = linux_to_bsd_signal[exit_signal]; + + if (exit_signal <= LINUX_SIGTBLSZ) + exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; /* RFTHREAD probably not necessary here, but it shouldn't hurt either */ ff |= RFTHREAD; @@ -979,10 +985,10 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | - bsd_to_linux_signal[WTERMSIG(tmpstat)]; + BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | - (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); return copyout(&tmpstat, args->status, sizeof(int)); } else return 0; @@ -1015,17 +1021,17 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args) if ((error = wait4(p, &tmp)) != 0) return error; - p->p_siglist &= ~sigmask(SIGCHLD); + SIGDELSET(p->p_siglist, SIGCHLD); if (args->status) { if ((error = copyin(args->status, &tmpstat, sizeof(int))) != 0) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | - bsd_to_linux_signal[WTERMSIG(tmpstat)]; + BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | - (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); return copyout(&tmpstat, args->status, sizeof(int)); } else return 0; @@ -1312,7 +1318,7 @@ linux_sched_setscheduler(p, uap) #ifdef DEBUG printf("Linux-emul(%ld): sched_setscheduler(%d, %d, %p)\n", - (long)p->p_pid, uap->pid, uap->policy, (void *)uap->param); + (long)p->p_pid, uap->pid, uap->policy, (const void *)uap->param); #endif switch (uap->policy) { diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h index 2ae69ab9c83..48c4409b19b 100644 --- a/sys/i386/linux/linux_proto.h +++ b/sys/i386/linux/linux_proto.h @@ -183,22 +183,22 @@ struct linux_ustat_args { }; struct linux_sigaction_args { int sig; char sig_[PAD_(int)]; - struct linux_sigaction * nsa; char nsa_[PAD_(struct linux_sigaction *)]; - struct linux_sigaction * osa; char osa_[PAD_(struct linux_sigaction *)]; + linux_osigaction_t * nsa; char nsa_[PAD_(linux_osigaction_t *)]; + linux_osigaction_t * osa; char osa_[PAD_(linux_osigaction_t *)]; }; struct linux_siggetmask_args { register_t dummy; }; struct linux_sigsetmask_args { - linux_sigset_t mask; char mask_[PAD_(linux_sigset_t)]; + linux_osigset_t mask; char mask_[PAD_(linux_osigset_t)]; }; struct linux_sigsuspend_args { int restart; char restart_[PAD_(int)]; - linux_sigset_t oldmask; char oldmask_[PAD_(linux_sigset_t)]; - linux_sigset_t mask; char mask_[PAD_(linux_sigset_t)]; + linux_osigset_t oldmask; char oldmask_[PAD_(linux_osigset_t)]; + linux_osigset_t mask; char mask_[PAD_(linux_osigset_t)]; }; struct linux_sigpending_args { - linux_sigset_t * mask; char mask_[PAD_(linux_sigset_t *)]; + linux_osigset_t * mask; char mask_[PAD_(linux_osigset_t *)]; }; struct linux_setrlimit_args { u_int resource; char resource_[PAD_(u_int)]; @@ -338,8 +338,8 @@ struct linux_adjtimex_args { }; struct linux_sigprocmask_args { int how; char how_[PAD_(int)]; - linux_sigset_t * mask; char mask_[PAD_(linux_sigset_t *)]; - linux_sigset_t * omask; char omask_[PAD_(linux_sigset_t *)]; + linux_osigset_t * mask; char mask_[PAD_(linux_osigset_t *)]; + linux_osigset_t * omask; char omask_[PAD_(linux_osigset_t *)]; }; struct linux_create_module_args { register_t dummy; @@ -459,14 +459,14 @@ struct linux_rt_sigreturn_args { }; struct linux_rt_sigaction_args { int sig; char sig_[PAD_(int)]; - struct linux_new_sigaction * act; char act_[PAD_(struct linux_new_sigaction *)]; - struct linux_new_sigaction * oact; char oact_[PAD_(struct linux_new_sigaction *)]; + linux_sigaction_t * act; char act_[PAD_(linux_sigaction_t *)]; + linux_sigaction_t * oact; char oact_[PAD_(linux_sigaction_t *)]; size_t sigsetsize; char sigsetsize_[PAD_(size_t)]; }; struct linux_rt_sigprocmask_args { int how; char how_[PAD_(int)]; - struct linux_new_sigset * mask; char mask_[PAD_(struct linux_new_sigset *)]; - struct linux_new_sigset * omask; char omask_[PAD_(struct linux_new_sigset *)]; + linux_sigset_t * mask; char mask_[PAD_(linux_sigset_t *)]; + linux_sigset_t * omask; char omask_[PAD_(linux_sigset_t *)]; size_t sigsetsize; char sigsetsize_[PAD_(size_t)]; }; struct linux_rt_sigpending_args { @@ -479,7 +479,8 @@ struct linux_rt_sigqueueinfo_args { register_t dummy; }; struct linux_rt_sigsuspend_args { - register_t dummy; + linux_sigset_t * newset; char newset_[PAD_(linux_sigset_t *)]; + size_t sigsetsize; char sigsetsize_[PAD_(size_t)]; }; struct linux_pread_args { register_t dummy; diff --git a/sys/i386/linux/linux_signal.c b/sys/i386/linux/linux_signal.c index 9f2200e526a..39334a74640 100644 --- a/sys/i386/linux/linux_signal.c +++ b/sys/i386/linux/linux_signal.c @@ -38,382 +38,384 @@ #include #include -static sigset_t -linux_to_bsd_sigset(linux_sigset_t mask) { - int b, l; - sigset_t new = 0; +static void +linux_to_bsd_sigset(linux_sigset_t *lss, sigset_t *bss) +{ + int b, l; - for (l = 1; l < LINUX_NSIG; l++) { - if (mask & (1 << (l - 1))) { - if ((b = linux_to_bsd_signal[l])) - new |= (1 << (b - 1)); + SIGEMPTYSET(*bss); + bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); + bss->__bits[1] = lss->__bits[1]; + for (l = 1; l <= LINUX_SIGTBLSZ; l++) { + if (LINUX_SIGISMEMBER(*lss, l)) { + b = linux_to_bsd_signal[_SIG_IDX(l)]; + if (b) + SIGADDSET(*bss, b); + } } - } - return new; } -static linux_sigset_t -bsd_to_linux_sigset(sigset_t mask) { - int b, l; - sigset_t new = 0; +static void +bsd_to_linux_sigset(sigset_t *bss, linux_sigset_t *lss) +{ + int b, l; - for (b = 1; b < NSIG; b++) { - if (mask & (1 << (b - 1))) { - if ((l = bsd_to_linux_signal[b])) - new |= (1 << (l - 1)); + LINUX_SIGEMPTYSET(*lss); + lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); + lss->__bits[1] = bss->__bits[1]; + for (b = 1; b <= LINUX_SIGTBLSZ; b++) { + if (SIGISMEMBER(*bss, b)) { + l = bsd_to_linux_signal[_SIG_IDX(b)]; + if (l) + LINUX_SIGADDSET(*lss, l); + } } - } - return new; } static void linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa) { - bsa->sa_mask = linux_to_bsd_sigset(lsa->lsa_mask); - bsa->sa_handler = lsa->lsa_handler; - bsa->sa_flags = 0; - if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) - bsa->sa_flags |= SA_NOCLDSTOP; - if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) - bsa->sa_flags |= SA_NOCLDWAIT; - if (lsa->lsa_flags & LINUX_SA_SIGINFO) - bsa->sa_flags |= SA_SIGINFO; - if (lsa->lsa_flags & LINUX_SA_ONSTACK) - bsa->sa_flags |= SA_ONSTACK; - if (lsa->lsa_flags & LINUX_SA_RESTART) - bsa->sa_flags |= SA_RESTART; - if (lsa->lsa_flags & LINUX_SA_ONESHOT) - bsa->sa_flags |= SA_RESETHAND; - if (lsa->lsa_flags & LINUX_SA_NOMASK) - bsa->sa_flags |= SA_NODEFER; + + linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); + bsa->sa_handler = lsa->lsa_handler; + bsa->sa_flags = 0; + if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) + bsa->sa_flags |= SA_NOCLDSTOP; + if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) + bsa->sa_flags |= SA_NOCLDWAIT; + if (lsa->lsa_flags & LINUX_SA_SIGINFO) + bsa->sa_flags |= SA_SIGINFO; + if (lsa->lsa_flags & LINUX_SA_ONSTACK) + bsa->sa_flags |= SA_ONSTACK; + if (lsa->lsa_flags & LINUX_SA_RESTART) + bsa->sa_flags |= SA_RESTART; + if (lsa->lsa_flags & LINUX_SA_ONESHOT) + bsa->sa_flags |= SA_RESETHAND; + if (lsa->lsa_flags & LINUX_SA_NOMASK) + bsa->sa_flags |= SA_NODEFER; } static void bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa) { - lsa->lsa_handler = bsa->sa_handler; - lsa->lsa_restorer = NULL; /* unsupported */ - lsa->lsa_mask = bsd_to_linux_sigset(bsa->sa_mask); - lsa->lsa_flags = 0; - if (bsa->sa_flags & SA_NOCLDSTOP) - lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; - if (bsa->sa_flags & SA_NOCLDWAIT) - lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; - if (bsa->sa_flags & SA_SIGINFO) - lsa->lsa_flags |= LINUX_SA_SIGINFO; - if (bsa->sa_flags & SA_ONSTACK) - lsa->lsa_flags |= LINUX_SA_ONSTACK; - if (bsa->sa_flags & SA_RESTART) - lsa->lsa_flags |= LINUX_SA_RESTART; - if (bsa->sa_flags & SA_RESETHAND) - lsa->lsa_flags |= LINUX_SA_ONESHOT; - if (bsa->sa_flags & SA_NODEFER) - lsa->lsa_flags |= LINUX_SA_NOMASK; + + bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); + lsa->lsa_handler = bsa->sa_handler; + lsa->lsa_restorer = NULL; /* unsupported */ + lsa->lsa_flags = 0; + if (bsa->sa_flags & SA_NOCLDSTOP) + lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; + if (bsa->sa_flags & SA_NOCLDWAIT) + lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; + if (bsa->sa_flags & SA_SIGINFO) + lsa->lsa_flags |= LINUX_SA_SIGINFO; + if (bsa->sa_flags & SA_ONSTACK) + lsa->lsa_flags |= LINUX_SA_ONSTACK; + if (bsa->sa_flags & SA_RESTART) + lsa->lsa_flags |= LINUX_SA_RESTART; + if (bsa->sa_flags & SA_RESETHAND) + lsa->lsa_flags |= LINUX_SA_ONESHOT; + if (bsa->sa_flags & SA_NODEFER) + lsa->lsa_flags |= LINUX_SA_NOMASK; } 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_args sa_args; - int error; - caddr_t sg = stackgap_init(); + struct sigaction *nsa, *osa, sa; + struct sigaction_args sa_args; + int error; + caddr_t sg = stackgap_init(); - if (linux_sig <= 0 || linux_sig >= LINUX_NSIG) - return EINVAL; + if (linux_sig <= 0 || linux_sig > LINUX_NSIG) + return (EINVAL); - if (linux_osa) - osa = stackgap_alloc(&sg, sizeof(struct sigaction)); - else - osa = NULL; + if (linux_osa != NULL) + osa = stackgap_alloc(&sg, sizeof(struct sigaction)); + else + osa = NULL; - if (linux_nsa) { - nsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - linux_to_bsd_sigaction(linux_nsa, &sa); - error = copyout(&sa, nsa, sizeof(struct sigaction)); + 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); + } + else + nsa = NULL; + + if (linux_sig <= LINUX_SIGTBLSZ) + sa_args.sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; + else + sa_args.sig = linux_sig; + + sa_args.act = nsa; + sa_args.oact = osa; + error = sigaction(p, &sa_args); if (error) - return error; - } - else - nsa = NULL; + return (error); - sa_args.signum = linux_to_bsd_signal[linux_sig]; - sa_args.nsa = nsa; - sa_args.osa = osa; - error = sigaction(p, &sa_args); - 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) { - error = copyin(osa, &sa, sizeof(struct sigaction)); - if (error) - return error; - bsd_to_linux_sigaction(&sa, linux_osa); - } - - return 0; + return (0); } int linux_sigaction(struct proc *p, struct linux_sigaction_args *args) { - linux_sigaction_t nsa, osa; - int error; + linux_osigaction_t osa; + linux_sigaction_t act, oact; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): sigaction(%d, %p, %p)\n", - (long)p->p_pid, args->sig, (void *)args->nsa, (void *)args->osa); + printf("Linux-emul(%ld): sigaction(%d, %p, %p)\n", (long)p->p_pid, + args->sig, (void *)args->nsa, (void *)args->osa); #endif - if (args->nsa) { - error = copyin(args->nsa, &nsa, sizeof(linux_sigaction_t)); - if (error) - return error; - } + if (args->nsa != NULL) { + error = copyin(args->nsa, &osa, sizeof(linux_osigaction_t)); + if (error) + return (error); + act.lsa_handler = osa.lsa_handler; + act.lsa_flags = osa.lsa_flags; + act.lsa_restorer = osa.lsa_restorer; + LINUX_SIGEMPTYSET(act.lsa_mask); + act.lsa_mask.__bits[0] = osa.lsa_mask; + } - error = linux_do_sigaction(p, args->sig, - args->nsa ? &nsa : NULL, - args->osa ? &osa : NULL); - if (error) - return error; + error = linux_do_sigaction(p, args->sig, + args->nsa ? &act : NULL, + args->osa ? &oact : NULL); - if (args->osa) { - error = copyout(&osa, args->osa, sizeof(linux_sigaction_t)); - if (error) - return error; - } + if (args->osa != NULL && !error) { + osa.lsa_handler = oact.lsa_handler; + osa.lsa_flags = oact.lsa_flags; + osa.lsa_restorer = oact.lsa_restorer; + osa.lsa_mask = oact.lsa_mask.__bits[0]; + error = copyout(&osa, args->osa, sizeof(linux_osigaction_t)); + } - return 0; + return (error); } int linux_signal(struct proc *p, struct linux_signal_args *args) { - linux_sigaction_t nsa, osa; - int error; + linux_sigaction_t nsa, osa; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): signal(%d, %p)\n", - (long)p->p_pid, args->sig, (void *)args->handler); + printf("Linux-emul(%ld): signal(%d, %p)\n", + (long)p->p_pid, args->sig, (void *)args->handler); #endif - nsa.lsa_handler = args->handler; - nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; - nsa.lsa_mask = NULL; + nsa.lsa_handler = args->handler; + nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; + LINUX_SIGEMPTYSET(nsa.lsa_mask); - error = linux_do_sigaction(p, args->sig, &nsa, &osa); + error = linux_do_sigaction(p, args->sig, &nsa, &osa); + p->p_retval[0] = (int)osa.lsa_handler; - p->p_retval[0] = (int)osa.lsa_handler; - - return 0; + return (error); } int linux_rt_sigaction(struct proc *p, struct linux_rt_sigaction_args *args) { - linux_sigaction_t nsa, osa; - linux_new_sigaction_t new_sa; - int error; + linux_sigaction_t nsa, osa; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): rt_sigaction(%d, %p, %p, %d)\n", - (long)p->p_pid, args->sig, (void *)args->act, - (void *)args->oact, args->sigsetsize); + printf("Linux-emul(%ld): rt_sigaction(%d, %p, %p, %d)\n", + (long)p->p_pid, args->sig, (void *)args->act, + (void *)args->oact, args->sigsetsize); #endif - if (args->sigsetsize != sizeof(linux_new_sigset_t)) - return EINVAL; + if (args->sigsetsize != sizeof(linux_sigset_t)) + return (EINVAL); -#ifdef DEBUG - if (args->sig >= LINUX_NSIG) { - printf("LINUX(%ld): rt_sigaction: 64-bit signal (%d)\n", - (long)p->p_pid, args->sig); - } -#endif + if (args->act != NULL) { + error = copyin(args->act, &nsa, sizeof(linux_sigaction_t)); + if (error) + return (error); + } - if (args->act) { - error = copyin(args->act, &new_sa, sizeof(linux_new_sigaction_t)); - if (error) - return error; + error = linux_do_sigaction(p, args->sig, + args->act ? &nsa : NULL, + args->oact ? &osa : NULL); - nsa.lsa_handler = new_sa.lsa_handler; - nsa.lsa_mask = new_sa.lsa_mask.sig[0]; - nsa.lsa_flags = new_sa.lsa_flags; - nsa.lsa_restorer = new_sa.lsa_restorer; + if (args->oact != NULL && !error) { + error = copyout(&osa, args->oact, sizeof(linux_sigaction_t)); + } -#ifdef DEBUG - if (new_sa.lsa_mask.sig[1] != 0) - printf("LINUX(%ld): rt_sigaction: sig[1] = 0x%08lx\n", - (long)p->p_pid, new_sa.lsa_mask.sig[1]); -#endif - } - - error = linux_do_sigaction(p, args->sig, - args->act ? &nsa : NULL, - args->oact ? &osa : NULL); - if (error) - return error; - - if (args->oact) { - new_sa.lsa_handler = osa.lsa_handler; - new_sa.lsa_flags = osa.lsa_flags; - new_sa.lsa_restorer = osa.lsa_restorer; - new_sa.lsa_mask.sig[0] = osa.lsa_mask; - new_sa.lsa_mask.sig[1] = 0; - error = copyout(&osa, args->oact, sizeof(linux_new_sigaction_t)); - if (error) - return error; - } - - return 0; + return (error); } static int linux_do_sigprocmask(struct proc *p, int how, linux_sigset_t *new, linux_sigset_t *old) { - int error = 0, s; - sigset_t mask; + int error, s; + sigset_t mask; - p->p_retval[0] = 0; + error = 0; + p->p_retval[0] = 0; - if (old != NULL) - *old = bsd_to_linux_sigset(p->p_sigmask); + if (old != NULL) + bsd_to_linux_sigset(&p->p_sigmask, old); - if (new != NULL) { - mask = linux_to_bsd_sigset(*new); + if (new != NULL) { + linux_to_bsd_sigset(new, &mask); - s = splhigh(); + s = splhigh(); - switch (how) { - case LINUX_SIG_BLOCK: - p->p_sigmask |= (mask & ~sigcantmask); - break; - case LINUX_SIG_UNBLOCK: - p->p_sigmask &= ~mask; - break; - case LINUX_SIG_SETMASK: - p->p_sigmask = (mask & ~sigcantmask); - break; - default: - error = EINVAL; - break; + switch (how) { + case LINUX_SIG_BLOCK: + SIGSETOR(p->p_sigmask, mask); + SIG_CANTMASK(p->p_sigmask); + break; + case LINUX_SIG_UNBLOCK: + SIGSETNAND(p->p_sigmask, mask); + break; + case LINUX_SIG_SETMASK: + p->p_sigmask = mask; + SIG_CANTMASK(p->p_sigmask); + break; + default: + error = EINVAL; + break; + } + + splx(s); } - splx(s); - } - - return error; + return (error); } int linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args) { - linux_sigset_t mask; - linux_sigset_t omask; - int error; + linux_osigset_t mask; + linux_sigset_t set, oset; + int error; #ifdef DEBUG - printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); + printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); #endif - if (args->mask != NULL) { - error = copyin(args->mask, &mask, sizeof(linux_sigset_t)); - if (error) - return error; - } + if (args->mask != NULL) { + error = copyin(args->mask, &mask, sizeof(linux_osigset_t)); + if (error) + return (error); + LINUX_SIGEMPTYSET(set); + set.__bits[0] = mask; + } - error = linux_do_sigprocmask(p, args->how, - args->mask ? &mask : NULL, - args->omask ? &omask : NULL); + error = linux_do_sigprocmask(p, args->how, + args->mask ? &set : NULL, + args->omask ? &oset : NULL); - if (!error && args->omask != NULL) { - error = copyout(&omask, args->omask, sizeof(linux_sigset_t)); - } + if (args->omask != NULL && !error) { + mask = oset.__bits[0]; + error = copyout(&mask, args->omask, sizeof(linux_osigset_t)); + } - return error; + return (error); } int linux_rt_sigprocmask(struct proc *p, struct linux_rt_sigprocmask_args *args) { - linux_new_sigset_t new_mask; - linux_sigset_t old_mask; - int error; + linux_sigset_t set, oset; + int error; #ifdef DEBUG - printf("Linux-emul(%ld): rt_sigprocmask(%d, %p, %p, %d)\n", - (long)p->p_pid, args->how, (void *)args->mask, - (void *)args->omask, args->sigsetsize); + printf("Linux-emul(%ld): rt_sigprocmask(%d, %p, %p, %d)\n", + (long)p->p_pid, args->how, (void *)args->mask, + (void *)args->omask, args->sigsetsize); #endif - if (args->sigsetsize != sizeof(linux_new_sigset_t)) - return EINVAL; + if (args->sigsetsize != sizeof(linux_sigset_t)) + return EINVAL; - if (args->mask != NULL) { - error = copyin(args->mask, &new_mask, sizeof(linux_new_sigset_t)); - if (error) - return error; + if (args->mask != NULL) { + error = copyin(args->mask, &set, sizeof(linux_sigset_t)); + if (error) + return (error); + } -#ifdef DEBUG - if (new_mask.sig[1] != 0) - printf("LINUX(%ld): rt_sigprocmask: sig[1] = 0x%08lx\n", - (long)p->p_pid, new_mask.sig[1]); -#endif - } + error = linux_do_sigprocmask(p, args->how, + args->mask ? &set : NULL, + args->omask ? &oset : NULL); - error = linux_do_sigprocmask(p, args->how, - args->mask ? new_mask.sig : NULL, - args->omask ? &old_mask : NULL); + if (args->omask != NULL && !error) { + error = copyout(&oset, args->omask, sizeof(linux_sigset_t)); + } - if (!error && args->omask != NULL) { - new_mask.sig[0] = old_mask; - error = copyout(&new_mask, args->omask, sizeof(linux_new_sigset_t)); - } - - return error; + return (error); } int linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args) { + linux_sigset_t mask; + #ifdef DEBUG - printf("Linux-emul(%d): siggetmask()\n", p->p_pid); + printf("Linux-emul(%d): siggetmask()\n", p->p_pid); #endif - p->p_retval[0] = bsd_to_linux_sigset(p->p_sigmask); - return 0; + + bsd_to_linux_sigset(&p->p_sigmask, &mask); + p->p_retval[0] = mask.__bits[0]; + return (0); } int linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args) { - int s; - sigset_t mask; + linux_sigset_t lset; + sigset_t bset; + int s; #ifdef DEBUG - printf("Linux-emul(%ld): sigsetmask(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); + printf("Linux-emul(%ld): sigsetmask(%08lx)\n", + (long)p->p_pid, (unsigned long)args->mask); #endif - p->p_retval[0] = bsd_to_linux_sigset(p->p_sigmask); - mask = linux_to_bsd_sigset(args->mask); - s = splhigh(); - p->p_sigmask = mask & ~sigcantmask; - splx(s); - return 0; + bsd_to_linux_sigset(&p->p_sigmask, &lset); + p->p_retval[0] = lset.__bits[0]; + LINUX_SIGEMPTYSET(lset); + lset.__bits[0] = args->mask; + linux_to_bsd_sigset(&lset, &bset); + s = splhigh(); + p->p_sigmask = bset; + SIG_CANTMASK(p->p_sigmask); + splx(s); + return (0); } int linux_sigpending(struct proc *p, struct linux_sigpending_args *args) { - linux_sigset_t linux_sig; + sigset_t bset; + linux_sigset_t lset; + linux_osigset_t mask; #ifdef DEBUG - printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); + printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); #endif - linux_sig = bsd_to_linux_sigset(p->p_siglist & p->p_sigmask); - return copyout(&linux_sig, args->mask, sizeof(linux_sig)); + + bset = p->p_siglist; + SIGSETAND(bset, p->p_sigmask); + bsd_to_linux_sigset(&bset, &lset); + mask = lset.__bits[0]; + return (copyout(&mask, args->mask, sizeof(mask))); } /* @@ -424,43 +426,94 @@ linux_sigpending(struct proc *p, struct linux_sigpending_args *args) int linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args) { - struct sigsuspend_args tmp; + struct sigsuspend_args bsd; + sigset_t *sigmask; + linux_sigset_t mask; + caddr_t sg = stackgap_init(); #ifdef DEBUG - printf("Linux-emul(%ld): sigsuspend(%08lx)\n", - (long)p->p_pid, (unsigned long)args->mask); + printf("Linux-emul(%ld): sigsuspend(%08lx)\n", + (long)p->p_pid, (unsigned long)args->mask); #endif - tmp.mask = linux_to_bsd_sigset(args->mask); - return sigsuspend(p, &tmp); + + sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); + LINUX_SIGEMPTYSET(mask); + mask.__bits[0] = args->mask; + linux_to_bsd_sigset(&mask, sigmask); + bsd.sigmask = sigmask; + return (sigsuspend(p, &bsd)); +} + +int +linux_rt_sigsuspend(p, uap) + struct proc *p; + struct linux_rt_sigsuspend_args *uap; +{ + linux_sigset_t lmask; + sigset_t *bmask; + struct sigsuspend_args bsd; + caddr_t sg = stackgap_init(); + int error; + +#ifdef DEBUG + printf("Linux-emul(%ld): rt_sigsuspend(%p, %d)\n", (long)p->p_pid, + (void *)uap->newset, uap->sigsetsize); +#endif + + if (uap->sigsetsize != sizeof(linux_sigset_t)) + return (EINVAL); + + error = copyin(uap->newset, &lmask, sizeof(linux_sigset_t)); + if (error) + return (error); + + bmask = stackgap_alloc(&sg, sizeof(sigset_t)); + linux_to_bsd_sigset(&lmask, bmask); + bsd.sigmask = bmask; + return (sigsuspend(p, &bsd)); } int linux_pause(struct proc *p, struct linux_pause_args *args) { - struct sigsuspend_args tmp; + struct sigsuspend_args bsd; + sigset_t *sigmask; + caddr_t sg = stackgap_init(); #ifdef DEBUG - printf("Linux-emul(%d): pause()\n", p->p_pid); + printf("Linux-emul(%d): pause()\n", p->p_pid); #endif - tmp.mask = p->p_sigmask; - return sigsuspend(p, &tmp); + + sigmask = stackgap_alloc(&sg, sizeof(sigset_t)); + *sigmask = p->p_sigmask; + bsd.sigmask = sigmask; + return sigsuspend(p, &bsd); } int linux_kill(struct proc *p, struct linux_kill_args *args) { - struct kill_args /* { - int pid; - int signum; - } */ tmp; + struct kill_args /* { + int pid; + int signum; + } */ tmp; #ifdef DEBUG - printf("Linux-emul(%d): kill(%d, %d)\n", - p->p_pid, args->pid, args->signum); + printf("Linux-emul(%d): kill(%d, %d)\n", + p->p_pid, args->pid, args->signum); #endif - if (args->signum < 0 || args->signum >= LINUX_NSIG) - return EINVAL; - tmp.pid = args->pid; - tmp.signum = linux_to_bsd_signal[args->signum]; - return kill(p, &tmp); + + /* + * Allow signal 0 as a means to check for privileges + */ + if (args->signum < 0 || args->signum > LINUX_NSIG) + return EINVAL; + + if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) + tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; + else + tmp.signum = args->signum; + + tmp.pid = args->pid; + return (kill(p, &tmp)); } diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c index 92b7d009f42..d62b6161bc6 100644 --- a/sys/i386/linux/linux_sysent.c +++ b/sys/i386/linux/linux_sysent.c @@ -194,7 +194,7 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_rt_sigpending }, /* 176 = linux_rt_sigpending */ { 0, (sy_call_t *)linux_rt_sigtimedwait }, /* 177 = linux_rt_sigtimedwait */ { 0, (sy_call_t *)linux_rt_sigqueueinfo }, /* 178 = linux_rt_sigqueueinfo */ - { 0, (sy_call_t *)linux_rt_sigsuspend }, /* 179 = linux_rt_sigsuspend */ + { 2, (sy_call_t *)linux_rt_sigsuspend }, /* 179 = linux_rt_sigsuspend */ { 0, (sy_call_t *)linux_pread }, /* 180 = linux_pread */ { 0, (sy_call_t *)linux_pwrite }, /* 181 = linux_pwrite */ { 3, (sy_call_t *)linux_chown }, /* 182 = linux_chown */ diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 871ccfbed4c..ecaa359388b 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -64,7 +64,7 @@ static int elf_linux_fixup __P((long **stack_base, struct image_params *iparams)); static void linux_prepsyscall __P((struct trapframe *tf, int *args, u_int *code, caddr_t *params)); -static void linux_sendsig __P((sig_t catcher, int sig, int mask, +static void linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask, u_long code)); /* @@ -82,22 +82,26 @@ static int bsd_to_linux_errno[ELAST + 1] = { -6, -6, -43, -42, -75, -6, -84 }; -int bsd_to_linux_signal[NSIG] = { - 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, - LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0, - LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, - 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, - LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, - LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, - LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, - LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2 +int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { + LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, + LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, + LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0, + LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, + LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, + LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, + LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, + 0, LINUX_SIGUSR1, LINUX_SIGUSR2 }; -int linux_to_bsd_signal[LINUX_NSIG] = { - 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, - SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, - SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, - SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGURG, 0 +int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { + SIGHUP, SIGINT, SIGQUIT, SIGILL, + SIGTRAP, SIGABRT, SIGBUS, SIGFPE, + SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, + SIGPIPE, SIGALRM, SIGTERM, SIGBUS, + SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, + SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, + SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, + SIGIO, SIGURG, 0 }; /* @@ -185,7 +189,7 @@ extern int _ucodesel, _udatasel; */ static void -linux_sendsig(sig_t catcher, int sig, int mask, u_long code) +linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) { register struct proc *p = curproc; register struct trapframe *regs; @@ -197,14 +201,14 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; #ifdef DEBUG - printf("Linux-emul(%ld): linux_sendsig(%p, %d, %d, %lu)\n", - (long)p->p_pid, catcher, sig, mask, code); + printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n", + (long)p->p_pid, catcher, sig, (void*)mask, code); #endif /* * Allocate space for the signal handler context. */ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { + SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe)); psp->ps_sigstk.ss_flags |= SS_ONSTACK; @@ -224,10 +228,9 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) * instruction to halt it in its tracks. */ SIGACTION(p, SIGILL) = SIG_DFL; - sig = sigmask(SIGILL); - p->p_sigignore &= ~sig; - p->p_sigcatch &= ~sig; - p->p_sigmask &= ~sig; + SIGDELSET(p->p_sigignore, SIGILL); + SIGDELSET(p->p_sigcatch, SIGILL); + SIGDELSET(p->p_sigmask, SIGILL); psignal(p, SIGILL); return; } @@ -235,12 +238,9 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) /* * Build the argument list for the signal handler. */ - if (p->p_sysent->sv_sigtbl) { - if (sig < p->p_sysent->sv_sigsize) - sig = p->p_sysent->sv_sigtbl[sig]; - else - sig = p->p_sysent->sv_sigsize + 1; - } + if (p->p_sysent->sv_sigtbl) + if (sig <= p->p_sysent->sv_sigsize) + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; frame.sf_handler = catcher; frame.sf_sig = sig; @@ -248,7 +248,7 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code) /* * Build the signal context to be used by sigreturn. */ - frame.sf_sc.sc_mask = mask; + frame.sf_sc.sc_mask = mask->__bits[0]; frame.sf_sc.sc_gs = rgs(); frame.sf_sc.sc_fs = regs->tf_fs; frame.sf_sc.sc_es = regs->tf_es; @@ -355,8 +355,12 @@ linux_sigreturn(p, args) } p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - p->p_sigmask = context.sc_mask &~ - (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); + SIGEMPTYSET(p->p_sigmask); + p->p_sigmask.__bits[0] = context.sc_mask; + SIGDELSET(p->p_sigmask, SIGKILL); + SIGDELSET(p->p_sigmask, SIGCONT); + SIGDELSET(p->p_sigmask, SIGSTOP); + /* * Restore signal context. */ @@ -395,7 +399,7 @@ struct sysentvec linux_sysvec = { LINUX_SYS_MAXSYSCALL, linux_sysent, 0xff, - NSIG, + LINUX_SIGTBLSZ, bsd_to_linux_signal, ELAST + 1, bsd_to_linux_errno, @@ -410,19 +414,19 @@ struct sysentvec linux_sysvec = { }; struct sysentvec elf_linux_sysvec = { - LINUX_SYS_MAXSYSCALL, - linux_sysent, - 0xff, - NSIG, - bsd_to_linux_signal, - ELAST + 1, - bsd_to_linux_errno, - translate_traps, - elf_linux_fixup, - linux_sendsig, - linux_sigcode, - &linux_szsigcode, - linux_prepsyscall, + LINUX_SYS_MAXSYSCALL, + linux_sysent, + 0xff, + LINUX_SIGTBLSZ, + bsd_to_linux_signal, + ELAST + 1, + bsd_to_linux_errno, + translate_traps, + elf_linux_fixup, + linux_sendsig, + linux_sigcode, + &linux_szsigcode, + linux_prepsyscall, "Linux ELF", elf_coredump }; diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index ab7c20949f6..e8766a94b97 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -102,15 +102,16 @@ 65 NOPROTO LINUX { int getpgrp(void); } 66 NOPROTO LINUX { int setsid(void); } 67 STD LINUX { int linux_sigaction(int sig, \ - struct linux_sigaction *nsa, \ - struct linux_sigaction *osa); } + linux_osigaction_t *nsa, \ + linux_osigaction_t *osa); } 68 STD LINUX { int linux_siggetmask(void); } -69 STD LINUX { int linux_sigsetmask(linux_sigset_t mask); } +69 STD LINUX { int linux_sigsetmask(linux_osigset_t mask); } 70 NOPROTO LINUX { int setreuid(int ruid, int euid); } 71 NOPROTO LINUX { int setregid(int rgid, int egid); } 72 STD LINUX { int linux_sigsuspend(int restart, \ - linux_sigset_t oldmask, linux_sigset_t mask); } -73 STD LINUX { int linux_sigpending(linux_sigset_t *mask); } + linux_osigset_t oldmask, \ + linux_osigset_t mask); } +73 STD LINUX { int linux_sigpending(linux_osigset_t *mask); } 74 NOPROTO LINUX { int osethostname(char *hostname, u_int len); } 75 STD LINUX { int linux_setrlimit(u_int resource, \ struct ogetrlimit *rlim); } @@ -186,7 +187,8 @@ 124 STD LINUX { int linux_adjtimex(void); } 125 NOPROTO LINUX { int mprotect(caddr_t addr, int len, int prot); } 126 STD LINUX { int linux_sigprocmask(int how, \ - linux_sigset_t *mask, linux_sigset_t *omask); } + linux_osigset_t *mask, \ + linux_osigset_t *omask); } 127 STD LINUX { int linux_create_module(void); } 128 STD LINUX { int linux_init_module(void); } 129 STD LINUX { int linux_delete_module(void); } @@ -251,17 +253,17 @@ 172 STD LINUX { int linux_prctl(void); } 173 STD LINUX { int linux_rt_sigreturn(void); } 174 STD LINUX { int linux_rt_sigaction(int sig, \ - struct linux_new_sigaction *act, \ - struct linux_new_sigaction *oact, \ + linux_sigaction_t *act, \ + linux_sigaction_t *oact, \ size_t sigsetsize); } 175 STD LINUX { int linux_rt_sigprocmask(int how, \ - struct linux_new_sigset *mask, \ - struct linux_new_sigset *omask, \ + linux_sigset_t *mask, linux_sigset_t *omask, \ size_t sigsetsize); } 176 STD LINUX { int linux_rt_sigpending(void); } 177 STD LINUX { int linux_rt_sigtimedwait(void); } 178 STD LINUX { int linux_rt_sigqueueinfo(void); } -179 STD LINUX { int linux_rt_sigsuspend(void); } +179 STD LINUX { int linux_rt_sigsuspend(linux_sigset_t *newset, \ + size_t sigsetsize); } 180 STD LINUX { int linux_pread(void); } 181 STD LINUX { int linux_pwrite(void); } 182 STD LINUX { int linux_chown(char *path, int uid, int gid); } diff --git a/sys/i386/svr4/svr4_machdep.c b/sys/i386/svr4/svr4_machdep.c index 611828981ee..bc2e46962c1 100644 --- a/sys/i386/svr4/svr4_machdep.c +++ b/sys/i386/svr4/svr4_machdep.c @@ -78,7 +78,6 @@ extern char svr4_sigcode[]; extern int _udatasel, _ucodesel; static void svr4_getsiginfo __P((union svr4_siginfo *, int, u_long, caddr_t)); -extern int bsd_to_svr4_sig[]; #if !defined(__NetBSD__) /* taken from /sys/arch/i386/include/psl.h on NetBSD-1.3 */ @@ -105,7 +104,8 @@ void svr4_getcontext(p, uc, mask, oonstack) struct proc *p; struct svr4_ucontext *uc; - int mask, oonstack; + sigset_t *mask; + int oonstack; { struct trapframe *tf = p->p_md.md_regs; svr4_greg_t *r = uc->uc_mcontext.greg; @@ -171,7 +171,7 @@ svr4_getcontext(p, uc, mask, oonstack) /* * Set the signal mask */ - bsd_to_svr4_sigset(&mask, &uc->uc_sigmask); + bsd_to_svr4_sigset(mask, &uc->uc_sigmask); /* * Set the flags @@ -200,7 +200,7 @@ svr4_setcontext(p, uc) svr4_greg_t *r = uc->uc_mcontext.greg; struct svr4_sigaltstack *s = &uc->uc_stack; struct sigaltstack *sf = &psp->ps_sigstk; - int mask; + sigset_t mask; /* * XXX: @@ -276,7 +276,8 @@ svr4_setcontext(p, uc) */ if (uc->uc_flags & SVR4_UC_SIGMASK) { svr4_to_bsd_sigset(&uc->uc_sigmask, &mask); - p->p_sigmask = mask & ~sigcantmask; + p->p_sigmask = mask; + SIG_CANTMASK(p->p_sigmask); } return 0; /*EJUSTRETURN;*/ @@ -389,7 +390,8 @@ svr4_getsiginfo(si, sig, code, addr) void svr4_sendsig(catcher, sig, mask, code) sig_t catcher; - int sig, mask; + int sig; + sigset_t *mask; u_long code; { register struct proc *p = curproc; @@ -405,7 +407,7 @@ svr4_sendsig(catcher, sig, mask, code) * Allocate space for the signal handler context. */ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { + SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct svr4_sigframe *)((caddr_t)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct svr4_sigframe)); psp->ps_sigstk.ss_flags |= SS_ONSTACK; diff --git a/sys/i386/svr4/svr4_machdep.h b/sys/i386/svr4/svr4_machdep.h index f183e60a47a..5546d270dad 100644 --- a/sys/i386/svr4/svr4_machdep.h +++ b/sys/i386/svr4/svr4_machdep.h @@ -73,7 +73,7 @@ typedef struct { struct svr4_ucontext; void svr4_getcontext __P((struct proc *, struct svr4_ucontext *, - int, int)); + sigset_t *, int)); int svr4_setcontext __P((struct proc *p, struct svr4_ucontext *)); typedef struct { diff --git a/sys/svr4/svr4_misc.c b/sys/svr4/svr4_misc.c index 9535cba8972..9720abca1e5 100644 --- a/sys/svr4/svr4_misc.c +++ b/sys/svr4/svr4_misc.c @@ -100,7 +100,6 @@ #define BSD_DIRENT(cp) ((struct dirent *)(cp)) -extern int bsd_to_svr4_sig[]; static int svr4_mknod __P((struct proc *, register_t *, char *, svr4_mode_t, svr4_dev_t)); @@ -159,11 +158,11 @@ svr4_sys_wait(p, uap) if (WIFSIGNALED(st)) { sig = WTERMSIG(st); if (sig >= 0 && sig < NSIG) - st = (st & ~0177) | bsd_to_svr4_sig[sig]; + st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig); } else if (WIFSTOPPED(st)) { sig = WSTOPSIG(st); if (sig >= 0 && sig < NSIG) - st = (st & ~0xff00) | (bsd_to_svr4_sig[sig] << 8); + st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8); } /* @@ -1119,7 +1118,7 @@ svr4_setinfo(p, st, s) } else if (WIFSTOPPED(st)) { sig = WSTOPSIG(st); if (sig >= 0 && sig < NSIG) - i.si_status = bsd_to_svr4_sig[sig]; + i.si_status = SVR4_BSD2SVR4_SIG(sig); if (i.si_status == SVR4_SIGCONT) i.si_code = SVR4_CLD_CONTINUED; @@ -1128,7 +1127,7 @@ svr4_setinfo(p, st, s) } else { sig = WTERMSIG(st); if (sig >= 0 && sig < NSIG) - i.si_status = bsd_to_svr4_sig[sig]; + i.si_status = SVR4_BSD2SVR4_SIG(sig); if (WCOREDUMP(st)) i.si_code = SVR4_CLD_DUMPED; diff --git a/sys/svr4/svr4_signal.c b/sys/svr4/svr4_signal.c index b1239871942..5b8838c2572 100644 --- a/sys/svr4/svr4_signal.c +++ b/sys/svr4/svr4_signal.c @@ -47,24 +47,19 @@ #include #include -#define sigemptyset(s) memset((s), 0, sizeof(*(s))) -#define sigismember(s, n) (*(s) & sigmask(n)) -#define sigaddset(s, n) (*(s) |= sigmask(n)) - #define svr4_sigmask(n) (1 << (((n) - 1) & 31)) #define svr4_sigword(n) (((n) - 1) >> 5) #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s))) +#define svr4_sigfillset(s) memset((s), 0xffffffff, sizeof(*(s))) #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n)) #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n)) -static __inline void svr4_sigfillset __P((svr4_sigset_t *)); void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *, struct sigaction *)); void bsd_to_svr4_sigaction __P((const struct sigaction *, struct svr4_sigaction *)); -int bsd_to_svr4_sig[] = { - 0, +int bsd_to_svr4_sig[SVR4_SIGTBLSZ] = { SVR4_SIGHUP, SVR4_SIGINT, SVR4_SIGQUIT, @@ -98,8 +93,7 @@ int bsd_to_svr4_sig[] = { SVR4_SIGUSR2, }; -int svr4_to_bsd_sig[] = { - 0, +int svr4_to_bsd_sig[SVR4_SIGTBLSZ] = { SIGHUP, SIGINT, SIGQUIT, @@ -133,17 +127,6 @@ int svr4_to_bsd_sig[] = { SIGXFSZ, }; -static __inline void -svr4_sigfillset(s) - svr4_sigset_t *s; -{ - int i; - - svr4_sigemptyset(s); - for (i = 1; i < SVR4_NSIG; i++) - svr4_sigaddset(s, i); -} - void svr4_to_bsd_sigset(sss, bss) const svr4_sigset_t *sss; @@ -151,17 +134,20 @@ svr4_to_bsd_sigset(sss, bss) { int i, newsig; - sigemptyset(bss); - for (i = 1; i < SVR4_NSIG; i++) { + SIGEMPTYSET(*bss); + bss->__bits[0] = sss->bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1); + bss->__bits[1] = sss->bits[1]; + bss->__bits[2] = sss->bits[2]; + bss->__bits[3] = sss->bits[3]; + for (i = 1; i <= SVR4_SIGTBLSZ; i++) { if (svr4_sigismember(sss, i)) { - newsig = svr4_to_bsd_sig[i]; + newsig = svr4_to_bsd_sig[_SIG_IDX(i)]; if (newsig) - sigaddset(bss, newsig); + SIGADDSET(*bss, newsig); } } } - void bsd_to_svr4_sigset(bss, sss) const sigset_t *bss; @@ -170,16 +156,19 @@ bsd_to_svr4_sigset(bss, sss) int i, newsig; svr4_sigemptyset(sss); - for (i = 1; i < NSIG; i++) { - if (sigismember(bss, i)) { - newsig = bsd_to_svr4_sig[i]; + sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1); + sss->bits[1] = bss->__bits[1]; + sss->bits[2] = bss->__bits[2]; + sss->bits[3] = bss->__bits[3]; + for (i = 1; i <= SVR4_SIGTBLSZ; i++) { + if (SIGISMEMBER(*bss, i)) { + newsig = bsd_to_svr4_sig[_SIG_IDX(i)]; if (newsig) svr4_sigaddset(sss, newsig); } } } - /* * XXX: Only a subset of the flags is currently implemented. */ @@ -293,9 +282,9 @@ svr4_sys_sigaction(p, uap) } else nbsa = NULL; - SCARG(&sa, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; - SCARG(&sa, nsa) = nbsa; - SCARG(&sa, osa) = obsa; + SCARG(&sa, sig) = SVR4_SVR42BSD_SIG(SCARG(uap, signum)); + SCARG(&sa, act) = nbsa; + SCARG(&sa, oact) = obsa; if ((error = sigaction(p, &sa)) != 0) return error; @@ -342,7 +331,7 @@ svr4_sys_sigaltstack(p, uap) } else nbss = NULL; - SCARG(&sa, nss) = nbss; + SCARG(&sa, ss) = nbss; SCARG(&sa, oss) = obss; if ((error = sigaltstack(p, &sa)) != 0) @@ -367,12 +356,13 @@ svr4_sys_signal(p, uap) register struct proc *p; struct svr4_sys_signal_args *uap; { - int signum = svr4_to_bsd_sig[SVR4_SIGNO(SCARG(uap, signum))]; + int signum; int error, *retval; caddr_t sg = stackgap_init(); + signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(SCARG(uap, signum))); retval = p->p_retval; - if (signum <= 0 || signum >= SVR4_NSIG) + if (signum <= 0 || signum > SVR4_NSIG) return (EINVAL); switch (SVR4_SIGCALL(SCARG(uap, signum))) { @@ -388,12 +378,12 @@ svr4_sys_signal(p, uap) nbsa = stackgap_alloc(&sg, sizeof(struct sigaction)); obsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = nbsa; - SCARG(&sa_args, osa) = obsa; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = nbsa; + SCARG(&sa_args, oact) = obsa; sa.sa_handler = (sig_t) SCARG(uap, handler); - sigemptyset(&sa.sa_mask); + SIGEMPTYSET(sa.sa_mask); sa.sa_flags = 0; if (signum != SIGALRM) @@ -417,18 +407,28 @@ svr4_sys_signal(p, uap) sighold: { struct sigprocmask_args sa; + sigset_t *set; + set = stackgap_alloc(&sg, sizeof(sigset_t)); + SIGEMPTYSET(*set); + SIGADDSET(*set, signum); SCARG(&sa, how) = SIG_BLOCK; - SCARG(&sa, mask) = sigmask(signum); + SCARG(&sa, set) = set; + SCARG(&sa, oset) = NULL; return sigprocmask(p, &sa); } case SVR4_SIGRELSE_MASK: { struct sigprocmask_args sa; + sigset_t *set; + set = stackgap_alloc(&sg, sizeof(sigset_t)); + SIGEMPTYSET(*set); + SIGADDSET(*set, signum); SCARG(&sa, how) = SIG_UNBLOCK; - SCARG(&sa, mask) = sigmask(signum); + SCARG(&sa, set) = set; + SCARG(&sa, oset) = NULL; return sigprocmask(p, &sa); } @@ -438,12 +438,12 @@ sighold: struct sigaction *bsa, sa; bsa = stackgap_alloc(&sg, sizeof(struct sigaction)); - SCARG(&sa_args, signum) = signum; - SCARG(&sa_args, nsa) = bsa; - SCARG(&sa_args, osa) = NULL; + SCARG(&sa_args, sig) = signum; + SCARG(&sa_args, act) = bsa; + SCARG(&sa_args, oact) = NULL; sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); + SIGEMPTYSET(sa.sa_mask); sa.sa_flags = 0; if ((error = copyout(&sa, bsa, sizeof(sa))) != 0) return error; @@ -457,8 +457,12 @@ sighold: case SVR4_SIGPAUSE_MASK: { struct sigsuspend_args sa; + sigset_t *set; - SCARG(&sa, mask) = p->p_sigmask & ~sigmask(signum); + set = stackgap_alloc(&sg, sizeof(sigset_t)); + *set = p->p_sigmask; + SIGDELSET(*set, signum); + SCARG(&sa, sigmask) = set; return sigsuspend(p, &sa); } @@ -498,15 +502,17 @@ svr4_sys_sigprocmask(p, uap) switch (SCARG(uap, how)) { case SVR4_SIG_BLOCK: - p->p_sigmask |= bss & ~sigcantmask; + SIGSETOR(p->p_sigmask, bss); + SIG_CANTMASK(p->p_sigmask); break; case SVR4_SIG_UNBLOCK: - p->p_sigmask &= ~bss; + SIGSETNAND(p->p_sigmask, bss); break; case SVR4_SIG_SETMASK: - p->p_sigmask = bss & ~sigcantmask; + p->p_sigmask = bss; + SIG_CANTMASK(p->p_sigmask); break; default: @@ -533,7 +539,8 @@ svr4_sys_sigpending(p, uap) case 1: /* sigpending */ if (SCARG(uap, mask) == NULL) return 0; - bss = p->p_siglist & p->p_sigmask; + bss = p->p_siglist; + SIGSETAND(bss, p->p_sigmask); bsd_to_svr4_sigset(&bss, &sss); break; @@ -554,16 +561,18 @@ svr4_sys_sigsuspend(p, uap) struct svr4_sys_sigsuspend_args *uap; { svr4_sigset_t sss; - sigset_t bss; + sigset_t *bss; struct sigsuspend_args sa; int error; + caddr_t sg = stackgap_init(); if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0) return error; - svr4_to_bsd_sigset(&sss, &bss); + bss = stackgap_alloc(&sg, sizeof(sigset_t)); + svr4_to_bsd_sigset(&sss, bss); - SCARG(&sa, mask) = bss; + SCARG(&sa, sigmask) = bss; return sigsuspend(p, &sa); } @@ -576,7 +585,7 @@ svr4_sys_kill(p, uap) struct kill_args ka; SCARG(&ka, pid) = SCARG(uap, pid); - SCARG(&ka, signum) = svr4_to_bsd_sig[SCARG(uap, signum)]; + SCARG(&ka, signum) = SVR4_SVR42BSD_SIG(SCARG(uap, signum)); return kill(p, &ka); } @@ -592,7 +601,7 @@ svr4_sys_context(p, uap) switch (uap->func) { case 0: DPRINTF(("getcontext(%p)\n", uap->uc)); - svr4_getcontext(p, &uc, p->p_sigmask, + svr4_getcontext(p, &uc, &p->p_sigmask, p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK); return copyout(&uc, uap->uc, sizeof(uc)); @@ -620,6 +629,6 @@ svr4_sys_pause(p, uap) { struct sigsuspend_args bsa; - SCARG(&bsa, mask) = p->p_sigmask; + SCARG(&bsa, sigmask) = &p->p_sigmask; return sigsuspend(p, &bsa); } diff --git a/sys/svr4/svr4_signal.h b/sys/svr4/svr4_signal.h index 8fb861d2014..b7bb13269f4 100644 --- a/sys/svr4/svr4_signal.h +++ b/sys/svr4/svr4_signal.h @@ -68,7 +68,8 @@ #define SVR4_SIGPROF 29 #define SVR4_SIGXCPU 30 #define SVR4_SIGXFSZ 31 -#define SVR4_NSIG 32 +#define SVR4_NSIG 128 +#define SVR4_SIGTBLSZ 31 #define SVR4_SIGNO_MASK 0x00FF #define SVR4_SIGNAL_MASK 0x0000 @@ -91,6 +92,14 @@ typedef void (*svr4_sig_t) __P((int, svr4_siginfo_t *, void *)); #define SVR4_SIG_UNBLOCK 2 #define SVR4_SIG_SETMASK 3 +extern int bsd_to_svr4_sig[]; +extern int svr4_to_bsd_sig[]; + +#define SVR4_BSD2SVR4_SIG(sig) \ + (((sig) <= SVR4_SIGTBLSZ) ? bsd_to_svr4_sig[_SIG_IDX(sig)] : sig) +#define SVR4_SVR42BSD_SIG(sig) \ + (((sig) <= SVR4_SIGTBLSZ) ? svr4_to_bsd_sig[_SIG_IDX(sig)] : sig) + typedef struct { u_long bits[4]; } svr4_sigset_t; @@ -127,6 +136,6 @@ void bsd_to_svr4_sigaltstack __P((const struct sigaltstack *, struct svr4_sigalt void bsd_to_svr4_sigset __P((const sigset_t *, svr4_sigset_t *)); void svr4_to_bsd_sigaltstack __P((const struct svr4_sigaltstack *, struct sigaltstack *)); void svr4_to_bsd_sigset __P((const svr4_sigset_t *, sigset_t *)); -void svr4_sendsig(sig_t, int, int, u_long); +void svr4_sendsig(sig_t, int, sigset_t *, u_long); #endif /* !_SVR4_SIGNAL_H_ */ diff --git a/sys/svr4/svr4_sysvec.c b/sys/svr4/svr4_sysvec.c index 099bb9c4dfa..6a2bc03d9bf 100644 --- a/sys/svr4/svr4_sysvec.c +++ b/sys/svr4/svr4_sysvec.c @@ -72,9 +72,6 @@ #include #include -extern int bsd_to_svr4_sig[]; -extern int svr4_to_bsd_sig[]; - int bsd_to_svr4_errno[ELAST+1] = { 0, SVR4_EPERM, @@ -176,7 +173,7 @@ struct sysentvec svr4_sysvec = { SVR4_SYS_MAXSYSCALL, svr4_sysent, 0xff, - NSIG, + SVR4_SIGTBLSZ, bsd_to_svr4_sig, ELAST, /* ELAST */ bsd_to_svr4_errno,