2006-11-10 22:57:42

by Mikulas Patocka

[permalink] [raw]
Subject: O_ASYNC question

Hi

Does anyone know what should O_ASYNC do? The manual page says that it
sends SIGIO to the process when input or output is possible, however it is
very vaguely defined.

Should the signal be level-triggered (being sent constantly while IO is
possible) or edge-triggered (being sent only when state changes)?

Should the signal be sent on read or write availability or any of them or
the one selected with O_RDONLY/O_WRONLY/O_RDRW?

I did some test and it looks almost unusable, see this program, it behaves
very strangely:

1. when you press some key and not yet ENTER, SIGIO is sent although there
are no characters to read because ENTER was not pressed.

2. there is no way to stop the flood of SIGIOs, once triggered, they are
coming over and over again. When all terminal characters are read, SIGIOs
is still signaled, even when I drop and set O_ASYNC flag sith fcntl, it
doesn't help.

On the other hand, FreeBSD and Solaris don't send any signal.

Mikulas

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

int h;

void async(int s)
{
char c;
int x = 0;
printf("signal\n"); fflush(stdout);
while (read(h, &c, 1) == 1) x++;
printf("read: %d\n", x); fflush(stdout);
if (fcntl(h, F_SETFL, O_NONBLOCK) < 0) perror("fcntl"), exit(1);
if (fcntl(h, F_SETFL, O_ASYNC | O_NONBLOCK) < 0) perror("fcntl"), exit(1);
sleep(1);
}

int main(void)
{
h = open("/dev/tty", O_RDONLY | O_NONBLOCK);
if (h < 0) perror("open"), exit(1);
signal(SIGIO, async);
if (fcntl(h, F_SETFL, O_ASYNC | O_NONBLOCK) < 0) perror("fcntl"), exit(1);
while (1) sleep(1);
}