[Bug 95331] New: fcntl.2 + sigaction.2 + signal.7 need further information about use of a SA_SIGINFO signal handler that uses si->si_fd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



https://bugzilla.kernel.org/show_bug.cgi?id=95331

            Bug ID: 95331
           Summary: fcntl.2 + sigaction.2 + signal.7 need further
                    information about use of a SA_SIGINFO signal handler
                    that uses si->si_fd
           Product: Documentation
           Version: unspecified
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: man-pages
          Assignee: documentation_man-pages@xxxxxxxxxxxxxxxxxxxx
          Reporter: jason.vas.dias@xxxxxxxxx
        Regression: No

Created attachment 171831
  --> https://bugzilla.kernel.org/attachment.cgi?id=171831&action=edit
File that demonstrates the problem

Despite extensive reading of latest versions of the $subject manual pages 
over the last few days while trying to debug a program that needs to 
read and write pipe file descriptors, I am still none the wiser about
the precise circumstances that the $signum signal, used in a :
  fcntl(fd, F_SETSIG, $signum )  
call, will be sent for an OUTPUT file descriptor. 
The test program, which I will attach, which is run as :
  $ mkfifo -m 0600 /tmp/f.in /tmp/f.out
  $ ./t_sigio_rdwr </tmp/f.in >/tmp/f.out &
  $ echo 'hello' >/tmp/f.in
  ../
  $ read </tmp/f.out
  ^C
only gets a SIGIO+SIGRTMIN signal for the output file descriptor (FD 1) when a
reader DISCONNECTS from its output pipe, by pressing <CTRL+C> - which is pretty
useless, IMHO - the program is expecting to receive a SIGIO+RTMIN signal when a
reader CONNECTs (opens) its output fifo. so that it can send the response.
All the documentation states is in the sigaction manual page:

   * SIGIO/SIGPOLL (the two names are synonyms on Linux) fills in si_band 
         and si_fd.  The si_band event is  a bit  mask  containing  the  same
         values as are filled in the revents field by poll(2).  The si_fd field
         indicates the file descriptor for which the I/O event occurred.
 ...
  si_code:
 ..
 SI_SIGIO
                  Queued  SIGIO  (only  in  kernels up to Linux 2.2; from Linux 
                                 2.4 onward SIGIO/SIGPOLL fills in
                  si_code as described below).
  The following values can be placed in si_code for a SIGIO/SIGPOLL signal:

           POLL_IN
                  Data input available.

           POLL_OUT
                  Output buffers available.

And in fcntl.2 :
        F_SETSIG (int)
              Set the signal sent when input or output becomes possible to the
value given in
              arg.  A value of zero means to send the default SIGIO signal. 
Any other  value
              (including  SIGIO)  is  the signal to send instead, and in this
case additional
              info is available to the signal handler if installed with
SA_SIGINFO.

              By using F_SETSIG with a nonzero value, and setting SA_SIGINFO
for  the  signal
              handler (see sigaction(2)), extra information about I/O events is
passed to the
              handler in a siginfo_t structure.  If the si_code field indicates
the source is
              SI_SIGIO,  the si_fd field gives the file descriptor associated
with the event.
              Otherwise, there is no indication which file descriptors are
pending,  and  you
              should  use  the  usual mechanisms (select(2), poll(2), read(2)
with O_NONBLOCK
              set etc.) to determine which file descriptors are available for
I/O.

              By selecting a real time signal (value >= SIGRTMIN), multiple I/O
events may be
              queued  using the same signal numbers.  (Queuing is dependent on
available mem‐
              ory).  Extra information is available if SA_SIGINFO is set for
the signal  han‐
              dler, as above.



Nowhere does it say WHEN or on what conditions the SIGIO will be generated,
or is it discussed what happens when SIGIO for multiple FDs are queued. 

The following strace output of the program demonstrates the problem:

