📄 irixsig.c
字号:
} recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); } if(old) { error = verify_area(VERIFY_WRITE, old, sizeof(*old)); if(error) return error; __copy_to_user(old, ¤t->blocked, sizeof(unsigned long)*4); } return 0;}asmlinkage int irix_sigsuspend(struct pt_regs *regs){ sigset_t *uset, saveset, newset; uset = (sigset_t *) regs->regs[4]; if (copy_from_user(&newset, uset, sizeof(sigset_t))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sigmask_lock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); regs->regs[2] = -EINTR; 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;};static inline unsigned long timespectojiffies(struct timespec *value){ unsigned long sec = (unsigned) value->tv_sec; long nsec = value->tv_nsec; if (sec > (LONG_MAX / HZ)) return LONG_MAX; nsec += 1000000000L / HZ - 1; nsec /= 1000000000L / HZ; return HZ * sec + nsec;}asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, struct timespec *tp){ long expire = MAX_SCHEDULE_TIMEOUT; sigset_t kset; int i, sig, error, timeo = 0;#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; error = verify_area(VERIFY_READ, set, sizeof(kset)); if (error) goto out; __copy_from_user(&kset, set, sizeof(set)); if (error) goto out; if (info && clear_user(info, sizeof(*info))) { error = -EFAULT; goto out; } if(tp) { error = verify_area(VERIFY_READ, tp, sizeof(*tp)); if(error) return error; if(!tp->tv_sec && !tp->tv_nsec) { error = -EINVAL; goto out; } expire = timespectojiffies(tp)+(tp->tv_sec||tp->tv_nsec); } while(1) { long tmp = 0; current->state = TASK_INTERRUPTIBLE; expire = schedule_timeout(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) info->sig = sig; error = 0; goto out; } } /* 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 P_PID 0#define P_PGID 2#define P_ALL 7extern int getrusage(struct task_struct *, int, struct rusage *);#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 *info, int options, struct rusage *ru){ int flag, retval; DECLARE_WAITQUEUE(wait, current); struct task_struct *p; if (!info) { retval = -EINVAL; goto out; } retval = verify_area(VERIFY_WRITE, info, sizeof(*info)); if(retval) goto out; if (ru) { retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru)); if(retval) goto out; } if (options & ~(W_MASK)) { retval = -EINVAL; goto out; } if (type != P_PID && type != P_PGID && type != P_ALL) { retval = -EINVAL; goto out; } add_wait_queue(¤t->wait_chldexit, &wait);repeat: flag = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); for (p = current->p_cptr; p; p = p->p_osptr) { if ((type == P_PID) && p->pid != pid) continue; if ((type == P_PGID) && p->pgrp != 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; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); __put_user(0, &info->code); __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); p->exit_code = 0; retval = 0; goto end_waitsys; case TASK_ZOMBIE: current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; if (ru != NULL) getrusage(p, RUSAGE_BOTH, ru); __put_user(SIGCHLD, &info->sig); __put_user(1, &info->code); /* CLD_EXITED */ __put_user(p->pid, &info->stuff.procinfo.pid); __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); retval = 0; if (p->p_opptr != p->p_pptr) { REMOVE_LINKS(p); p->p_pptr = p->p_opptr; SET_LINKS(p); notify_parent(p, SIGCHLD); } else release(p); goto end_waitsys; default: continue; } } 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->wait_chldexit, &wait);out: 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 *ctx; unsigned long flags; if (regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4];#ifdef DEBUG_SIG printk("[%s:%d] irix_getcontext(%p)\n", current->comm, current->pid, ctx);#endif error = verify_area(VERIFY_WRITE, ctx, sizeof(*ctx)); if(error) goto out; __put_user(current->thread.irix_oldctx, &ctx->link); __copy_to_user(&ctx->sigmask, ¤t->blocked, sizeof(irix_sigset_t)); /* XXX Do sigstack stuff someday... */ __put_user(0, &ctx->stack.sp); __put_user(0, &ctx->stack.size); __put_user(0, &ctx->stack.flags); __put_user(0, &ctx->weird_graphics_thing); __put_user(0, &ctx->regs[0]); for (i = 1; i < 32; i++) __put_user(regs->regs[i], &ctx->regs[i]); __put_user(regs->lo, &ctx->regs[32]); __put_user(regs->hi, &ctx->regs[33]); __put_user(regs->cp0_cause, &ctx->regs[34]); __put_user(regs->cp0_epc, &ctx->regs[35]); flags = 0x0f; if(!current->used_math) { flags &= ~(0x08); } else { /* XXX wheee... */ printk("Wheee, no code for saving IRIX FPU context yet.\n"); } __put_user(flags, &ctx->flags); error = 0;out: return error;}asmlinkage unsigned long irix_setcontext(struct pt_regs *regs){ int error, base = 0; struct irix5_context *ctx; if(regs->regs[2] == 1000) base = 1; ctx = (struct irix5_context *) regs->regs[base + 4];#ifdef DEBUG_SIG printk("[%s:%d] irix_setcontext(%p)\n", current->comm, current->pid, ctx);#endif error = verify_area(VERIFY_READ, ctx, sizeof(*ctx)); if (error) goto out; if (ctx->flags & 0x02) { /* XXX sigstack garbage, todo... */ printk("Wheee, cannot do sigstack stuff in setcontext\n"); } if (ctx->flags & 0x04) { int i; /* XXX extra control block stuff... todo... */ for(i = 1; i < 32; i++) regs->regs[i] = ctx->regs[i]; regs->lo = ctx->regs[32]; regs->hi = ctx->regs[33]; regs->cp0_epc = ctx->regs[35]; } if (ctx->flags & 0x08) { /* XXX fpu context, blah... */ printk("Wheee, cannot restore FPU context yet...\n"); } current->thread.irix_oldctx = ctx->link; error = regs->regs[2];out: return error;}struct irix_sigstack { unsigned long sp; int status; };asmlinkage int irix_sigstack(struct irix_sigstack *new, struct irix_sigstack *old){ int error;#ifdef DEBUG_SIG printk("[%s:%d] irix_sigstack(%p,%p)\n", current->comm, current->pid, new, old);#endif if(new) { error = verify_area(VERIFY_READ, new, sizeof(*new)); if(error) goto out; } if(old) { error = verify_area(VERIFY_WRITE, old, sizeof(*old)); if(error) goto out; } error = 0;out: return error;}struct irix_sigaltstack { unsigned long sp; int size; int status; };asmlinkage int irix_sigaltstack(struct irix_sigaltstack *new, struct irix_sigaltstack *old){ int error;#ifdef DEBUG_SIG printk("[%s:%d] irix_sigaltstack(%p,%p)\n", current->comm, current->pid, new, old);#endif if (new) { error = verify_area(VERIFY_READ, new, sizeof(*new)); if(error) goto out; } if (old) { error = verify_area(VERIFY_WRITE, old, sizeof(*old)); if(error) goto out; } error = 0;out: error = 0; return error;}struct irix_procset { int cmd, ltype, lid, rtype, rid;};asmlinkage int irix_sigsendset(struct irix_procset *pset, int sig){ int error; error = verify_area(VERIFY_READ, pset, sizeof(*pset)); if(error) goto out;#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 error = -EINVAL;out: return error;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -