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

📄 irixsig.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		recalc_sigpending(current);		spin_unlock_irq(&current->sigmask_lock);	}	if(old) {		error = verify_area(VERIFY_WRITE, old, sizeof(*old));		if(error)			return error;		__copy_to_user(old, &current->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(&current->sigmask_lock);	saveset = current->blocked;	current->blocked = newset;	recalc_sigpending(current);	spin_unlock_irq(&current->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 (&current->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(&current->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(&current->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, &current->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 + -