Exemplo n.º 1
0
static void send_sigio_to_task(struct task_struct *p,
			       struct fown_struct *fown,
			       int fd, int reason, int group)
{
	/*
	 * F_SETSIG can change ->signum lockless in parallel, make
	 * sure we read it once and use the same value throughout.
	 */
	int signum = READ_ONCE(fown->signum);

	if (!sigio_perm(p, fown, signum))
		return;

	switch (signum) {
		siginfo_t si;
		default:
			/* Queue a rt signal with the appropriate fd as its
			   value.  We use SI_SIGIO as the source, not 
			   SI_KERNEL, since kernel signals always get 
			   delivered even if we can't queue.  Failure to
			   queue in this case _should_ be reported; we fall
			   back to SIGIO in that case. --sct */
			clear_siginfo(&si);
			si.si_signo = signum;
			si.si_errno = 0;
		        si.si_code  = reason;
			/*
			 * Posix definies POLL_IN and friends to be signal
			 * specific si_codes for SIG_POLL.  Linux extended
			 * these si_codes to other signals in a way that is
			 * ambiguous if other signals also have signal
			 * specific si_codes.  In that case use SI_SIGIO instead
			 * to remove the ambiguity.
			 */
			if ((signum != SIGPOLL) && sig_specific_sicodes(signum))
				si.si_code = SI_SIGIO;

			/* Make sure we are called with one of the POLL_*
			   reasons, otherwise we could leak kernel stack into
			   userspace.  */
			BUG_ON((reason < POLL_IN) || ((reason - POLL_IN) >= NSIGPOLL));
			if (reason - POLL_IN >= NSIGPOLL)
				si.si_band  = ~0L;
			else
				si.si_band = mangle_poll(band_table[reason - POLL_IN]);
			si.si_fd    = fd;
			if (!do_send_sig_info(signum, &si, p, group))
				break;
		/* fall-through: fall back on the old plain SIGIO signal */
		case 0:
			do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
	}
}
Exemplo n.º 2
0
Arquivo: fcntl.c Projeto: nemumu/linux
static void send_sigio_to_task(struct task_struct *p,
                               struct fown_struct *fown,
                               int fd, int reason, int group)
{
    /*
     * F_SETSIG can change ->signum lockless in parallel, make
     * sure we read it once and use the same value throughout.
     */
    int signum = ACCESS_ONCE(fown->signum);

    if (!sigio_perm(p, fown, signum))
        return;

    switch (signum) {
        siginfo_t si;
    default:
        /* Queue a rt signal with the appropriate fd as its
           value.  We use SI_SIGIO as the source, not
           SI_KERNEL, since kernel signals always get
           delivered even if we can't queue.  Failure to
           queue in this case _should_ be reported; we fall
           back to SIGIO in that case. --sct */
        si.si_signo = signum;
        si.si_errno = 0;
        si.si_code  = reason;
        /* Make sure we are called with one of the POLL_*
           reasons, otherwise we could leak kernel stack into
           userspace.  */
        BUG_ON((reason & __SI_MASK) != __SI_POLL);
        if (reason - POLL_IN >= NSIGPOLL)
            si.si_band  = ~0L;
        else
            si.si_band = band_table[reason - POLL_IN];
        si.si_fd    = fd;
        if (!do_send_sig_info(signum, &si, p, group))
            break;
    /* fall-through: fall back on the old plain SIGIO signal */
    case 0:
        do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
    }
}
Exemplo n.º 3
0
Arquivo: fcntl.c Projeto: nemumu/linux
static void send_sigurg_to_task(struct task_struct *p,
                                struct fown_struct *fown, int group)
{
    if (sigio_perm(p, fown, SIGURG))
        do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group);
}