Subject: Re: kqueue: pipes and EOF
To: None <current-users@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: current-users
Date: 10/07/2004 21:09:58
--p2kqVDKq5asng8Dg
Content-Type: multipart/mixed; boundary="xXmbgvnjoT4axfJE"
Content-Disposition: inline


--xXmbgvnjoT4axfJE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Christian Biere wrote:
> Is there any reason why kqueue() doesn't return a EVFILT_READ event
> with EV_EOF set in this case or is this a bug?

I've attached a short program to demonstrate the difference. Should I
send-pr it?

--=20
Christian

--xXmbgvnjoT4axfJE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pipe_test.c"
Content-Transfer-Encoding: quoted-printable

/*
 * To see the effect using when kqueue():
 * cc -DUSE_KQUEUE pipe_test.c -o pipe_test
 *
 * The same using poll():
 * cc pipe_test.c -o pipe_test
 */
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

static void fatal(const char *s);

#ifdef USE_KQUEUE
#include <sys/event.h>
#include <sys/time.h>

static void
wait_for_eof(int fd)
{
  int kq;
  struct kevent kev;
  static const struct timespec ts =3D { 0, 0 };

  kq =3D kqueue();
  if (-1 =3D=3D kq)
    fatal("kqueue");

  EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
  if (kevent(kq, &kev, 1, 0, 0, &ts))
    fatal("kevent()");

  while (-1 =3D=3D kevent(kq, NULL, 0, &kev, 1, NULL)) {
    if (errno !=3D EINTR)
      fatal("kevent()");
  }
}

#else /* !USE_KQUEUE */

#include <poll.h>

static void
wait_for_eof(int fd)
{
  struct pollfd pfd;

  pfd.fd =3D fd;
  pfd.events =3D POLLIN;
  while (-1 =3D=3D poll(&pfd, 1, INFTIM)) {
    if (errno !=3D EINTR)
      fatal("poll()");
  }
}

#endif

static void
fatal(const char *s)
{
  perror(s);
  exit(EXIT_FAILURE);
}

int main(void)
{
  int fds[2];

  if (pipe(fds))
    fatal("pipe()");
 =20
  switch (fork()) {
  case -1:
    fatal("fork()");
    break;
  case 0: /* Child */
    close(fds[1]);

    wait_for_eof(fds[0]);
    printf("Child terminates now\n");
    exit(EXIT_SUCCESS);
    break;
  default: /* Parent */
    close(fds[0]);
  }

  sleep(4);
  printf("Parent terminates now\n");
  exit(EXIT_SUCCESS);
}


--xXmbgvnjoT4axfJE--

--p2kqVDKq5asng8Dg
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (NetBSD)

iD8DBQFBZZSG0KQix3oyIMcRAqftAJ9G5NPgrFUNfdSnsTANElwWbgvV2wCdFhiv
TaXix2BAfwNhrivtDUbOyc0=
=41Nv
-----END PGP SIGNATURE-----

--p2kqVDKq5asng8Dg--