I think that changing the behavior of the existing API in a way that
gratuitously increases the differences between BSDs is unwise.  IMHO, we
should follow NetBSD on this and add kqueue1(), that being obviously
consistent with the previous 'add flags argument' extensions: pipe2(),
dup3(), and accept4().

(As you know, close-on-fork is imposed because the "take a descriptor
number" filters are specified in a way tied to a struct filedesc and
there's no obvious extension to the kqueue behavior for sharing it across
processes.  Oh, and as a result trying to do so would result in
use-after-frees and/or assertion failures in the kernel.  Using a kqueue
after exec() is weird, but not logically undefined in that way.)

Philip

On Sun, Aug 13, 2023 at 4:55 AM Visa Hankala <v...@hankala.org> wrote:

> FreeBSD and NetBSD have variants of the kqueue(2) system call that
> allow setting the close-on-exec flag on the returned file descriptor.
>
> In general, I think it is good that the flag can be set atomically
> for new descriptors. However, it seems to me that it is almost surely
> a mistake if a kqueue descriptor is passed over an exec.
>
> Instead of adding a new system call, maybe close-on-exec should be
> enabled automatically by kqueue(2). Today it feels backwards that
> close-on-exec is off by default.
>
> Note that kqueue cannot be inherited by accident in fork-then-exec
> situations because fork(2) closes kqueue descriptors for the child
> process.
>
> Index: sys/kern/kern_event.c
> ===================================================================
> RCS file: src/sys/kern/kern_event.c,v
> retrieving revision 1.197
> diff -u -p -r1.197 kern_event.c
> --- sys/kern/kern_event.c       13 Aug 2023 08:29:28 -0000      1.197
> +++ sys/kern/kern_event.c       13 Aug 2023 10:42:45 -0000
> @@ -932,7 +932,7 @@ sys_kqueue(struct proc *p, void *v, regi
>         *retval = fd;
>         LIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_next);
>         kq = NULL;
> -       fdinsert(fdp, fd, 0, fp);
> +       fdinsert(fdp, fd, UF_EXCLOSE, fp);
>         FRELE(fp, p);
>  out:
>         fdpunlock(fdp);
> Index: lib/libc/sys/kqueue.2
> ===================================================================
> RCS file: src/lib/libc/sys/kqueue.2,v
> retrieving revision 1.48
> diff -u -p -r1.48 kqueue.2
> --- lib/libc/sys/kqueue.2       13 Aug 2023 08:29:28 -0000      1.48
> +++ lib/libc/sys/kqueue.2       13 Aug 2023 10:42:45 -0000
> @@ -74,6 +74,7 @@ on a file descriptor will remove any kev
>  .Pp
>  .Fn kqueue
>  creates a new kernel event queue and returns a descriptor.
> +The new descriptor has close-on-exec flag set.
>  The queue is not inherited by a child created with
>  .Xr fork 2 .
>  Similarly, kqueues cannot be passed across UNIX-domain sockets.
>
>

Reply via email to