2

我有

struct sigaction pipe_act;
pipe_act.sa_flags = SA_SIGINFO;
pipe_act.sa_sigaction = sigpipehandler
sigaction(SIGPIPE, &pipe_act, NULL);

当我尝试编写 sigpipeHandler 时,gcc 告诉我它需要三个参数。第二个参数没问题,它是 siginfo_t 结构,包含有关信号的信息,第一个和第三个(一个 int 和一个 void 变量),它们是什么?

4

2 回答 2

10

男人sigaction说:

 The sigaction structure is defined as something like:

       struct sigaction {
           void     (*sa_handler)(int);
           void     (*sa_sigaction)(int, siginfo_t *, void *);
           sigset_t   sa_mask;
           int        sa_flags;
           void     (*sa_restorer)(void);
       };  

   sa_handler specifies the action to be associated with signum and may be
   SIG_DFL for the default action, SIG_IGN to ignore  this  signal,  or  a
   pointer to a signal handling function.  This function receives the sig‐
   nal number as its only argument.

   If SA_SIGINFO is specified in sa_flags, then sa_sigaction  (instead  of
   sa_handler)  specifies  the  signal-handling function for signum.  This
   function receives the signal number as its first argument, a pointer to
   a  siginfo_t as its second argument and a pointer to a ucontext_t (cast
   to void *) as its third argument.


   ....
   The siginfo_t argument to sa_sigaction is a struct with  the  following
   elements:
       siginfo_t {
           int      si_signo;    /* Signal number */
           int      si_errno;    /* An errno value */
           int      si_code;     /* Signal code */
           int      si_trapno;   /* Trap number that caused
                                    hardware-generated signal
                                    (unused on most architectures) */
           pid_t    si_pid;      /* Sending process ID */
           uid_t    si_uid;      /* Real user ID of sending process */
           int      si_status;   /* Exit value or signal */
           clock_t  si_utime;    /* User time consumed */
           clock_t  si_stime;    /* System time consumed */
           sigval_t si_value;    /* Signal value */
           int      si_int;      /* POSIX.1b signal */
           void    *si_ptr;      /* POSIX.1b signal */
           int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
           int      si_timerid;  /* Timer ID; POSIX.1b timers */
           void    *si_addr;     /* Memory location which caused fault */
           long     si_band;     /* Band event (was int in
                                    glibc 2.3.2 and earlier) */
           int      si_fd;       /* File descriptor */
           short    si_addr_lsb; /* Least significant bit of address
                                    (since kernel 2.6.32) */
       }
于 2012-09-25T17:09:04.747 回答
5

第一个参数是信号编号。它是必需的,因为您可以对多个不同的信号使用相同的处理程序。

第三个参数包含接收信号时使用的上下文。可以通过makecontext()/setcontext()/getcontext()/swapcontext()函数使用上下文来实现用户空间线程。上下文结构还包含不可移植的体系结构特定信息,例如接收到信号时处理器寄存器的值。弄乱处理器状态需要您自担风险。

于 2012-09-25T17:45:56.760 回答