title: si_value not a member of siginfo_t inside sigaction handler using POSIX message queues
body: <p>I am sure I am missing something obvious but my problem is as follows.</p>
  
  <p>As a programming exercise I am trying to create an async posix message queue server to handle incoming messages asynchronously in a handler.</p>
  
  <p>Now according to my documentation <a href="http://man7.org/linux/man-pages/man2/sigaction.2.html" rel="nofollow noreferrer">sigaction(2)</a>, <a href="https://linux.die.net/man/3/mq_notify" rel="nofollow noreferrer">mq_notify(3)</a> and <a href="http://man7.org/linux/man-pages/man7/sigevent.7.html" rel="nofollow noreferrer">sigevent(7)</a> my thought process should work. Before I post my code I'll outline my thought process on how it should be working.</p>
  
  <ul>
  <li>Using <code>sigaction</code> and <code>SA_SIGINFO</code> I will set the signal handler for <code>SIGIO</code>. </li>
  <li>Using <code>mq_notify</code> and <code>struct sigevent</code> I will tell my message queue to send <code>SIGIO</code> to the current process when a message arrives. </li>
  <li>By placing a pointer to my <code>mqd_t</code> for my message queue into the <code>struct sigevent.sigen_value.sigval_ptr</code> I will be able to retrieve this value in my signal handler through <code>struct siginfo</code>. </li>
  <li>As<code>sigevent(7)</code> tells me that when <code>SIGEV_SIGNAL</code> is set in <code>sigev_notify</code> then <code>si_code</code>, <code>si_signo</code> and <code>si_value</code> are set in the signal handler's <code>siginfo</code>. Specifically <code>si_value</code> is set to the value passed in for <code>sigev_value</code> when calling <code>mq_nofity</code>. </li>
  <li>In my signal handler I should be able to get my message queue's <code>mqd_t</code> by doing something like <code>(mqd_t *)(info-&gt;si_value.sival_ptr)</code> where info is the <code>siginfo_t*</code> passed as an argument to my signal handler. I have my <code>mqd_t</code> in a struct <code>mq_info_t</code> as I will later do some more stuff with this.</li>
  </ul>
  
  <p>Now my problem seems to be stemming from something different, but I thought I would outline my thought process in case it is somehow relevant. According to <code>sigaction(2)</code>, <code>siginfo_t</code> is a large struct containing all sorts of information, including <code>si_value</code>.</p>
  
  <p>Now in my gdb I am getting the error that my <code>siginfo_t</code> in my signal handler does not have a member named <code>si_value</code>. The same idea is mentioned in this question <a href="https://stackoverflow.com/questions/44879718/sigaction-using-void-sa-sigactionint-siginfo-t-void">here</a>.</p>
  
  <blockquote>
    <p>(gdb) p *info $1 = {si_signo = 29, si_errno = 0, si_code = -3, __pad0
    = 0, _sifields = {_pad = {128611, 1000, -8896, 32767, 
          0 }, _kill = {si_pid = 128611, si_uid = 1000}, _timer = {si_tid = 128611, si_overrun = 1000, si_sigval = {
            sival_int = -8896, sival_ptr = 0x7fffffffdd40}}, _rt = {si_pid = 128611, si_uid = 1000, si_sigval = {sival_int = -8896,
            sival_ptr = 0x7fffffffdd40}}, _sigchld = {si_pid = 128611, si_uid = 1000, si_status = -8896, si_utime = 0, si_stime = 0},
        _sigfault = {si_addr = 0x3e80001f663, si_addr_lsb = -8896, _bounds = {_addr_bnd = {_lower = 0x0, _upper = 0x0}, _pkey = 0}},
        _sigpoll = {si_band = 4294967424611, si_fd = -8896}, _sigsys = {_call_addr = 0x3e80001f663, _syscall = -8896, _arch = 32767}}}</p>
  </blockquote>
  
  <p>Looking at where <code>siginfo_t</code> is defined for my build I found that the structure defined in <code>/usr/include/bits/types/siginfo_t.h</code> had the same structure. I am thinking this is some issue to do with the feature macros of my builds but I am do not know much in that area. My build has <code>#define _POSIX_C_SOURCE 199309L</code>.</p>
  
  <p>Now the key components of my code are as follows</p>
  
  <pre><code>#define _POSIX_C_SOURCE 199309L
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;mqueue.h&gt;
  #include &lt;string.h&gt;
  
  typedef struct mq_info {
      mqd_t fd;
  } mq_info_t;
  
  /** Handler for receiving async messages */
  void sigHandler(int signal, siginfo_t *info, void *context)
  {
      char buffer[MAX_SIZE + 1];
      int must_stop = 0;
      ssize_t bytes_read;
      mq_info_t *mq_i = (mq_info_t *)(info-&gt;si_value.sival_ptr);
      mqd_t mq = mq_i-&gt;fd;
  
      printf("In handler\n");
  
      do {
          bytes_read = mq_receive(mq, buffer, MAX_SIZE, NULL);
  
          printf("MQ received: %s\n", buffer);
      } while (bytes_read &gt; 0);
  
      printf("left handler\n");
  }
  
  int openMessageQueue(char *name, long max_msg_num, long max_msg_size)
  {
      mq_info_t *mq_i = calloc(1, sizeof(mq_info_t));
      struct mq_attr attr;
      struct sigaction sa;
      struct sigevent ev;
      union sigval sv = { .sival_ptr = &amp;mq_i };
  
      attr.mq_flags = O_NONBLOCK; // Async
      attr.mq_maxmsg = max_msg_num;
      attr.mq_msgsize = max_msg_size;
      attr.mq_curmsgs = 0; // Num of messages currently in queue
  
      if (-1 == (mq_i-&gt;fd = mq_open(name, O_CREAT | O_RDONLY, 0644, &amp;attr)))
          goto error;
  
      printf("queue opened\n");
  
      /** Setup handler for SIGIO */
      sa.sa_flags = SA_SIGINFO;
      sa.sa_sigaction = sigHandler;
      printf("Sighandler: %p\n", sigHandler);
      sigfillset(&amp;sa.sa_mask);
      sigdelset(&amp;sa.sa_mask, SIGIO);
      if (sigaction(SIGIO, &amp;sa, NULL))
          goto error;
  
      printf("sigaction done\n");
  
      /** Set up process to be informed about async queue event */
      ev.sigev_notify = SIGEV_SIGNAL; // Specify a signal should be sen
      ev.sigev_signo = SIGIO; // Signal of interest
      ev.sigev_value =
          sv; // Suplementary data passed to signal handling fuction
      ev.sigev_notify_function = NULL; // Used by SIGEV_THREAD
      ev.sigev_notify_attributes = NULL; // Used by SIGEV_THREAD
  
      /** Register this process to receive async notifications when a new message  */
      /**     arrives on the specified message queue  */
      if (mq_notify(mq_i-&gt;fd, &amp;ev) &lt; 0) {
          perror("notify failed");
          goto error;
      }
  
      printf("notify done\n");
  
      return 0;
  
  error:
      mq_unlink(name);
      return -1;
  }
  </code></pre>
  
  <p>Thanks in advance, I hope I have provided all relevant infromation.</p>
  
  <p>Arch Linux w 5.3.8 kernel</p>