SIGIO arriving for file descriptors I did not set it for and when no IO is possible

前端 未结 1 376
囚心锁ツ
囚心锁ツ 2020-12-11 04:51

I am trying to receive a signal when I/O is possible on a file descriptor. The program needs to be doing something else when it is not doing I/O, so using select(2) is not

相关标签:
1条回答
  • 2020-12-11 05:07

    Ah, interesting.

    The short answer is, a SIGIO is repeatedly arriving for stdin because stdin is writeable, and, separately, your SIGIO delivery is not quite properly set up.

    Why is si_fd apparently unreliable?

    First, you need to specify SA_SIGINFO in sa_flags before you can safely use an sa_sigaction handler.

    Second, you need to #define _GNU_SOURCE and explicitly F_SETSIG to SIGIO before Linux will fill in si_fd (and si_band, for that matter) for you. A bit silly, IMHO, but so it is. Without this, the value passed in to si_fd is not meaningful, as you discovered.

    Why is SIGIO being delivered over and over?

    I'm guessing your program's stdin is inherited from your invoking shell, which I'd guess is a terminal device and is writeable. Just as fd 0 would continuously select(2) writeable, so will it continuously generate SIGIOs for you.

    In any case, si_band holds the answer. Enable F_SETSIG, #include <poll.h>, and inspect si_band for POLLIN, POLLOUT, etc., to determine which I/O events tripped the signal.

    Really, stdin is writeable?

    Yeah. Try these for comparison:

    $ [ -w /dev/stdin ] && echo Yes, stdin is writeable
    Yes, stdin is writeable    
    
    # Endless SIGIOs
    $ ./my-sigio-prog
    ^C
    
    # No SIGIO
    $ ./my-sigio-prog < /dev/null
    
    # Two SIGIOs, after a delay.  One for line-buffered "foo\n" and one for EOF
    $ { sleep 3; echo foo; sleep 3; } | ./my-sigio-prog
    
    0 讨论(0)
提交回复
热议问题