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

📄 signal.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	err |= __put_user(scr->pt.pr, &sc->sc_pr);			/* predicates */	err |= __put_user(scr->pt.b0, &sc->sc_br[0]);			/* b0 (rp) */	err |= __put_user(scr->pt.b6, &sc->sc_br[6]);			/* b6 */	err |= __put_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */	err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 3*8);		/* r1-r3 */	err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8);		/* r8-r11 */	err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 4*8);	/* r12-r15 */	err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);	/* r16-r31 */	err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);	return err;}static longsetup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,	     struct sigscratch *scr){	extern char ia64_sigtramp[], __start_gate_section[];	unsigned long tramp_addr, new_rbs = 0;	struct sigframe *frame;	struct siginfo si;	long err;	frame = (void *) scr->pt.r12;	tramp_addr = GATE_ADDR + (ia64_sigtramp - __start_gate_section);	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack((unsigned long) frame)) {		new_rbs  = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);		frame = (void *) ((current->sas_ss_sp + current->sas_ss_size)				  & ~(STACK_ALIGN - 1));	}	frame = (void *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))		goto give_sigsegv;	err  = copy_siginfo_to_user(&frame->info, info);	err |= __put_user(current->sas_ss_sp, &frame->sc.sc_stack.ss_sp);	err |= __put_user(current->sas_ss_size, &frame->sc.sc_stack.ss_size);	err |= __put_user(sas_ss_flags(scr->pt.r12), &frame->sc.sc_stack.ss_flags);	err |= setup_sigcontext(&frame->sc, set, scr);	if (err)		goto give_sigsegv;	scr->pt.r12 = (unsigned long) frame - 16;		/* new stack pointer */	scr->pt.r2  = sig;					/* signal number */	scr->pt.r3  = (unsigned long) ka->sa.sa_handler;	/* addr. of handler's proc desc */	scr->pt.r15 = new_rbs;	scr->pt.ar_fpsr = FPSR_DEFAULT;			/* reset fpsr for signal handler */	scr->pt.cr_iip = tramp_addr;	ia64_psr(&scr->pt)->ri = 0;			/* start executing in first slot */#ifdef CONFIG_IA64_NEW_UNWIND	/*	 * Note: this affects only the NaT bits of the scratch regs	 * (the ones saved in pt_regs), which is exactly what we want.	 */	scr->scratch_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */#else	/*	 * Note: this affects only the NaT bits of the scratch regs	 * (the ones saved in pt_regs), which is exactly what we want.	 * The NaT bits for the preserved regs (r4-r7) are in	 * sw->ar_unat iff this process is being PTRACED.	 */	scr->sw.caller_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */#endif#if DEBUG_SIG	printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%lx\n",	       current->comm, current->pid, sig, scr->pt.r12, scr->pt.cr_iip, scr->pt.r3);#endif	return 1;  give_sigsegv:	if (sig == SIGSEGV)		ka->sa.sa_handler = SIG_DFL;	si.si_signo = SIGSEGV;	si.si_errno = 0;	si.si_code = SI_KERNEL;	si.si_pid = current->pid;	si.si_uid = current->uid;	si.si_addr = frame;	force_sig_info(SIGSEGV, &si, current);	return 0;}static longhandle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset,	       struct sigscratch *scr){#ifdef CONFIG_IA32_SUPPORT	if (IS_IA32_PROCESS(&scr->pt)) {		/* send signal to IA-32 process */		if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt))			return 0;	} else#endif	/* send signal to IA-64 process */	if (!setup_frame(sig, ka, info, oldset, scr))		return 0;	if (ka->sa.sa_flags & SA_ONESHOT)		ka->sa.sa_handler = SIG_DFL;	if (!(ka->sa.sa_flags & SA_NODEFER)) {		spin_lock_irq(&current->sigmask_lock);		{			sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);			sigaddset(&current->blocked, sig);			recalc_sigpending(current);		}		spin_unlock_irq(&current->sigmask_lock);	}	return 1;}/* * Note that `init' is a special process: it doesn't get signals it * doesn't want to handle.  Thus you cannot kill init even with a * SIGKILL even by mistake. * * Note that we go through the signals twice: once to check the * signals that the kernel can handle, and then we build all the * user-level signal handling stack-frames in one go after that. */longia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall){	struct k_sigaction *ka;	siginfo_t info;	long restart = in_syscall;	long errno = scr->pt.r8;	/*	 * In the ia64_leave_kernel code path, we want the common case	 * to go fast, which is why we may in certain cases get here	 * from kernel mode. Just return without doing anything if so.	 */	if (!user_mode(&scr->pt))		return 0;	if (!oldset)		oldset = &current->blocked;#ifdef CONFIG_IA32_SUPPORT	if (IS_IA32_PROCESS(&scr->pt)) {		if (in_syscall) {			if (errno >= 0)				restart = 0;			else				errno = -errno;		}	} else#endif	if (scr->pt.r10 != -1) {		/*		 * A system calls has to be restarted only if one of		 * the error codes ERESTARTNOHAND, ERESTARTSYS, or		 * ERESTARTNOINTR is returned.  If r10 isn't -1 then		 * r8 doesn't hold an error code and we don't need to		 * restart the syscall, so we set in_syscall to zero.		 */		restart = 0;	}	for (;;) {		unsigned long signr;		spin_lock_irq(&current->sigmask_lock);		signr = dequeue_signal(&current->blocked, &info);		spin_unlock_irq(&current->sigmask_lock);		if (!signr)			break;		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {			/* Let the debugger run.  */			current->exit_code = signr;			current->thread.siginfo = &info;			current->state = TASK_STOPPED;			notify_parent(current, SIGCHLD);			schedule();			signr = current->exit_code;			current->thread.siginfo = 0;			/* We're back.  Did the debugger cancel the sig?  */			if (!signr)				continue;			current->exit_code = 0;			/* The debugger continued.  Ignore SIGSTOP.  */			if (signr == SIGSTOP)				continue;			/* Update the siginfo structure.  Is this good?  */			if (signr != info.si_signo) {				info.si_signo = signr;				info.si_errno = 0;				info.si_code = SI_USER;				info.si_pid = current->p_pptr->pid;				info.si_uid = current->p_pptr->uid;			}			/* If the (new) signal is now blocked, requeue it.  */			if (sigismember(&current->blocked, signr)) {				send_sig_info(signr, &info, current);				continue;			}		}		ka = &current->sig->action[signr - 1];		if (ka->sa.sa_handler == SIG_IGN) {			if (signr != SIGCHLD)				continue;			/* Check for SIGCHLD: it's special.  */			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)				/* nothing */;			continue;		}		if (ka->sa.sa_handler == SIG_DFL) {			int exit_code = signr;			/* Init gets no signals it doesn't want.  */			if (current->pid == 1)				continue;			switch (signr) {			      case SIGCONT: case SIGCHLD: case SIGWINCH:				continue;			      case SIGTSTP: case SIGTTIN: case SIGTTOU:				if (is_orphaned_pgrp(current->pgrp))					continue;				/* FALLTHRU */			      case SIGSTOP:				current->state = TASK_STOPPED;				current->exit_code = signr;				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags				      & SA_NOCLDSTOP))					notify_parent(current, SIGCHLD);				schedule();				continue;			      case SIGQUIT: case SIGILL: case SIGTRAP:			      case SIGABRT: case SIGFPE: case SIGSEGV:			      case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:				if (do_coredump(signr, &scr->pt))					exit_code |= 0x80;				/* FALLTHRU */			      default:				sigaddset(&current->pending.signal, signr);				recalc_sigpending(current);				current->flags |= PF_SIGNALED;				do_exit(exit_code);				/* NOTREACHED */			}		}		if (restart) {			switch (errno) {			      case ERESTARTSYS:				if ((ka->sa.sa_flags & SA_RESTART) == 0) {			      case ERESTARTNOHAND:#ifdef CONFIG_IA32_SUPPORT					if (IS_IA32_PROCESS(&scr->pt))						scr->pt.r8 = -EINTR;					else#endif					scr->pt.r8 = EINTR;					/* note: scr->pt.r10 is already -1 */					break;				}			      case ERESTARTNOINTR:#ifdef CONFIG_IA32_SUPPORT				if (IS_IA32_PROCESS(&scr->pt)) {					scr->pt.r8 = scr->pt.r1;					scr->pt.cr_iip -= 2;				} else#endif				ia64_decrement_ip(&scr->pt);			}		}		/* Whee!  Actually deliver the signal.  If the		   delivery failed, we need to continue to iterate in		   this loop so we can deliver the SIGSEGV... */		if (handle_signal(signr, ka, &info, oldset, scr))			return 1;	}	/* Did we come from a system call? */	if (restart) {		/* Restart the system call - no handlers present */		if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR) {#ifdef CONFIG_IA32_SUPPORT			if (IS_IA32_PROCESS(&scr->pt)) {				scr->pt.r8 = scr->pt.r1;				scr->pt.cr_iip -= 2;			} else#endif			/*			 * Note: the syscall number is in r15 which is			 * saved in pt_regs so all we need to do here			 * is adjust ip so that the "break"			 * instruction gets re-executed.			 */			ia64_decrement_ip(&scr->pt);		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -