Ядро Linux в комментариях

Arch/i386/kernel/signal.c


2744 /* 2745 * linux/arch/i386/kernel/signal.c 2746 * 2747 * Copyright (C) 1991, 1992 Linus Torvalds 2748 * 1997-11-28 Modified for POSIX.1b signals by Richard 2749 * Henderson */ 2750 2751 #include <linux/config.h> 2752 2753 #include <linux/sched.h> 2754 #include <linux/mm.h> 2755 #include <linux/smp.h> 2756 #include <linux/smp_lock.h> 2757 #include <linux/kernel.h> 2758 #include <linux/signal.h> 2759 #include <linux/errno.h> 2760 #include <linux/wait.h> 2761 #include <linux/ptrace.h> 2762 #include <linux/unistd.h> 2763 #include <linux/stddef.h> 2764 #include <asm/ucontext.h> 2765 #include <asm/uaccess.h> 2766 2767 #define DEBUG_SIG 0 2768 2769 #define _BLOCKABLE (~(sigmask(SIGKILL)|sigmask(SIGSTOP))) 2770 2771 asmlinkage int sys_wait4(pid_t pid, 2772 unsigned long *stat_addr, 2773 int options, unsigned long *ru); 2774 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, 2775 sigset_t *oldset)); 2776 2777 /* Atomically swap in the new signal mask, and wait for a 2778 * signal. */ 2779 asmlinkage int 2780 sys_sigsuspend(int history0, int history1, 2781 old_sigset_t mask) 2782 { 2783 struct pt_regs * regs = (struct pt_regs *) &history0; 2784 sigset_t saveset; 2785 2786 mask &= _BLOCKABLE; 2787 spin_lock_irq(&current->sigmask_lock); 2788 saveset = current->blocked; 2789 siginitset(&current->blocked, mask); 2790 recalc_sigpending(current); 2791 spin_unlock_irq(&current->sigmask_lock); 2792 2793 regs->eax = -EINTR; 2794 while (1) { 2795 current->state = TASK_INTERRUPTIBLE; 2796 schedule(); 2797 if (do_signal(regs, &saveset)) 2798 return -EINTR; 2799 } 2800 } 2801 2802 asmlinkage int 2803 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) 2804 { 2805 struct pt_regs * regs = (struct pt_regs *) &unewset; 2806 sigset_t saveset, newset; 2807 2808 /* XXX: Don't preclude handling different sized 2809 * sigset_t's. */ 2810 if (sigsetsize != sizeof(sigset_t)) 2811 return -EINVAL; 2812 2813 if (copy_from_user(&newset, unewset, sizeof(newset))) 2814 return -EFAULT; 2815 sigdelsetmask(&newset, ~_BLOCKABLE); 2816 2817 spin_lock_irq(&current->sigmask_lock); 2818 saveset = current->blocked; 2819 current->blocked = newset; 2820 recalc_sigpending(current); 2821 spin_unlock_irq(&current->sigmask_lock); 2822 2823 regs->eax = -EINTR; 2824 while (1) { 2825 current->state = TASK_INTERRUPTIBLE; 2826 schedule(); 2827 if (do_signal(regs, &saveset)) 2828 return -EINTR; 2829 } 2830 } 2831 2832 asmlinkage int 2833 sys_sigaction(int sig, const struct old_sigaction *act, 2834 struct old_sigaction *oact) 2835 { 2836 struct k_sigaction new_ka, old_ka; 2837 int ret; 2838 2839 if (act) { 2840 old_sigset_t mask; 2841 if (verify_area(VERIFY_READ, act, sizeof(*act)) 2842 __get_user(new_ka.sa.sa_handler, 2843 &act->sa_handler) 2844 __get_user(new_ka.sa.sa_restorer, 2845 &act->sa_restorer)) 2846 return -EFAULT; 2847 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 2848 __get_user(mask, &act->sa_mask); 2849 siginitset(&new_ka.sa.sa_mask, mask); 2850 } 2851 2852 ret = do_sigaction(sig, act ? &new_ka : NULL, 2853 oact ? &old_ka : NULL); 2854 2855 if (!ret && oact) { 2856 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) 2857 __put_user(old_ka.sa.sa_handler, 2858 &oact->sa_handler) 2859 __put_user(old_ka.sa.sa_restorer, 2860 &oact->sa_restorer)) 2861 return -EFAULT; 2862 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 2863 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 2864 } 2865 2866 return ret; 2867 } 2868 2869 asmlinkage int 2870 sys_sigaltstack(const stack_t *uss, stack_t *uoss) 2871 { 2872 struct pt_regs *regs = (struct pt_regs *) &uss; 2873 return do_sigaltstack(uss, uoss, regs->esp); 2874 } 2875 2876 2877 /* Do a signal return; undo the signal stack. */ 2878 2879 struct sigframe 2880 { 2881 char *pretcode; 2882 int sig; 2883 struct sigcontext sc; 2884 struct _fpstate fpstate; 2885 unsigned long extramask[_NSIG_WORDS-1]; 2886 char retcode[8]; 2887 }; 2888 2889 struct rt_sigframe 2890 { 2891 char *pretcode; 2892 int sig; 2893 struct siginfo *pinfo; 2894 void *puc; 2895 struct siginfo info; 2896 struct ucontext uc; 2897 struct _fpstate fpstate; 2898 char retcode[8]; 2899 }; 2900 2901 2902 static inline int restore_i387_hard(struct _fpstate *buf) 2903 { 2904 struct task_struct *tsk = current; 2905 clear_fpu(tsk); 2906 return __copy_from_user(&tsk->tss.i387.hard, buf, 2907 sizeof(*buf)); 2908 } 2909 2910 static inline int restore_i387(struct _fpstate *buf) 2911 { 2912 int err; 2913 #ifndef CONFIG_MATH_EMULATION 2914 err = restore_i387_hard(buf); 2915 #else 2916 if (boot_cpu_data.hard_math) 2917 err = restore_i387_hard(buf); 2918 else 2919 err = restore_i387_soft(&current->tss.i387.soft,buf); 2920 #endif 2921 current->used_math = 1; 2922 return err; 2923 } 2924 2925 static int 2926 restore_sigcontext(struct pt_regs *regs, 2927 struct sigcontext *sc, int *peax) 2928 { 2929 unsigned int err = 0; 2930 2931 #define COPY(x) err |= __get_user(regs->x, &sc->x) 2932 2933 #define COPY_SEG(seg) \ 2934 { unsigned short tmp; \ 2935 err |= __get_user(tmp, &sc->seg); \ 2936 regs->x##seg = tmp; } 2937 2938 #define COPY_SEG_STRICT(seg) \ 2939 { unsigned short tmp; \ 2940 err |= __get_user(tmp, &sc->seg); \ 2941 regs->x##seg = tmp|3; } 2942 2943 #define GET_SEG(seg) \ 2944 { unsigned short tmp; \ 2945 err |= __get_user(tmp, &sc->seg); \ 2946 loadsegment(seg,tmp); } 2947 2948 GET_SEG(gs); 2949 GET_SEG(fs); 2950 COPY_SEG(es); 2951 COPY_SEG(ds); 2952 COPY(edi); 2953 COPY(esi); 2954 COPY(ebp); 2955 COPY(esp); 2956 COPY(ebx); 2957 COPY(edx); 2958 COPY(ecx); 2959 COPY(eip); 2960 COPY_SEG_STRICT(cs); 2961 COPY_SEG_STRICT(ss); 2962 2963 { 2964 unsigned int tmpflags; 2965 err |= __get_user(tmpflags, &sc->eflags); 2966 regs->eflags = (regs->eflags & ~0x40DD5) | 2967 (tmpflags & 0x40DD5); 2968 regs->orig_eax = -1; /* disable syscall checks */ 2969 } 2970 2971 { 2972 struct _fpstate * buf; 2973 err |= __get_user(buf, &sc->fpstate); 2974 if (buf) { 2975 if (verify_area(VERIFY_READ, buf, sizeof(*buf))) 2976 goto badframe; 2977 err |= restore_i387(buf); 2978 } 2979 } 2980 2981 err |= __get_user(*peax, &sc->eax); 2982 return err; 2983 2984 badframe: 2985 return 1; 2986 } 2987 2988 asmlinkage int sys_sigreturn(unsigned long __unused) 2989 { 2990 struct pt_regs *regs = (struct pt_regs *) &__unused; 2991 struct sigframe *frame = 2992 (struct sigframe *)(regs->esp - 8); 2993 sigset_t set; 2994 int eax; 2995 2996 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 2997 goto badframe; 2998 if (__get_user(set.sig[0], &frame->sc.oldmask) 2999 (_NSIG_WORDS > 1 3000 && __copy_from_user(&set.sig[1], &frame->extramask, 3001 sizeof(frame->extramask)))) 3002 goto badframe; 3003 3004 sigdelsetmask(&set, ~_BLOCKABLE); 3005 spin_lock_irq(&current->sigmask_lock); 3006 current->blocked = set; 3007 recalc_sigpending(current); 3008 spin_unlock_irq(&current->sigmask_lock); 3009 3010 if (restore_sigcontext(regs, &frame->sc, &eax)) 3011 goto badframe; 3012 return eax; 3013 3014 badframe: 3015 force_sig(SIGSEGV, current); 3016 return 0; 3017 } 3018 3019 asmlinkage int sys_rt_sigreturn(unsigned long __unused) 3020 { 3021 struct pt_regs *regs = (struct pt_regs *) &__unused; 3022 struct rt_sigframe *frame = 3023 (struct rt_sigframe *)(regs->esp - 4); 3024 sigset_t set; 3025 stack_t st; 3026 int eax; 3027 3028 if (verify_area(VERIFY_READ, frame, sizeof(*frame))) 3029 goto badframe; 3030 if (__copy_from_user(&set, &frame->uc.uc_sigmask, 3031 sizeof(set))) 3032 goto badframe; 3033 3034 sigdelsetmask(&set, ~_BLOCKABLE); 3035 spin_lock_irq(&current->sigmask_lock); 3036 current->blocked = set; 3037 recalc_sigpending(current); 3038 spin_unlock_irq(&current->sigmask_lock); 3039 3040 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, 3041 &eax)) 3042 goto badframe; 3043 3044 if (__copy_from_user(&st, &frame->uc.uc_stack, 3045 sizeof(st))) 3046 goto badframe; 3047 /* It is more difficult to avoid calling this function 3048 * than to call it and ignore errors. */ 3049 do_sigaltstack(&st, NULL, regs->esp); 3050 3051 return eax; 3052 3053 badframe: 3054 force_sig(SIGSEGV, current); 3055 return 0; 3056 } 3057 3058 /* Set up a signal frame. */ 3059 3060 static inline int save_i387_hard(struct _fpstate * buf) 3061 { 3062 struct task_struct *tsk = current; 3063 3064 unlazy_fpu(tsk); 3065 tsk->tss.i387.hard.status = tsk->tss.i387.hard.swd; 3066 if (__copy_to_user(buf, &tsk->tss.i387.hard, 3067 sizeof(*buf))) 3068 return -1; 3069 return 1; 3070 } 3071 3072 static int save_i387(struct _fpstate *buf) 3073 { 3074 if (!current->used_math) 3075 return 0; 3076 3077 /* This will cause a "finit" to be triggered by the 3078 * next attempted FPU operation by the 'current' 3079 * process. */ 3080 current->used_math = 0; 3081 3082 #ifndef CONFIG_MATH_EMULATION 3083 return save_i387_hard(buf); 3084 #else 3085 return boot_cpu_data.hard_math ? save_i387_hard(buf) 3086 : save_i387_soft(&current->tss.i387.soft, buf); 3087 #endif 3088 } 3089 3090 static int 3091 setup_sigcontext(struct sigcontext *sc, 3092 struct _fpstate *fpstate, 3093 struct pt_regs *regs,unsigned long mask) 3094 { 3095 int tmp, err = 0; 3096 3097 tmp = 0; 3098 __asm__("movl %%gs,%w0" : "=r"(tmp): "0"(tmp)); 3099 err |= __put_user(tmp, (unsigned int *)&sc->gs); 3100 __asm__("movl %%fs,%w0" : "=r"(tmp): "0"(tmp)); 3101 err |= __put_user(tmp, (unsigned int *)&sc->fs); 3102 3103 err |= __put_user(regs->xes, (unsigned int *)&sc->es); 3104 err |= __put_user(regs->xds, (unsigned int *)&sc->ds); 3105 err |= __put_user(regs->edi, &sc->edi); 3106 err |= __put_user(regs->esi, &sc->esi); 3107 err |= __put_user(regs->ebp, &sc->ebp); 3108 err |= __put_user(regs->esp, &sc->esp); 3109 err |= __put_user(regs->ebx, &sc->ebx); 3110 err |= __put_user(regs->edx, &sc->edx); 3111 err |= __put_user(regs->ecx, &sc->ecx); 3112 err |= __put_user(regs->eax, &sc->eax); 3113 err |= __put_user(current->tss.trap_no, &sc->trapno); 3114 err |= __put_user(current->tss.error_code, &sc->err); 3115 err |= __put_user(regs->eip, &sc->eip); 3116 err |= __put_user(regs->xcs, (unsigned int *)&sc->cs); 3117 err |= __put_user(regs->eflags, &sc->eflags); 3118 err |= __put_user(regs->esp, &sc->esp_at_signal); 3119 err |= __put_user(regs->xss, (unsigned int *)&sc->ss); 3120 3121 tmp = save_i387(fpstate); 3122 if (tmp < 0) 3123 err = 1; 3124 else 3125 err |= __put_user(tmp ? fpstate : NULL,&sc->fpstate); 3126 3127 /* non-iBCS2 extensions.. */ 3128 err |= __put_user(mask, &sc->oldmask); 3129 err |= __put_user(current->tss.cr2, &sc->cr2); 3130 3131 return err; 3132 } 3133 3134 /* Determine which stack to use.. */ 3135 static inline void * 3136 get_sigframe(struct k_sigaction *ka, 3137 struct pt_regs * regs, size_t frame_size) 3138 { 3139 unsigned long esp; 3140 3141 /* Default to using normal stack */ 3142 esp = regs->esp; 3143 3144 /* This is the X/Open sanctioned signal stack 3145 * switching. */ 3146 if (ka->sa.sa_flags & SA_ONSTACK) { 3147 if (! on_sig_stack(esp)) 3148 esp = current->sas_ss_sp + current->sas_ss_size; 3149 } 3150 3151 /* This is the legacy signal stack switching. */ 3152 else if ((regs->xss & 0xffff) != __USER_DS && 3153 !(ka->sa.sa_flags & SA_RESTORER) && 3154 ka->sa.sa_restorer) { 3155 esp = (unsigned long) ka->sa.sa_restorer; 3156 } 3157 3158 return (void *)((esp - frame_size) & -8ul); 3159 } 3160 3161 static void setup_frame(int sig, struct k_sigaction *ka, 3162 sigset_t *set, struct pt_regs * regs) 3163 { 3164 struct sigframe *frame; 3165 int err = 0; 3166 3167 frame = get_sigframe(ka, regs, sizeof(*frame)); 3168 3169 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 3170 goto give_sigsegv; 3171 3172 err |= __put_user((current->exec_domain 3173 && current->exec_domain->signal_invmap 3174 && sig < 32 3175 ? current->exec_domain->signal_invmap[sig] 3176 : sig), 3177 &frame->sig); 3178 3179 err |= setup_sigcontext(&frame->sc, &frame->fpstate, 3180 regs, set->sig[0]); 3181 3182 if (_NSIG_WORDS > 1) { 3183 err |= __copy_to_user(frame->extramask, &set->sig[1], 3184 sizeof(frame->extramask)); 3185 } 3186 3187 /* Set up to return from userspace. If provided, use a 3188 * stub already in userspace. */ 3189 if (ka->sa.sa_flags & SA_RESTORER) { 3190 err |= __put_user(ka->sa.sa_restorer, 3191 &frame->pretcode); 3192 } else { 3193 err |= __put_user(frame->retcode, &frame->pretcode); 3194 /* This is popl %eax ; movl $,%eax ; int $0x80 */ 3195 err |= __put_user(0xb858, 3196 (short *)(frame->retcode+0)); 3197 err |= __put_user(__NR_sigreturn, 3198 (int *)(frame->retcode+2)); 3199 err |= __put_user(0x80cd, 3200 (short *)(frame->retcode+6)); 3201 } 3202 3203 if (err) 3204 goto give_sigsegv; 3205 3206 /* Set up registers for signal handler */ 3207 regs->esp = (unsigned long) frame; 3208 regs->eip = (unsigned long) ka->sa.sa_handler; 3209 3210 set_fs(USER_DS); 3211 regs->xds = __USER_DS; 3212 regs->xes = __USER_DS; 3213 regs->xss = __USER_DS; 3214 regs->xcs = __USER_CS; 3215 regs->eflags &= ~TF_MASK; 3216 3217 #if DEBUG_SIG 3218 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 3219 current->comm, current->pid, frame, regs->eip, 3220 frame->pretcode); 3221 #endif 3222 3223 return; 3224 3225 give_sigsegv: 3226 if (sig == SIGSEGV) 3227 ka->sa.sa_handler = SIG_DFL; 3228 force_sig(SIGSEGV, current); 3229 } 3230 3231 static void setup_rt_frame(int sig, 3232 struct k_sigaction *ka, siginfo_t *info, 3233 sigset_t *set, struct pt_regs * regs) 3234 { 3235 struct rt_sigframe *frame; 3236 int err = 0; 3237 3238 frame = get_sigframe(ka, regs, sizeof(*frame)); 3239 3240 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 3241 goto give_sigsegv; 3242 3243 err |= __put_user((current->exec_domain 3244 && current->exec_domain->signal_invmap 3245 && sig < 32 3246 ? current->exec_domain->signal_invmap[sig] 3247 : sig), 3248 &frame->sig); 3249 err |= __put_user(&frame->info, &frame->pinfo); 3250 err |= __put_user(&frame->uc, &frame->puc); 3251 err |= __copy_to_user(&frame->info,info,sizeof(*info)); 3252 3253 /* Create the ucontext. */ 3254 err |= __put_user(0, &frame->uc.uc_flags); 3255 err |= __put_user(0, &frame->uc.uc_link); 3256 err |= __put_user(current->sas_ss_sp, 3257 &frame->uc.uc_stack.ss_sp); 3258 err |= __put_user(sas_ss_flags(regs->esp), 3259 &frame->uc.uc_stack.ss_flags); 3260 err |= __put_user(current->sas_ss_size, 3261 &frame->uc.uc_stack.ss_size); 3262 err |= setup_sigcontext(&frame->uc.uc_mcontext, 3263 &frame->fpstate, 3264 regs, set->sig[0]); 3265 err |= __copy_to_user(&frame->uc.uc_sigmask, set, 3266 sizeof(*set)); 3267 3268 /* Set up to return from userspace. If provided, use a 3269 * stub already in userspace. */ 3270 if (ka->sa.sa_flags & SA_RESTORER) { 3271 err |= __put_user(ka->sa.sa_restorer, 3272 &frame->pretcode); 3273 } else { 3274 err |= __put_user(frame->retcode, &frame->pretcode); 3275 /* This is movl $,%eax ; int $0x80 */ 3276 err |= __put_user(0xb8, (char *)(frame->retcode+0)); 3277 err |= __put_user(__NR_rt_sigreturn, 3278 (int *)(frame->retcode+1)); 3279 err |= __put_user(0x80cd, 3280 (short *)(frame->retcode+5)); 3281 } 3282 3283 if (err) 3284 goto give_sigsegv; 3285 3286 /* Set up registers for signal handler */ 3287 regs->esp = (unsigned long) frame; 3288 regs->eip = (unsigned long) ka->sa.sa_handler; 3289 3290 set_fs(USER_DS); 3291 regs->xds = __USER_DS; 3292 regs->xes = __USER_DS; 3293 regs->xss = __USER_DS; 3294 regs->xcs = __USER_CS; 3295 regs->eflags &= ~TF_MASK; 3296 3297 #if DEBUG_SIG 3298 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 3299 current->comm, current->pid, frame, regs->eip, 3300 frame->pretcode); 3301 #endif 3302 3303 return; 3304 3305 give_sigsegv: 3306 if (sig == SIGSEGV) 3307 ka->sa.sa_handler = SIG_DFL; 3308 force_sig(SIGSEGV, current); 3309 } 3310 3311 /* OK, we're invoking a handler */ 3312 3313 static void


3314 handle_signal( unsigned long sig, struct k_sigaction *ka, 3315 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) 3316 { 3317 /* Are we from a system call? */ 3318 if (regs->orig_eax >= 0) { 3319 /* If so, check system call restarting.. */ 3320 switch (regs->eax) { 3321 case -ERESTARTNOHAND: 3322 regs->eax = -EINTR; 3323 break; 3324 3325 case -ERESTARTSYS: 3326 if (!(ka->sa.sa_flags & SA_RESTART)) { 3327 regs->eax = -EINTR; 3328 break; 3329 } 3330 /* fallthrough */ 3331 case -ERESTARTNOINTR: 3332 regs->eax = regs->orig_eax; 3333 regs->eip -= 2; 3334 } 3335 } 3336 3337 /* Set up the stack frame */ 3338 if (ka->sa.sa_flags & SA_SIGINFO) 3339 setup_rt_frame(sig, ka, info, oldset, regs); 3340 else 3341 setup_frame(sig, ka, oldset, regs); 3342 3343 if (ka->sa.sa_flags & SA_ONESHOT) 3344 ka->sa.sa_handler = SIG_DFL; 3345 3346 if (!(ka->sa.sa_flags & SA_NODEFER)) { 3347 spin_lock_irq(&current->sigmask_lock); 3348 sigorsets(&current->blocked,&current->blocked, 3349 &ka->sa.sa_mask); 3350 sigaddset(&current->blocked,sig); 3351 recalc_sigpending(current); 3352 spin_unlock_irq(&current->sigmask_lock); 3353 } 3354 } 3355 3356 /* Note that 'init' is a special process: it doesn't get 3357 * signals it doesn't want to handle. Thus you cannot 3358 * kill init even with a SIGKILL even by mistake. 3359 * 3360 * Note that we go through the signals twice: once to 3361 * check the signals that the kernel can handle, and then 3362 * we build all the user-level signal handling 3363 * stack-frames in one go after that. */

3364 int do_signal(struct pt_regs *regs, sigset_t *oldset) 3365 { 3366 siginfo_t info; 3367 struct k_sigaction *ka; 3368 3369 /* We want the common case to go fast, which is why we 3370 * may in certain cases get here from kernel mode. Just 3371 * return without doing anything if so. */ 3372 if ((regs->xcs & 3) != 3) 3373 return 1; 3374 3375 if (!oldset) 3376 oldset = &current->blocked; 3377 3378 for (;;) { 3379 unsigned long signr; 3380 3381 spin_lock_irq(&current->sigmask_lock); 3382 signr = dequeue_signal(&current->blocked, &info); 3383 spin_unlock_irq(&current->sigmask_lock); 3384 3385 if (!signr) 3386 break; 3387 3388 if ((current->flags & PF_PTRACED) && 3389 signr != SIGKILL) { 3390 /* Let the debugger run. */ 3391 current->exit_code = signr; 3392 current->state = TASK_STOPPED; 3393 notify_parent(current, SIGCHLD); 3394 schedule(); 3395 3396 /* We're back. Did the debugger cancel the sig? */ 3397 if (!(signr = current->exit_code)) 3398 continue; 3399 current->exit_code = 0; 3400 3401 /* The debugger continued. Ignore SIGSTOP. */ 3402 if (signr == SIGSTOP) 3403 continue; 3404 3405 /* Update the siginfo structure. Is this good? */ 3406 if (signr != info.si_signo) { 3407 info.si_signo = signr; 3408 info.si_errno = 0; 3409 info.si_code = SI_USER; 3410 info.si_pid = current->p_pptr->pid; 3411 info.si_uid = current->p_pptr->uid; 3412 } 3413 3414 /* If (new) signal is now blocked, requeue it. */ 3415 if (sigismember(&current->blocked, signr)) { 3416 send_sig_info(signr, &info, current); 3417 continue; 3418 } 3419 } 3420 3421 ka = &current->sig->action[signr-1]; 3422 if (ka->sa.sa_handler == SIG_IGN) { 3423 if (signr != SIGCHLD) 3424 continue; 3425 /* Check for SIGCHLD: it's special. */ 3426 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) 3427 /* nothing */; 3428 continue; 3429 } 3430 3431 if (ka->sa.sa_handler == SIG_DFL) { 3432 int exit_code = signr; 3433 3434 /* Init gets no signals it doesn't want. */ 3435 if (current->pid == 1) 3436 continue; 3437 3438 switch (signr) { 3439 case SIGCONT: case SIGCHLD: case SIGWINCH: 3440 continue; 3441 3442 case SIGTSTP: case SIGTTIN: case SIGTTOU: 3443 if (is_orphaned_pgrp(current->pgrp)) 3444 continue; 3445 /* FALLTHRU */ 3446 3447 case SIGSTOP: 3448 current->state = TASK_STOPPED; 3449 current->exit_code = signr; 3450 if (!(current->p_pptr->sig->action[SIGCHLD-1]. 3451 sa.sa_flags & SA_NOCLDSTOP)) 3452 notify_parent(current, SIGCHLD); 3453 schedule(); 3454 continue; 3455



3456 case SIGQUIT: case SIGILL: case SIGTRAP: 3457 case SIGABRT: case SIGFPE: case SIGSEGV: 3458 lock_kernel(); 3459 if (current->binfmt 3460 && current->binfmt->core_dump 3461 && current->binfmt->core_dump(signr, regs)) 3462 exit_code |= 0x80; 3463 unlock_kernel(); 3464 /* FALLTHRU */ 3465 3466 default: 3467 lock_kernel(); 3468 sigaddset(&current->signal, signr); 3469 current->flags |= PF_SIGNALED; 3470 do_exit(exit_code); 3471 /* NOTREACHED */ 3472 } 3473 } 3474 3475 /* Whee! Actually deliver the signal. */ 3476 handle_signal(signr, ka, &info, oldset, regs); 3477 return 1; 3478 } 3479 3480 /* Did we come from a system call? */ 3481 if (regs->orig_eax >= 0) { 3482 /* Restart the system call - no handlers present */ 3483 if (regs->eax == -ERESTARTNOHAND 3484 regs->eax == -ERESTARTSYS 3485 regs->eax == -ERESTARTNOINTR) { 3486 regs->eax = regs->orig_eax; 3487 regs->eip -= 2; 3488 } 3489 } 3490 return 0; 3491 }


Содержание раздела