[pid 11215] rt_sigprocmask(SIG_BLOCK, [PIPE RT_31], [], 8) = 0
[pid 11215] fcntl(1, F_GETFL)           = 0x8001 (flags O_WRONLY|O_LARGEFILE)
[pid 11215] fcntl(1, F_SETFL, O_WRONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] fcntl(1, 0xf /* F_??? */, 0x7fff1c940090) = 0
[pid 11215] fcntl(1, F_SETSIG, 0x3f)    = 0
[pid 11215] fcntl(0, F_GETFL)           = 0x8000 (flags O_RDONLY|O_LARGEFILE)
[pid 11215] fcntl(0, F_SETFL, O_WRONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] fcntl(0, 0xf /* F_??? */, 0x7fff1c940090) = 0
[pid 11215] fcntl(0, F_SETSIG, 0x3f)    = 0
[pid 11215] rt_sigaction(SIGRT_31, {0x400b4d, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, {SIG_DFL, [], 0},
8) = 0
[pid 11215] rt_sigaction(SIGPIPE, {0x400e49, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, {SIG_DFL, [], 0},
8) = 0
[pid 11215] fcntl(1, F_SETFL, O_WRONLY|O_LARGEFILE) = 0
[pid 11215] write(2, "reading\n", 8reading
)    = 8
[pid 11215] read(0, "hello\n", 8192)    = 6
[pid 11215] write(2, "read 6 bytes\n", 13read 6 bytes
) = 13
[pid 11215] write(2, "writing: 6 bytes\n", 17writing: 6 bytes
) = 17
[pid 11215] write(1, "hello\n", 6)      = 6
[pid 11215] write(2, "wrote : 6\n", 10wrote : 6
) = 10
[pid 11215] rt_sigprocmask(SIG_BLOCK, [PIPE RT_31], [PIPE RT_31], 8) = 0
[pid 11215] fcntl(0, F_GETFL)           = 0xa000 (flags
O_RDONLY|O_ASYNC|O_LARGEFILE)
[pid 11215] fcntl(0, F_SETFL, O_RDONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] fcntl(0, 0xf /* F_??? */, 0x7fff1c940090) = 0
[pid 11215] fcntl(0, F_SETSIG, 0x3f)    = 0
[pid 11215] fcntl(0, F_GETFL)           = 0xa000 (flags
O_RDONLY|O_ASYNC|O_LARGEFILE)
[pid 11215] fcntl(0, F_SETFL, O_RDONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] fcntl(0, 0xf /* F_??? */, 0x7fff1c940090) = 0
[pid 11215] fcntl(0, F_SETSIG, 0x3f)    = 0
[pid 11215] rt_sigaction(SIGRT_31, {0x400b4d, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, {0x400b4d, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, 8) = 0
[pid 11215] rt_sigaction(SIGPIPE, {0x400e49, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, {0x400e49, [],
SA_RESTORER|SA_STACK|SA_NODEFER|SA_SIGINFO, 0x7fc6c47f0340}, 8) = 0
[pid 11215] fcntl(1, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
[pid 11215] write(2, "reading\n", 8reading
)    = 8
[pid 11215] read(0, "", 8192)           = 0
[pid 11215] write(2, "read returned 0 - waiting for SI"..., 36read returned 0 -
waiting for SIGIO
) = 36
[pid 11215] fcntl(0, F_SETFL, O_RDONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] rt_sigprocmask(SIG_UNBLOCK, [PIPE RT_31], [PIPE RT_31], 8) = 0
[pid 11215] pause()                     = ? ERESTARTNOHAND (To be restarted if
no handler)
[pid 11215] --- SIGRT_31 {si_signo=SIGRT_31, si_code=0x1, si_pid=65, si_uid=0}
---
[pid 11215] --- SIGRT_31 {si_signo=SIGRT_31, si_code=0x1, si_pid=65, si_uid=0}
---
[pid 11215] write(2, "IO: SI_FD: 0\n", 13IO: SI_FD: 0
) = 13
[pid 11215] rt_sigreturn()              = 0
[pid 11215] write(2, "IO: SI_FD: 0\n", 13IO: SI_FD: 0
) = 13
[pid 11215] rt_sigreturn()              = -1 EINTR (Interrupted system call)
[pid 11215] rt_sigprocmask(SIG_BLOCK, [PIPE RT_31], [], 8) = 0
[pid 11215] write(2, "after SIGIO - retrying read \n", 29after SIGIO - retrying
read 
) = 29
[pid 11215] fcntl(0, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
[pid 11215] write(2, "reading\n", 8reading
)    = 8
[pid 11215] read(0, "hello\n", 8192)    = 6
[pid 11215] write(2, "read 6 bytes\n", 13read 6 bytes
) = 13
[pid 11215] write(2, "writing: 6 bytes\n", 17writing: 6 bytes
) = 17
[pid 11215] write(1, "hello\n", 6)      = -1 EPIPE (Broken pipe)
[pid 11215] rt_sigprocmask(SIG_UNBLOCK, [PIPE RT_31], [PIPE RT_31], 8) = 0
[pid 11215] --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=11215,
si_uid=1001} ---
[pid 11215] write(2, "PIPE: SI_FD: 0\n", 15PIPE: SI_FD: 0
) = 15
[pid 11215] rt_sigreturn()              = 0
[pid 11215] write(2, "PIPE - waiting for connection\n", 30PIPE - waiting for
connection
) = 30
[pid 11215] fcntl(1, F_SETFL, O_RDONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] pause(

Now I have to press <CTRL+C>, and only AFTER the reader has disonnected does
the
t_sigio_rdwr process get a SIGIO:


)                     = ? ERESTARTNOHAND (To be restarted if no handler)
[pid 11215] --- SIGRT_31 {si_signo=SIGRT_31, si_code=0x2, si_pid=772, si_uid=0,
si_value={int=1, ptr=0x1}} ---
[pid 11215] write(2, "IO: SI_FD: 1\n", 13IO: SI_FD: 1
) = 13
[pid 11215] rt_sigreturn()              = -1 EINTR (Interrupted system call)
[pid 11215] fcntl(1, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
[pid 11215] rt_sigprocmask(SIG_BLOCK, [PIPE RT_31], [], 8) = 0
[pid 11215] write(2, "AFTER SIGIO : 1\n", 16AFTER SIGIO : 1
) = 16
[pid 11215] write(2, "writing: 6 bytes\n", 17writing: 6 bytes
) = 17
[pid 11215] write(1, "hello\n", 6)      = -1 EPIPE (Broken pipe)
[pid 11215] rt_sigprocmask(SIG_UNBLOCK, [PIPE RT_31], [PIPE RT_31], 8) = 0
[pid 11215] --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=11215,
si_uid=1001} ---
[pid 11215] write(2, "PIPE: SI_FD: 1\n", 15PIPE: SI_FD: 1
) = 15
[pid 11215] rt_sigreturn()              = 0
[pid 11215] write(2, "PIPE - waiting for connection\n", 30PIPE - waiting for
connection
) = 30
[pid 11215] fcntl(1, F_SETFL, O_RDONLY|O_ASYNC|O_LARGEFILE) = 0
[pid 11215] pause(

But since the reader had to disconnect, it gets SIGPIPE trying to write,
so never leaves the state of trying to write back the second input line.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux