This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

SIGIO reraising?


Hello,

I have trouble in SIGIO handling, but I don't know whether this is the
right place to ask help.  Please forgive me about the disturbing and
take a look at my questions.  Thanks.

To test SIGIO handling, I wrote a simple program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <regex.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>

volatile int input_available = 0;
char input_buffer[1024];
volatile int input_buffer_nread;
volatile int sigio_handler_called_times = 0;

void
sigio_handler (int sigid)
{
 int n_to_read = 0;
 int i;

 input_available = 1;
 sigio_handler_called_times++;

 ioctl (0, FIONREAD, &n_to_read);
 if (n_to_read > sizeof input_buffer)
   n_to_read = sizeof input_buffer;
 input_buffer_nread = read (0, input_buffer, n_to_read);

 printf ("[ %d ]\n", sigio_handler_called_times);
 sleep (1);
}

int
main (int argc, char *argv[])
{
 struct termios tty_attr;

printf ("%s\n", ttyname (0));

signal (SIGIO, sigio_handler);

 tcgetattr (0, &tty_attr);
 tty_attr.c_lflag &= ~ICANON;
 tty_attr.c_lflag &= ~ECHO;
 tcsetattr (0, TCSANOW, &tty_attr);

 fcntl (0, F_SETOWN, getpid ());
 fcntl (0, F_SETFL, (O_NDELAY | O_ASYNC));

 while (1)
   {
     if (input_available)
       {
         int i;
         for (i = 0; i < input_buffer_nread; i++)
           printf ("%c", input_buffer[i]);
         input_available = 0;
       }
   }

 return 0;
}

I expect the loop in main checks whether there is some input time by
time, and display the available input when SIGIO comes.  But the
program behavior is not as expected.  The output of the program is:

$ ./a.out
/dev/pts/6
[ 1 ]
[ 2 ]
[ 3 ]
[ 4 ]
[ 5 ]
[ 6 ]
[ 7 ]
... ...

The first line of the output shows the tty's name.  Before I press any
key, there's no any further output from the program.  This is
expected, since the program is busy executing the loop in the main
function.

Things become strange after I type a character on the keyboard.  The
typed character is not displayed (outside the SIGIO handler), and the
signal SIGIO is re-raised once and once again.  As showed above, the
SIGIO handler prints [ 1 ], [ 2 ], ... but never leave the control to
the loop in the main function.

I traced the progress, as below:

$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 23 vars */]) = 0
uname({sys="Linux", node="imdev3.corp.cnb.yahoo.com", ...}) = 0
brk(0) = 0x86b9000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=69827, ...}) = 0
old_mmap(NULL, 69827, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fee000
close(3) = 0
open("/lib/tls/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\317"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1454462, ...}) = 0
old_mmap(0x318000, 1219772, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x318000
old_mmap(0x43c000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x124000) = 0x43c000
old_mmap(0x440000, 7356, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x440000
close(3) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fed000
mprotect(0x43c000, 4096, PROT_READ) = 0
mprotect(0x314000, 4096, PROT_READ) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7fed940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7fee000, 69827) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
brk(0) = 0x86b9000
brk(0x86db000) = 0x86db000
readlink("/proc/self/fd/0", "/dev/pts/7", 4095) = 10
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 7), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fff000
write(1, "/dev/pts/7\n", 11/dev/pts/7
) = 11
rt_sigaction(SIGIO, {0x8048548, [IO], SA_RESTORER|SA_RESTART, 0x33f8c8}, {SIG_DFL}, 8) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
getpid() = 4974
fcntl64(0, F_SETOWN, 4974) = 0
fcntl64(0, F_SETFL, O_RDONLY|O_NONBLOCK|O_ASYNC) = 0
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 1 ]\n", 6[ 1 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 2 ]\n", 6[ 2 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 3 ]\n", 6[ 3 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 4 ]\n", 6[ 4 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 5 ]\n", 6[ 5 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 6 ]\n", 6[ 6 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
ioctl(0, FIONREAD, [0]) = 0
read(0, "", 0) = 0
write(1, "[ 7 ]\n", 6[ 7 ]
) = 6
rt_sigprocmask(SIG_BLOCK, [CHLD], [IO], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [IO], NULL, 8) = 0
nanosleep({1, 0}, {1, 0}) = 0
sigreturn() = ? (mask now [])
--- SIGIO (I/O possible) @ 0 (0) ---
... ... ... ... ... ... ...


As we see, SIGIO is raised again and again, even when there is no
input on fd 0.

I don't see big faults in my program.  Is there something I missed?
How should I fix the problem?  Thanks very much.

Regards,
Guanpeng Xu

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]