NetBSD Problem Report #60765
From www@netbsd.org Tue Sep 22 13:00:34 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id C0A541A923C
for <gnats-bugs@gnats.NetBSD.org>; Tue, 22 Sep 2026 13:00:34 +0000 (UTC)
Message-Id: <20260922130033.5181C1A923E@mollari.NetBSD.org>
Date: Tue, 22 Sep 2026 13:00:33 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: closefrom(2) does not actually return EINTR
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>
>Number: 60765
>Category: kern
>Synopsis: closefrom(2) does not actually return EINTR
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Sep 22 13:05:00 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10, ...
>Organization:
The CloseFD Interruption, Inc.
>Environment:
>Description:
The man page says:
> ERRORS
> closefrom() will fail if:
> ...
> [EINTR] An interrupt was received.
But closefrom(fd), which is just a wrapper fcntl(fd, F_CLOSEM),
cannot actually return EINTR -- it can only return EBADF (if fd
< 0) or 0:
349 case F_CLOSEM:
350 if (fd < 0)
351 return SET_ERROR(EBADF);
352 while ((i = fdp->fd_lastfile) >= fd) {
353 if (fd_getfile(i) == NULL) {
354 /* Another thread has updated. */
355 continue;
356 }
357 fd_close(i);
358 }
359 return 0;
https://nxr.netbsd.org/xref/src/sys/kern/sys_descrip.c?r=1.54#349
Suppose a file is open on an interruptible nfs mount, or a
socket is open with SO_LINGER enabled so it will wait in close
until all buffered output has been transmitted. Suppose
there's _multiple_ such cases. Suppose the network is flakes
out so one of these sleeps. And suppose the user hits ^C
during the first sleep.
Here are two possible outcomes from the user's perspective:
1. closefrom fails with EINTR, having closed only some but not
all of the descriptors.
2. closefrom wakes on signal during the first fd, and then goes
to sleep again on the second fd, not letting the application
respond to interruption.
Neither option is correct in general (that's why we have
SA_RESTART), but the system currently allows only (2).
>How-To-Repeat:
code inspectman
>Fix:
Consider one of:
(a) Loop on ERESTART but break on EINTR from fd_close.
(b) Omit EINTR from possible outcomes in man page.
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.