Index: sys/kern/kern_descrip.c =================================================================== --- sys/kern/kern_descrip.c +++ sys/kern/kern_descrip.c @@ -1338,8 +1338,20 @@ return (closefp(fdp, fd, fp, td, 1)); } +static void +kern_cloexec(struct filedesc *fdp, int fd) +{ + struct filedescent *fde; + + FILEDESC_XLOCK(fdp); + fde = fdeget_locked(fdp, fd); + if (fde != NULL) + fde->fde_flags |= UF_EXCLOSE; + FILEDESC_XUNLOCK(fdp); +} + int -kern_close_range(struct thread *td, u_int lowfd, u_int highfd) +kern_close_range(struct thread *td, u_int lowfd, u_int highfd, u_int flags) { struct filedesc *fdp; int fd, ret, lastfile; @@ -1372,7 +1384,10 @@ for (fd = lowfd; fd <= highfd; fd++) { if (fdp->fd_ofiles[fd].fde_file != NULL) { FILEDESC_SUNLOCK(fdp); - (void)kern_close(td, fd); + if (flags & CLOSE_RANGE_CLOEXEC) + kern_cloexec(fdp, fd); + else + (void)kern_close(td, fd); FILEDESC_SLOCK(fdp); } } @@ -1392,10 +1407,9 @@ sys_close_range(struct thread *td, struct close_range_args *uap) { - /* No flags currently defined */ - if (uap->flags != 0) + if (uap->flags & ~CLOSE_RANGE_CLOEXEC) return (EINVAL); - return (kern_close_range(td, uap->lowfd, uap->highfd)); + return (kern_close_range(td, uap->lowfd, uap->highfd, uap->flags)); } #ifdef COMPAT_FREEBSD12 @@ -1420,7 +1434,7 @@ * closefrom(0) which closes all files. */ lowfd = MAX(0, uap->lowfd); - return (kern_close_range(td, lowfd, ~0U)); + return (kern_close_range(td, lowfd, ~0U, 0)); } #endif /* COMPAT_FREEBSD12 */ Index: sys/sys/syscallsubr.h =================================================================== --- sys/sys/syscallsubr.h +++ sys/sys/syscallsubr.h @@ -108,7 +108,7 @@ struct timespec *ats); void kern_thread_cputime(struct thread *targettd, struct timespec *ats); void kern_process_cputime(struct proc *targetp, struct timespec *ats); -int kern_close_range(struct thread *td, u_int lowfd, u_int highfd); +int kern_close_range(struct thread *td, u_int lowfd, u_int highfd, u_int flags); int kern_close(struct thread *td, int fd); int kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); Index: sys/sys/unistd.h =================================================================== --- sys/sys/unistd.h +++ sys/sys/unistd.h @@ -158,6 +158,11 @@ #define _PC_ACL_NFS4 64 #endif +#if __BSD_VISIBLE +/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */ +#define CLOSE_RANGE_CLOEXEC (1U << 2) +#endif + /* From OpenSolaris, used by SEEK_DATA/SEEK_HOLE. */ #define _PC_MIN_HOLE_SIZE 21