Subject: Re: O_ASYNC on ttys
To: None <christos@zoulas.com>
From: maximum entropy <entropy@tappedin.com>
List: tech-kern
Date: 07/07/2001 20:09:04
>Recebido-para: <entropy@tappedin.com>
>From: christos@zoulas.com (Christos Zoulas)
>Date: Sat, 7 Jul 2001 19:30:33 -0400
>Organization: Astron Software
>Cc: tech-kern@netbsd.org
>
>On Jul 7,  6:26pm, entropy@tappedin.com (maximum entropy) wrote:
>-- Subject: Re: O_ASYNC on ttys
>
>| I'm fairly certain that this change would break the POSIX conformance
>| of our tcsetpgrp(3).
>| 
>
>How, POSIX does not know about FASYNC?

Sorry, by "this change" I meant der Mouse's suggested change to
TIOCSPGRP.  I missed the beginning of the thread, and just took that
opportunity to jump in and point that out.

After reading the thread in the archives, I'm not sure any of it is
necessary.  O_ASYNC cares about the process group or PID indicated by
an earlier call to fcntl(fd, F_SETOWN, pid) call, not the process
group of a controlling tty.  So der Mouse should be able to get the
SIGIO signals he wants without any kernel changes.  Below is an
example using pipes.

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

int gotsigio = 0;

void
sigiohandler(int sig) {
  gotsigio = 1;
}

int
main()
{
  int pipefds[2];
  char *str1 = "Hello, world!\n";
  char str2[PIPE_BUF];
  int r;
  int pid;
  struct sigaction sa_sigio;
  int flags;

  sa_sigio.sa_handler = sigiohandler;
  if (sigemptyset(&(sa_sigio.sa_mask)) == -1) {
    perror("sigemptyset");
    exit(EXIT_FAILURE);
  }
  sa_sigio.sa_flags = 0;
  if (sigaction(SIGIO, &sa_sigio, NULL) == -1) {
    perror("sigaction");
    exit(EXIT_FAILURE);
  }
  if (pipe(pipefds) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
  }
  if ((pid = fcntl(pipefds[0], F_GETOWN, NULL)) == -1) {
    perror("fcntl F_GETOWN");
    exit(EXIT_FAILURE);
  }
  printf("fcntl FGETOWN: %d\n", pid);
  printf("my pid: %d\n", (int) getpid());
  if ((pid = fcntl(pipefds[0], F_SETOWN, (int) getpid())) == -1) {
    perror("fcntl F_GETOWN");
    exit(EXIT_FAILURE);
  }
  if ((pid = fcntl(pipefds[0], F_GETOWN, NULL)) == -1) {
    perror("fcntl F_GETOWN");
    exit(EXIT_FAILURE);
  }
  printf("fcntl FGETOWN: %d\n", pid);
  if ((flags = fcntl(pipefds[0], F_GETFL, NULL)) == -1) {
    perror("fcntl F_GETFL");
    exit(EXIT_FAILURE);
  }
  flags |= O_ASYNC;
  if (fcntl(pipefds[0], F_SETFL, flags) == -1) {
    perror("fcntl F_SETFL");
    exit(EXIT_FAILURE);
  }
  printf("gotsigio: %d\n", gotsigio);
  if (write(pipefds[1], str1, strlen(str1) + 1) == -1) {
    perror("write");
    exit(EXIT_FAILURE);
  }
  printf("gotsigio: %d\n", gotsigio);
  if (close(pipefds[1]) == -1) {
    perror("close");
    exit(EXIT_FAILURE);
  }
  while ((r = read(pipefds[0], str2, PIPE_BUF)) != 0) {
    if (r == -1) {
      perror("read");
      exit(EXIT_FAILURE);
    }
    printf("%.*s", PIPE_BUF, str2);
  }
  exit(EXIT_SUCCESS);
}
    
1[545]entropy@zippy:~/c $ ./a.out
fcntl FGETOWN: 0
my pid: 1212
fcntl FGETOWN: 1212
gotsigio: 0
gotsigio: 1
Hello, world!

Cheers,
entropy

--
entropy -- it's not just a good idea, it's the second law.