⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irixsig.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 (&current->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(&current->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(&current->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, &current->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" (&regs));		/* 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 + -