📄 irixsig.c
字号:
while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); if (do_irix_signal(&saveset, regs)) return -EINTR; }}/* hate hate hate... */struct irix5_siginfo { int sig, code, error; union { char unused[128 - (3 * 4)]; /* Safety net. */ struct { int pid; union { int uid; struct { int utime, status, stime; } child; } procdata; } procinfo; unsigned long fault_addr; struct { int fd; long band; } fileinfo; unsigned long sigval; } stuff;};asmlinkage int irix_sigpoll_sys(unsigned long __user *set, struct irix5_siginfo __user *info, struct timespec __user *tp){ long expire = MAX_SCHEDULE_TIMEOUT; sigset_t kset; int i, sig, error, timeo = 0; struct timespec ktp;#ifdef DEBUG_SIG printk("[%s:%d] irix_sigpoll_sys(%p,%p,%p)\n", current->comm, current->pid, set, info, tp);#endif /* Must always specify the signal set. */ if (!set) return -EINVAL; if (copy_from_user(&kset, set, sizeof(set))) return -EFAULT; if (info && clear_user(info, sizeof(*info))) { error = -EFAULT; goto out; } if (tp) { if (copy_from_user(&ktp, tp, sizeof(*tp))) return -EFAULT; if (!ktp.tv_sec && !ktp.tv_nsec) return -EINVAL; expire = timespec_to_jiffies(&ktp) + (ktp.tv_sec || ktp.tv_nsec); } while(1) { long tmp = 0; expire = schedule_timeout_interruptible(expire); for (i=0; i<=4; i++) tmp |= (current->pending.signal.sig[i] & kset.sig[i]); if (tmp) break; if (!expire) { timeo = 1; break; } if (signal_pending(current)) return -EINTR; } if (timeo) return -EAGAIN; for (sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { if (sigismember (&kset, sig)) continue; if (sigismember (¤t->pending.signal, sig)) { /* XXX need more than this... */ if (info) return copy_to_user(&info->sig, &sig, sizeof(sig)); return 0; } } /* Should not get here, but do something sane if we do. */ error = -EINTR;out: return error;}/* This is here because of irix5_siginfo definition. */#define IRIX_P_PID 0#define IRIX_P_PGID 2#define IRIX_P_ALL 7extern int getrusage(struct task_struct *, int, struct rusage __user *);#define W_EXITED 1#define W_TRAPPED 2#define W_STOPPED 4#define W_CONT 8#define W_NOHANG 64#define W_MASK (W_EXITED | W_TRAPPED | W_STOPPED | W_CONT | W_NOHANG)asmlinkage int irix_waitsys(int type, int pid, struct irix5_siginfo __user *info, int options, struct rusage __user *ru){ int flag, retval; DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; struct task_struct *p; struct list_head *_p; if (!info) return -EINVAL; if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) return -EFAULT; if (ru) if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru))) return -EFAULT; if (options & ~W_MASK) return -EINVAL; if (type != IRIX_P_PID && type != IRIX_P_PGID && type != IRIX_P_ALL) return -EINVAL; add_wait_queue(¤t->signal->wait_chldexit, &wait);repeat: flag = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); tsk = current; list_for_each(_p,&tsk->children) { p = list_entry(_p,struct task_struct,sibling); if ((type == IRIX_P_PID) && p->pid != pid) continue; if ((type == IRIX_P_PGID) && process_group(p) != pid) continue; if ((p->exit_signal != SIGCHLD)) continue; flag = 1; switch (p->state) { case TASK_STOPPED: if (!p->exit_code) continue; if (!(options & (W_TRAPPED|W_STOPPED)) && !(p->ptrace & PT_PTRACED)) continue; read_unlock(&tasklist_lock); /* move to end of parent's list to avoid starvation */ write_lock_irq(&tasklist_lock); remove_parent(p); add_parent(p); write_unlock_irq(&tasklist_lock); retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; if (retval) goto end_waitsys; retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(0, &info->code); retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); if (retval) goto end_waitsys; p->exit_code = 0; goto end_waitsys; case EXIT_ZOMBIE: current->signal->cutime += p->utime + p->signal->cutime; current->signal->cstime += p->stime + p->signal->cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); retval = __put_user(SIGCHLD, &info->sig); retval |= __put_user(1, &info->code); /* CLD_EXITED */ retval |= __put_user(p->pid, &info->stuff.procinfo.pid); retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); if (retval) return retval; if (p->real_parent != p->parent) { write_lock_irq(&tasklist_lock); remove_parent(p); p->parent = p->real_parent; add_parent(p); do_notify_parent(p, SIGCHLD); write_unlock_irq(&tasklist_lock); } else release_task(p); goto end_waitsys; default: continue; } tsk = next_thread(tsk); } read_unlock(&tasklist_lock); if (flag) { retval = 0; if (options & W_NOHANG) goto end_waitsys; retval = -ERESTARTSYS; if (signal_pending(current)) goto end_waitsys; current->state = TASK_INTERRUPTIBLE; schedule(); goto repeat; } retval = -ECHILD;end_waitsys: current->state = TASK_RUNNING; remove_wait_queue(¤t->signal->wait_chldexit, &wait); return retval;}struct irix5_context { u32 flags; u32 link; u32 sigmask[4]; struct { u32 sp, size, flags; } stack; int regs[36]; u32 fpregs[32]; u32 fpcsr; u32 _unused0; u32 _unused1[47]; u32 weird_graphics_thing;};asmlinkage int irix_getcontext(struct pt_regs *regs){ int error, i, base = 0; struct irix5_context __user *ctx; unsigned long flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context __user *) regs->regs[base + 4];#ifdef DEBUG_SIG printk("[%s:%d] irix_getcontext(%p)\n", current->comm, current->pid, ctx);#endif if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))); return -EFAULT; error = __put_user(current->thread.irix_oldctx, &ctx->link); error |= __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)) ? -EFAULT : 0; /* XXX Do sigstack stuff someday... */ error |= __put_user(0, &ctx->stack.sp); error |= __put_user(0, &ctx->stack.size); error |= __put_user(0, &ctx->stack.flags); error |= __put_user(0, &ctx->weird_graphics_thing); error |= __put_user(0, &ctx->regs[0]); for (i = 1; i < 32; i++) error |= __put_user(regs->regs[i], &ctx->regs[i]); error |= __put_user(regs->lo, &ctx->regs[32]); error |= __put_user(regs->hi, &ctx->regs[33]); error |= __put_user(regs->cp0_cause, &ctx->regs[34]); error |= __put_user(regs->cp0_epc, &ctx->regs[35]); flags = 0x0f; if (!used_math()) { flags &= ~(0x08); } else { /* XXX wheee... */ printk("Wheee, no code for saving IRIX FPU context yet.\n"); } error |= __put_user(flags, &ctx->flags); return error;}asmlinkage void irix_setcontext(struct pt_regs *regs){ struct irix5_context __user *ctx; int err, base = 0; u32 flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context __user *) regs->regs[base + 4];#ifdef DEBUG_SIG printk("[%s:%d] irix_setcontext(%p)\n", current->comm, current->pid, ctx);#endif if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))) goto segv_and_exit; err = __get_user(flags, &ctx->flags); if (flags & 0x02) { /* XXX sigstack garbage, todo... */ printk("Wheee, cannot do sigstack stuff in setcontext\n"); } if (flags & 0x04) { int i; /* XXX extra control block stuff... todo... */ for (i = 1; i < 32; i++) err |= __get_user(regs->regs[i], &ctx->regs[i]); err |= __get_user(regs->lo, &ctx->regs[32]); err |= __get_user(regs->hi, &ctx->regs[33]); err |= __get_user(regs->cp0_epc, &ctx->regs[35]); } if (flags & 0x08) /* XXX fpu context, blah... */ printk(KERN_ERR "Wheee, cannot restore FPU context yet...\n"); err |= __get_user(current->thread.irix_oldctx, &ctx->link); if (err) goto segv_and_exit; /* * Don't let your children do this ... */ __asm__ __volatile__( "move\t$29,%0\n\t" "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */segv_and_exit: force_sigsegv(SIGSEGV, current);}struct irix_sigstack { unsigned long sp; int status;};asmlinkage int irix_sigstack(struct irix_sigstack __user *new, struct irix_sigstack __user *old){#ifdef DEBUG_SIG printk("[%s:%d] irix_sigstack(%p,%p)\n", current->comm, current->pid, new, old);#endif if (new) { if (!access_ok(VERIFY_READ, new, sizeof(*new))) return -EFAULT; } if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) return -EFAULT; } return 0;}struct irix_sigaltstack { unsigned long sp; int size; int status; };asmlinkage int irix_sigaltstack(struct irix_sigaltstack __user *new, struct irix_sigaltstack __user *old){#ifdef DEBUG_SIG printk("[%s:%d] irix_sigaltstack(%p,%p)\n", current->comm, current->pid, new, old);#endif if (new) if (!access_ok(VERIFY_READ, new, sizeof(*new))) return -EFAULT; if (old) { if (!access_ok(VERIFY_WRITE, old, sizeof(*old))) return -EFAULT; } return 0;}struct irix_procset { int cmd, ltype, lid, rtype, rid;};asmlinkage int irix_sigsendset(struct irix_procset __user *pset, int sig){ if (!access_ok(VERIFY_READ, pset, sizeof(*pset))) return -EFAULT;#ifdef DEBUG_SIG printk("[%s:%d] irix_sigsendset([%d,%d,%d,%d,%d],%d)\n", current->comm, current->pid, pset->cmd, pset->ltype, pset->lid, pset->rtype, pset->rid, sig);#endif return -EINVAL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -