2

私は持っています

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

sigpipeHandlerを書き込もうとしたとき、gccは3つの引数が必要だと言った。2番目の引数は問題ありません。シグナルに関する情報を含むsiginfo_t構造体で、1番目と3番目(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

最初の引数はシグナル番号です。複数の異なるシグナルに対して同じハンドラーを使用する可能性があるため、これが必要です。

3 番目の引数には、シグナルを受信したときに使用されていたコンテキストが含まれます。関数を介してコンテキストを使用して、makecontext()/setcontext()/getcontext()/swapcontext()ユーザー空間スレッドを実装できます。コンテキスト構造には、移植性のないアーキテクチャ固有の情報も含まれます。たとえば、信号を受信したときのプロセッサ レジスタの値などです。あなた自身の責任でプロセッサの状態を台無しにしてください。

于 2012-09-25T17:45:56.760 に答える