git: e6b64eea5e77 - main - kern: Make close_range() support CLOSE_RANGE_CLOEXEC

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Sun, 06 Jul 2025 23:18:38 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=e6b64eea5e7751b92bbabcef8470ff75547f5d0f

commit e6b64eea5e7751b92bbabcef8470ff75547f5d0f
Author:     Ricardo Branco <rbranco@suse.de>
AuthorDate: 2025-05-11 20:17:43 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-07-06 23:08:33 +0000

    kern: Make close_range() support CLOSE_RANGE_CLOEXEC
    
    Reviewed by:    kib
    MFC after:      1 month
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1698
---
 sys/kern/kern_descrip.c | 14 ++++++++------
 sys/sys/unistd.h        |  1 +
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index bd6fa0c14075..e432f33d810e 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1424,13 +1424,15 @@ kern_close(struct thread *td, int fd)
 }
 
 static int
-close_range_cloexec(struct thread *td, u_int lowfd, u_int highfd)
+close_range_flags(struct thread *td, u_int lowfd, u_int highfd, int flags)
 {
 	struct filedesc *fdp;
 	struct fdescenttbl *fdt;
 	struct filedescent *fde;
-	int fd;
+	int fd, fde_flags;
 
+	fde_flags = ((flags & CLOSE_RANGE_CLOEXEC) != 0 ? UF_EXCLOSE : 0) |
+	    ((flags & CLOSE_RANGE_CLOFORK) != 0 ? UF_FOCLOSE : 0);
 	fdp = td->td_proc->p_fd;
 	FILEDESC_XLOCK(fdp);
 	fdt = atomic_load_ptr(&fdp->fd_files);
@@ -1442,7 +1444,7 @@ close_range_cloexec(struct thread *td, u_int lowfd, u_int highfd)
 	for (; fd <= highfd; fd++) {
 		fde = &fdt->fdt_ofiles[fd];
 		if (fde->fde_file != NULL)
-			fde->fde_flags |= UF_EXCLOSE;
+			fde->fde_flags |= fde_flags;
 	}
 out_locked:
 	FILEDESC_XUNLOCK(fdp);
@@ -1500,8 +1502,8 @@ kern_close_range(struct thread *td, int flags, u_int lowfd, u_int highfd)
 		return (EINVAL);
 	}
 
-	if ((flags & CLOSE_RANGE_CLOEXEC) != 0)
-		return (close_range_cloexec(td, lowfd, highfd));
+	if ((flags & (CLOSE_RANGE_CLOEXEC | CLOSE_RANGE_CLOFORK)) != 0)
+		return (close_range_flags(td, lowfd, highfd, flags));
 
 	return (close_range_impl(td, lowfd, highfd));
 }
@@ -1521,7 +1523,7 @@ sys_close_range(struct thread *td, struct close_range_args *uap)
 	AUDIT_ARG_CMD(uap->highfd);
 	AUDIT_ARG_FFLAGS(uap->flags);
 
-	if ((uap->flags & ~(CLOSE_RANGE_CLOEXEC)) != 0)
+	if ((uap->flags & ~(CLOSE_RANGE_CLOEXEC | CLOSE_RANGE_CLOFORK)) != 0)
 		return (EINVAL);
 	return (kern_close_range(td, uap->flags, uap->lowfd, uap->highfd));
 }
diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h
index c12343e5d0fd..c291c1dc2b95 100644
--- a/sys/sys/unistd.h
+++ b/sys/sys/unistd.h
@@ -211,6 +211,7 @@
  * close_range() options.
  */
 #define	CLOSE_RANGE_CLOEXEC	(1<<2)
+#define	CLOSE_RANGE_CLOFORK	(1<<3)
 
 #endif /* __BSD_VISIBLE */