18,773
社区成员
发帖
与我相关
我的任务
分享
int main(int argc,char** argv)
{
...
struct sigaction sigio_act;
//设置信号集
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGIO);
//设置 SIGIO 对应的信号处理函数
sigio_act.sa_sigaction = sig_handler;
//当sa_flags包含 SA_SIGINFO 标志时,系统使用sa_sigaction函数作为信号处理函数,否则使用sa_handler.
sigio_act.sa_flags = SA_SIGINFO;
if(sigaction(SIGIO, &sigio_act, NULL) < 0) {
error_msg("install SIGIO sigaction error");
}
fcntl(devmem_fd, F_SETOWN, getpid());
int oflags = fcntl(devmem_fd, F_GETFL);
fcntl(devmem_fd, F_SETFL, oflags | FASYNC);
/*若F_SETSIG未设置, 默认发送 SIGIO, 即使设置 SA_SIGINFO, siginfo_t 附加信息仍为默认内容, si_code 为默认 SI_KERNEL(值为128);
*若设置 F_SETSIG 为 仍一个有效信号(包括SIGIO),即可收到完整的 siginfo_t 附加信息;
*/
fcntl(devmem_fd, F_SETSIG, SIGIO); //fcntl(devmem_fd, F_SETSIG, SIGUSR1);
while(1){
sleep(1);
}
...
}
// reason就是传入的POLL_IN/POLL_OUT
450 static void send_sigio_to_task(struct task_struct *p,
451 struct fown_struct *fown,
452 int fd, int reason, int group)
453 {
454 /*
455 * F_SETSIG can change ->signum lockless in parallel, make
456 * sure we read it once and use the same value throughout.
457 */
458 int signum = ACCESS_ONCE(fown->signum);
459
460 if (!sigio_perm(p, fown, signum))
461 return;
462
463 switch (signum) {
464 siginfo_t si;
465 default:
466 /* Queue a rt signal with the appropriate fd as its
467 value. We use SI_SIGIO as the source, not
468 SI_KERNEL, since kernel signals always get
469 delivered even if we can't queue. Failure to
470 queue in this case _should_ be reported; we fall
471 back to SIGIO in that case. --sct */
472 si.si_signo = signum;
473 si.si_errno = 0;
474 si.si_code = reason;
475 /* Make sure we are called with one of the POLL_*
476 reasons, otherwise we could leak kernel stack into
477 userspace. */
478 BUG_ON((reason & __SI_MASK) != __SI_POLL);
479 if (reason - POLL_IN >= NSIGPOLL)
480 si.si_band = ~0L;
481 else
482 si.si_band = band_table[reason - POLL_IN];
483 si.si_fd = fd;
484 if (!do_send_sig_info(signum, &si, p, group))
485 break;
486 /* fall-through: fall back on the old plain SIGIO signal */
487 case 0:
488 do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
489 }
490 }
union sigval {
int sival_int;
void *sival_ptr;
};
typedef struct {
int si_signo;
int si_code;
union sigval si_value;
int si_errno;
pid_t si_pid;
uid_t si_uid;
void *si_addr;
int si_status;
int si_band;
} siginfo_t;
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_sigaction=xxx_handler;
act.sa_flags=SA_SIGINFO;
if(sigaction(SIGIO,&act,NULL) < 0)
{
printf("install sigal error\n");
}
void xxx_handler(int signum,siginfo_t *info,void *myact)
{
printf("Receive signal number:%d\n",signum);
printf("si_signo:%d\n", info->si_signo);
printf("si_code:%d\n", info->si_code);
printf("si_value int:%d\n",info->si_value.sival_ptr);
printf("si_value void*:%X\n",(unsigned long)info->si_value.sival_ptr);
printf("si_errno:%d\n", info->si_errno);
printf("si_pid:%d\n", info->si_pid);
printf("si_uid:%d\n", info->si_uid);
printf("si_addr:%X\n",(unsigned long)info->si_addr);
printf("si_status:%d\n", info->si_status);
printf("si_band:%d\n", info->si_band);
}
驱动向应用发出信号 kill_fasync(&dev->async_queue, SIGIO, POLL_IN)打印出以下结果
si_signo:29
si_code:128
si_value int:0
si_value void*:0
si_errno:0
si_pid:0
si_uid:0
si_addr:0
si_status:0
si_band:0
驱动向应用发出信号 kill_fasync(&dev->async_queue, SIGIO, POLL_OUT)打印出以下结果
si_signo:29
si_code:128
si_value int:0
si_value void*:0
si_errno:0
si_pid:0
si_uid:0
si_addr:0
si_status:0
si_band:0
POLL_IN和POLL_OUT的结果是一样的,驱动发信号时应用中的信号处理函数只接收到了si_signo、si_code两个数据,后面的数值都为0,还是没找到kill_fasync第三个参数的意义是在哪里体现的??
void xxx_handler(int signum,siginfo_t *info,void *myact);
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_sigaction=xxx_handler;
act.sa_flags=SA_SIGINFO;
if(sigaction(SIGIO,&act,NULL) < 0)
{
printf("install sigal error\n");
}