Subject: asynchronous i/o
To: None <netbsd-users@NetBSD.ORG, port-i386@NetBSD.ORG>
From: Brook Milligan <brook@trillium.NMSU.Edu>
List: port-i386
Date: 06/09/1996 22:39:39
I am trying to write an application that relies on asynchronous i/o on
a file it opens (i.e., not the stdio streams).  I thought the
procedure for this was the following:

1. open the file (in this case /dev/tty00)
2. have SIGIO signals sent to this process (fcntl(fd, F_SETOWN, pid))
3. install a signal handler
4. enable asynchronous i/o on the file (fcntl(fd, F_SETFL, O_ASYNC))
5. wait for input

I tried to implement the above (see the program included below along
with the output from running it on a netbsd 1.1/i386 box) but cannot
get the SIGIO signal sent to anything other than the process group 1.
The fcntl(fd, F_SETOWN, pid or -pgrp) calls always return an error
indicating "Inappropriate ioctl for device".

Am I doing the wrong thing to get asynchronous i/o?  I'd appreciate
any help you can offer.  Thanks!

Cheers,
Brook

========================  output  =========================================
PID = 160; Process group = 160
SIGIO for file descriptor 3 sent to -1
Cannot send SIGIO for file descriptor 3 to 160; Inappropriate ioctl for device
Cannot send SIGIO for file descriptor 3 to -160; Inappropriate ioctl for device

========================  program  ========================================
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/uio.h>

int fd;

void io_interrupt ()
{
  char buffer [1024];
  size_t n_in;
  if (n_in = read (fd, &buffer, 1024) > 0)
    write (1, &buffer, n_in);
}

int main ()
{
  int error;
  pid_t pid;
  pid_t pgrp;

  pid = getpid ();
  pgrp = getpgrp ();
  fprintf (stderr, "PID = %d; Process group = %d\n", pid, pgrp);
				/* open file */
  fd = open ("/dev/tty00", O_RDWR, 644);
  fprintf (stderr, "SIGIO for file descriptor %d sent to %d\n", 
	   fd, fcntl (fd, F_GETOWN, 0));
				/* set destination of SIGIO */
  error = fcntl (fd, F_SETOWN, pid);
  if (error)
    {
      fprintf (stderr, "Cannot send SIGIO for file descriptor %d to %d; %s\n",
	       fd, pid, strerror (errno));
      error = fcntl (fd, F_SETOWN, -pgrp);
      if (error)
	{
	  fprintf (stderr, "Cannot send SIGIO for file descriptor %d to %d; %s\n",
		   fd, -pgrp, strerror (errno));
	  exit (1);
	}
    }
				/* NEVER REACHED! */
  fprintf (stderr, "SIGIO for file descriptor %d sent to %d\n", 
	   fd, fcntl (fd, F_GETOWN, 0));
				/* install signal handler */
  signal (SIGIO, io_interrupt);
				/* set asynchronous i/o */
  error = fcntl (fd, F_SETFL, O_ASYNC);
				/* write to file */
  write (fd, "f\r", 2);
				/* wait for response */
  sleep (5);
  return 0;
}