/* * Process the signal() function from iBCS * * This version appeared in "Advanced Programming in the Unix Environment" * by W. Richard Stevens, page 298. */ void abi_sig_handler(struct pt_regs *regp, int sig, __sighandler_t handler, int oneshot) { struct sigaction act, oact; mm_segment_t fs; int error; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; act.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction); if (act.sa_restorer) act.sa_flags |= SA_RESTORER; act.sa_handler = handler; if (oneshot) act.sa_flags |= SA_ONESHOT | SA_NOMASK; fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigaction,sig, &act, &oact, sizeof(sigset_t)); set_fs(fs); if (error < 0) { set_error(regp, iABI_errors(-error)); } else { set_result(regp, (int)((long)oact.sa_handler)); } }
void abi_sigpause (struct pt_regs * regs) { old_sigset_t newset; int sig, answer; #ifdef __sparc__ printk(KERN_ERR "Sparc/iBCS: sigpause not yet implemented\n"); #else if (!abi_signo(regs, &sig)) return; newset = ~0UL; newset &= (1UL << (sig-1)); answer = SYS(sigsuspend)(0, current->blocked, newset, regs->esi, regs->edi, regs->ebp, regs->eax, regs->xds, regs->xes, regs->orig_eax, regs->eip, regs->xcs, regs->eflags, regs->esp, regs->xss); if (answer < 0) { set_error(regs, iABI_errors(-answer)); } #endif }
/* * Process the iBCS sigignore * * This is basically a signal (...,SIG_IGN) call. */ void abi_sigignore(struct pt_regs *regp) { struct sigaction act, oact; int error, sig; mm_segment_t fs; if (!abi_signo(regp, &sig)) return; sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; act.sa_flags = SA_SIGINFO; act.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction); if (act.sa_restorer) act.sa_flags |= SA_RESTORER; fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigaction,sig, &act, &oact, sizeof(sigset_t)); set_fs(fs); if (error < 0) set_error(regp, iABI_errors(-error)); }
/* * Process the iBCS sigset function. * * This is basically the same as the signal() routine with the exception * that it will accept a SIG_HOLD parameter. * * A SIG_HOLD will defer the processing of the signal until a sigrelse() * function is called. */ int abi_sigset (struct pt_regs * regs) { sigset_t newmask, oldmask; __sighandler_t vec; int sig, answer; mm_segment_t old_fs; if (abi_signo (regs, &sig)) { vec = (__sighandler_t) SECOND_PARAM; if (vec != SIG_HOLD) { deactivate_signal(current, sig); abi_sig_handler (regs, sig, vec, 0); } else { /* * Process the hold function */ sigemptyset (&newmask); sigaddset (&newmask, sig); TO_KERNEL (old_fs); answer = SYS(rt_sigprocmask) (SIG_BLOCK, &newmask, &oldmask, sizeof(sigset_t)); FROM_KERNEL (old_fs); if (answer < 0) { set_error (regs, iABI_errors (-answer)); } } } return 0; }
void abi_sig_handler (struct pt_regs * regs, int sig, __sighandler_t handler, int oneshot) { struct sigaction act, oact; int answer; mm_segment_t old_fs; sigemptyset (&act.sa_mask); act.sa_restorer = NULL; act.sa_handler = handler; act.sa_flags = 0; if (oneshot) act.sa_flags = SA_ONESHOT | SA_NOMASK; else act.sa_flags = 0; TO_KERNEL (old_fs); answer = SYS(rt_sigaction) (sig, &act, &oact, sizeof(sigset_t)); FROM_KERNEL (old_fs); if (answer < 0) { set_error (regs, iABI_errors (-answer)); } else set_result (regs, (int) oact.sa_handler); }
static void timod_error(int fd, int prim, int terr, int uerr) { struct file *fp; struct T_primsg *it; struct T_error_ack *err; #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_STREAMS, "TI: %u error prim=%d, TLI=%d, UNIX=%d\n", fd, prim, terr, uerr); #endif fp = fcheck(fd); it = timod_mkctl(sizeof(struct T_error_ack)); if (!it) return; err = (struct T_error_ack *)&it->type; err->PRIM_type = T_ERROR_ACK; err->ERROR_prim = prim; err->TLI_error = terr; err->UNIX_error = iABI_errors(uerr); it->pri = MSG_HIPRI; it->length = sizeof(struct T_error_ack); it->next = Priv(fp)->pfirst; Priv(fp)->pfirst = it; if (!Priv(fp)->plast) Priv(fp)->plast = it; timod_socket_wakeup(fp); }
void cxenix(struct pt_regs *regs) { int sysno = regs->eax >> 8; if (sysno >= ARRAY_SIZE(cxenix_table)) set_error(regs, iABI_errors(-EINVAL)); else lcall7_dispatch(regs, &cxenix_table[sysno], 1); }
static asmlinkage void isc_lcall7(int segment, struct pt_regs *regs) { int sysno = _AX(regs) & 0xff; if (sysno >= ARRAY_SIZE(isc_syscall_table)) set_error(regs, iABI_errors(-EINVAL)); else lcall7_dispatch(regs, &isc_syscall_table[sysno], 1); }
static void uw7_lcall7(int segment, struct pt_regs *regs) { int sysno = regs->eax & 0xff; if (sysno >= ARRAY_SIZE(uw7_syscall_table)) set_error(regs, iABI_errors(-EINVAL)); else lcall7_dispatch(regs, &uw7_syscall_table[sysno], 1); }
inline int abi_signo (struct pt_regs *regs, int *sig) { int value = abi_mapsig(SIGNAL_NUMBER & 0xFF); if (value == -1) { set_error (regs, iABI_errors (EINVAL)); return 0; } *sig = value; return 1; }
static void isc_sysisc(struct pt_regs *regs) { int sysno; __get_user(sysno, ((unsigned long *)_SP(regs))+1); if (sysno >= ARRAY_SIZE(sysisc_table)) set_error(regs, iABI_errors(-EINVAL)); else lcall7_dispatch(regs, &sysisc_table[sysno], 2); }
/* * Either we want this static or in a header... */ __inline int abi_signo(struct pt_regs *regp, int *sigp) { int value; value = abi_mapsig(SIGNAL_NUMBER(regp) & 0xFF); if (value == -1) { set_error(regp, iABI_errors(EINVAL)); return 0; } else { *sigp = value; return 1; } }
/* * Process the iBCS sigpause * * Wait for the signal indicated to arrive before resuming the * processing. I do not know if the signal is processed first using * the normal event processing before the return. If someone can * shed some light on this then please correct this code. I block * the signal and look for it to show up in the pending list. */ void abi_sigpause(struct pt_regs *regs) { old_sigset_t newset; int error, sig; if (!abi_signo(regs, &sig)) return; newset = (~0UL) & (1UL << (sig-1)); #ifdef CONFIG_65BIT error = 0; #else error = SYS(sigsuspend,0, current->blocked.sig[0], newset); #endif if (error < 0) set_error(regs, iABI_errors(-error)); }
/* * Process the iBCS sigrelse. * * Re-enable the signal processing from a previously suspended * signal. This may have been done by calling the sighold() function * or a longjmp() during the signal processing routine. If you do a * longjmp() function then it is expected that you will call sigrelse * before going on with the program. */ void abi_sigrelse (struct pt_regs * regs) { sigset_t newmask, oldmask; int sig, answer; mm_segment_t old_fs; if (!abi_signo (regs, &sig)) return; sigemptyset (&newmask); sigaddset (&newmask, sig); TO_KERNEL (old_fs); answer = SYS(rt_sigprocmask) (SIG_UNBLOCK, &newmask, &oldmask, sizeof(sigset_t)); FROM_KERNEL (old_fs); if (answer < 0) { set_error (regs, iABI_errors (-answer)); } }
/* * Process the iBCS sigrelse. * * Re-enable the signal processing from a previously suspended * signal. This may have been done by calling the sighold() function * or a longjmp() during the signal processing routine. If you do a * longjmp() function then it is expected that you will call sigrelse * or set the handler again using sigset before going on with the program. */ void abi_sigrelse(struct pt_regs *regp) { sigset_t newmask, oldmask; int error, sig; mm_segment_t fs; if (!abi_signo(regp, &sig)) return; sigemptyset(&newmask); sigaddset(&newmask, sig); fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigprocmask,SIG_UNBLOCK, &newmask, &oldmask, sizeof(sigset_t)); set_fs(fs); if (error < 0) set_error(regp, iABI_errors(-error)); }
/* * Process the SVR4 sigset function. * * This is basically the same as the signal() routine with the * exception that it will accept a SIG_HOLD parameter. * * A SIG_HOLD will defer the processing of the signal until a sigrelse() * function is called or the signal handler is set again using this function. */ int abi_sigset(struct pt_regs *regp) { int sig, error; sigset_t newmask, oldmask; __sighandler_t vec; mm_segment_t fs; int action; if (abi_signo(regp, &sig) == 0) return 0; vec = (__sighandler_t)SECOND_PARAM(regp); action = SIG_BLOCK; if (vec != SIG_HOLD) { action = SIG_UNBLOCK; deactivate_signal(current, sig); abi_sig_handler(regp, sig, vec, 0); } /* * Process the signal hold/unhold function. */ sigemptyset(&newmask); sigaddset(&newmask, sig); fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigprocmask,action, &newmask, &oldmask, sizeof(sigset_t)); set_fs(fs); if (error < 0) set_error(regp, iABI_errors(-error)); return 0; }
void abi_sigignore (struct pt_regs * regs) { struct sigaction act, oact; int sig, answer; mm_segment_t old_fs; if (!abi_signo (regs, &sig)) return; sigemptyset (&act.sa_mask); act.sa_restorer = NULL; act.sa_handler = SIG_IGN; act.sa_flags = 0; TO_KERNEL (old_fs); answer = SYS(rt_sigaction) (sig, &act, &oact, sizeof(sigset_t)); FROM_KERNEL (old_fs); if (answer < 0) { set_error (regs, iABI_errors (-answer)); } }
int svr4_shmsys(struct pt_regs *regp) { int arg1, arg2, arg3, cmd, err = 0; u_long raddr; mm_segment_t fs; cmd = get_syscall_parameter(regp, 0); if (cmd == SVR4_shmdt) { err = svr4_shmdt(regp); goto out; } arg1 = get_syscall_parameter(regp, 1); arg2 = get_syscall_parameter(regp, 2); arg3 = get_syscall_parameter(regp, 3); switch (cmd) { case SVR4_shmat: #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmat(%d, %x, %o)\n", arg1, arg2, arg3); #endif fs = get_fs(); set_fs(get_ds()); #ifdef CONFIG_65BIT err = SYS(shmat, arg1, arg2, arg3, &raddr); #else err = SYS(ipc,SHMAT+0x10000,arg1,arg3,&raddr,arg2); #endif set_fs(fs); if (err >= 0) err = (int)raddr; #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmat returns %x\n", err); #endif break; case SVR4_shmget: #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmget(%d, %x, %o)\n", arg1, arg2, arg3); #endif #ifdef CONFIG_65BIT err = SYS(shmget, arg1, arg2, arg3); #else err = SYS(ipc,SHMGET,arg1, arg2, arg3); #endif #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "shmget returns %d\n", err); #endif break; case SVR4_shmctl: err = svr4_shmctl(arg1, arg2, (char *)((long)arg3)); break; default: #if defined(CONFIG_ABI_TRACE) __abi_trace("shmsys: unsupported command: %x\n", cmd); #endif err = -EINVAL; } out: if (err < 0 && err > -255) { set_error(regp, iABI_errors(-err)); #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_API, "Error %d\n", get_result(regp)); #endif return 0; } clear_error(regp); set_result(regp, err); return 0; }
int svr4_shmsys(struct pt_regs * regs) { int command = get_syscall_parameter (regs, 0); int arg1, arg2, arg3; mm_segment_t old_fs; long retval = 0; char *addr = 0; arg1 = arg2 = arg3 = 0; switch (command) { case U_SHMAT: case U_SHMCTL: case U_SHMGET: arg1 = get_syscall_parameter (regs, 1); arg2 = get_syscall_parameter (regs, 2); arg3 = get_syscall_parameter (regs, 3); break; case U_SHMDT: addr = (char *) get_syscall_parameter (regs, 1); break; default: printk(KERN_ERR "%d iBCS: bad SHM command %d\n", current->pid, command); retval = -EINVAL; goto test_exit; } switch (command) { case U_SHMAT: { #ifdef IPCCALL unsigned long raddr; #endif #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: ibcs_shmat: args: %d %x %o \n", current->pid, arg1, arg2, arg3); #endif /* * raddr = 0 tells sys_shmat to limit to 2G * and we are IBCS, no raddr value to return */ #ifdef IPCCALL old_fs = get_fs(); set_fs(get_ds()); retval = SYS (ipc) (IPCCALL(1,SHMAT), arg1, arg3, &raddr, (char *) arg2); set_fs(old_fs); if (retval >= 0) retval = raddr; #else retval = SYS (ipc) (SHMAT, arg1, arg3, 0, (char *) arg2); #endif #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: ibcs_shmat: return val is %lx\n", current->pid, retval); #endif goto test_exit; } case U_SHMGET: #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: ibcs_shmget: args: %d %x %o \n", current->pid, arg1, arg2, arg3); #endif retval = SYS (ipc) (SHMGET, arg1, arg2, arg3, 0); goto test_exit; case U_SHMDT: #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: ibcs_shmdt: arg: %lx\n", current->pid, (unsigned long)addr); #endif retval = SYS (ipc) (SHMDT, 0, 0, 0, addr); goto test_exit; case U_SHMCTL: #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: ibcs_shmctl: args: %d %x %o %d %x\n", current->pid, arg1, arg2, arg3, arg3, arg3); #endif switch (arg2) { case U_SHMLOCK: retval = SYS (ipc) (SHMCTL, arg1, SHM_LOCK, 0, arg3); goto test_exit; case U_SHMUNLOCK: retval = SYS (ipc) (SHMCTL, arg1, SHM_UNLOCK, 0, arg3); goto test_exit; case U_IPC_SET: { struct ibcs_shmid_ds is; struct shmid_ds ls; retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is)); if (retval) goto test_exit; copy_from_user(&is, (char *)arg3, sizeof(is)); ishm_to_lshm(&is, &ls); old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls); set_fs(old_fs); if (retval < 0) goto test_exit; lshm_to_ishm(&ls, &is); copy_to_user((char *)arg3, &is, sizeof(is)); goto test_exit; } case U_IPC_SET_L: { struct ibcs_shmid_ds_l is; struct shmid_ds ls; retval = verify_area(VERIFY_WRITE, (char *)arg3, sizeof(is)); if (retval) goto test_exit; copy_from_user(&is, (char *)arg3, sizeof(is)); ishm_to_lshm_l(&is, &ls); old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (SHMCTL, arg1, IPC_SET, 0, &ls); set_fs(old_fs); if (retval < 0) goto test_exit; lshm_to_ishm_l(&ls, &is); copy_to_user((char *)arg3, &is, sizeof(is)); goto test_exit; } case U_IPC_RMID: case U_IPC_RMID_L: retval = SYS (ipc) (SHMCTL, arg1, IPC_RMID, arg3); goto test_exit; case U_IPC_STAT: { struct ibcs_shmid_ds is; struct shmid_ds ls; old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls); set_fs(old_fs); if (retval < 0) goto test_exit; lshm_to_ishm(&ls, &is); retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0; goto test_exit; } case U_IPC_STAT_L: { struct ibcs_shmid_ds_l is; struct shmid_ds ls; old_fs = get_fs(); set_fs (get_ds()); retval = SYS (ipc) (SHMCTL, arg1, IPC_STAT, 0, &ls); set_fs(old_fs); if (retval < 0) goto test_exit; lshm_to_ishm_l(&ls, &is); retval = copy_to_user((char *)arg3, &is, sizeof(is)) ? -EFAULT : 0; goto test_exit; } default: printk(KERN_ERR "%d iBCS: ibcs_shmctl: unsupported command %d\n", current->pid, arg2); } retval = -EINVAL; goto test_exit; default: #ifdef CONFIG_ABI_TRACE printk(KERN_DEBUG "%d iBCS: ibcs_shm: command: %x\n", current->pid, command); #endif retval = -EINVAL; goto test_exit; } test_exit:; if ((retval < 0) && (retval > -255)) { set_error (regs, iABI_errors (-retval)); #ifdef CONFIG_ABI_TRACE if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) printk(KERN_DEBUG "%d iBCS: Error %ld\n", current->pid, get_result (regs)); #endif } else { clear_error (regs); set_result (regs, retval); } return 0; }