Skip to content

Commit 33bd877

Browse files
Add initial support for POSIX O_CLOFORK
1 parent 4dbe268 commit 33bd877

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

sys/kern/kern_descrip.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,11 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
510510
error = kern_dup(td, FDDUP_FCNTL, FDDUP_FLAG_CLOEXEC, fd, tmp);
511511
break;
512512

513+
case F_DUPFD_CLOFORK:
514+
tmp = arg;
515+
error = kern_dup(td, FDDUP_FCNTL, FDDUP_FLAG_CLOFORK, fd, tmp);
516+
break;
517+
513518
case F_DUP2FD:
514519
tmp = arg;
515520
error = kern_dup(td, FDDUP_FIXED, 0, fd, tmp);
@@ -520,13 +525,19 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
520525
error = kern_dup(td, FDDUP_FIXED, FDDUP_FLAG_CLOEXEC, fd, tmp);
521526
break;
522527

528+
case F_DUP2FD_CLOFORK:
529+
tmp = arg;
530+
error = kern_dup(td, FDDUP_FIXED, FDDUP_FLAG_CLOFORK, fd, tmp);
531+
break;
532+
523533
case F_GETFD:
524534
error = EBADF;
525535
FILEDESC_SLOCK(fdp);
526536
fde = fdeget_noref(fdp, fd);
527537
if (fde != NULL) {
528538
td->td_retval[0] =
529-
(fde->fde_flags & UF_EXCLOSE) ? FD_CLOEXEC : 0;
539+
((fde->fde_flags & UF_EXCLOSE) != 0 ? FD_CLOEXEC : 0) |
540+
((fde->fde_flags & UF_FOCLOSE) != 0 ? FD_CLOFORK : 0);
530541
error = 0;
531542
}
532543
FILEDESC_SUNLOCK(fdp);
@@ -537,8 +548,10 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
537548
FILEDESC_XLOCK(fdp);
538549
fde = fdeget_noref(fdp, fd);
539550
if (fde != NULL) {
540-
fde->fde_flags = (fde->fde_flags & ~UF_EXCLOSE) |
541-
(arg & FD_CLOEXEC ? UF_EXCLOSE : 0);
551+
fde->fde_flags =
552+
(fde->fde_flags & ~(UF_EXCLOSE | UF_FOCLOSE)) |
553+
((arg & FD_CLOEXEC) != 0 ? UF_EXCLOSE : 0) |
554+
((arg & FD_CLOFORK) != 0 ? UF_FOCLOSE : 0);
542555
error = 0;
543556
}
544557
FILEDESC_XUNLOCK(fdp);
@@ -938,7 +951,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
938951
fdp = p->p_fd;
939952
oioctls = NULL;
940953

941-
MPASS((flags & ~(FDDUP_FLAG_CLOEXEC)) == 0);
954+
MPASS((flags & ~(FDDUP_FLAG_CLOEXEC | FDDUP_FLAG_CLOFORK)) == 0);
942955
MPASS(mode < FDDUP_LASTMODE);
943956

944957
AUDIT_ARG_FD(old);
@@ -963,8 +976,10 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
963976
goto unlock;
964977
if (mode == FDDUP_FIXED && old == new) {
965978
td->td_retval[0] = new;
966-
if (flags & FDDUP_FLAG_CLOEXEC)
979+
if ((flags & FDDUP_FLAG_CLOEXEC) != 0)
967980
fdp->fd_ofiles[new].fde_flags |= UF_EXCLOSE;
981+
if ((flags & FDDUP_FLAG_CLOFORK) != 0)
982+
fdp->fd_ofiles[new].fde_flags |= UF_FOCLOSE;
968983
error = 0;
969984
goto unlock;
970985
}
@@ -1039,10 +1054,9 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
10391054
fde_copy(oldfde, newfde);
10401055
filecaps_copy_finish(&oldfde->fde_caps, &newfde->fde_caps,
10411056
nioctls);
1042-
if ((flags & FDDUP_FLAG_CLOEXEC) != 0)
1043-
newfde->fde_flags = oldfde->fde_flags | UF_EXCLOSE;
1044-
else
1045-
newfde->fde_flags = oldfde->fde_flags & ~UF_EXCLOSE;
1057+
newfde->fde_flags = (oldfde->fde_flags & ~(UF_EXCLOSE | UF_FOCLOSE)) |
1058+
((flags & FDDUP_FLAG_CLOEXEC) != 0 ? UF_EXCLOSE : 0) |
1059+
((flags & FDDUP_FLAG_CLOFORK) != 0 ? UF_FOCLOSE : 0);
10461060
#ifdef CAPABILITIES
10471061
seqc_write_end(&newfde->fde_seqc);
10481062
#endif
@@ -2163,7 +2177,8 @@ _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
21632177
seqc_write_begin(&fde->fde_seqc);
21642178
#endif
21652179
fde->fde_file = fp;
2166-
fde->fde_flags = (flags & O_CLOEXEC) != 0 ? UF_EXCLOSE : 0;
2180+
fde->fde_flags = ((flags & O_CLOEXEC) != 0 ? UF_EXCLOSE : 0) |
2181+
((flags & O_CLOFORK) != 0 ? UF_FOCLOSE : 0);
21672182
if (fcaps != NULL)
21682183
filecaps_move(fcaps, &fde->fde_caps);
21692184
else
@@ -2423,6 +2438,7 @@ fdcopy(struct filedesc *fdp)
24232438
newfdp->fd_freefile = fdp->fd_freefile;
24242439
FILEDESC_FOREACH_FDE(fdp, i, ofde) {
24252440
if ((ofde->fde_file->f_ops->fo_flags & DFLAG_PASSABLE) == 0 ||
2441+
((ofde->fde_flags & UF_FOCLOSE) != 0) ||
24262442
!fhold(ofde->fde_file)) {
24272443
if (newfdp->fd_freefile == fdp->fd_freefile)
24282444
newfdp->fd_freefile = i;

sys/kern/sys_pipe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ sys_pipe2(struct thread *td, struct pipe2_args *uap)
548548
{
549549
int error, fildes[2];
550550

551-
if (uap->flags & ~(O_CLOEXEC | O_NONBLOCK))
551+
if ((uap->flags & ~(O_CLOEXEC | O_CLOFORK | O_NONBLOCK)) != 0)
552552
return (EINVAL);
553553
error = kern_pipe(td, fildes, uap->flags, NULL, NULL);
554554
if (error)

sys/sys/fcntl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ typedef __pid_t pid_t;
143143
#define O_NAMEDATTR 0x04000000 /* NFSv4 named attributes */
144144
#endif
145145

146+
#if __POSIX_VISIBLE >= 202405
147+
#define O_CLOFORK 0x08000000
148+
#endif
149+
146150
/*
147151
* XXX missing O_RSYNC.
148152
*/
@@ -269,6 +273,13 @@ typedef __pid_t pid_t;
269273
#define F_GET_SEALS 20
270274
#define F_ISUNIONSTACK 21 /* Kludge for libc, don't use it. */
271275
#define F_KINFO 22 /* Return kinfo_file for this fd */
276+
#endif /* __BSD_VISIBLE */
277+
278+
#if __POSIX_VISIBLE >= 202405
279+
#define F_DUPFD_CLOFORK 23 /* Like F_DUPFD, but FD_CLOFORK is set */
280+
#endif
281+
#if __BSD_VISIBLE
282+
#define F_DUP2FD_CLOFORK 24 /* Like F_DUP2FD, but FD_CLOFORK is set */
272283

273284
/* Seals (F_ADD_SEALS, F_GET_SEALS). */
274285
#define F_SEAL_SEAL 0x0001 /* Prevent adding sealings */
@@ -279,6 +290,9 @@ typedef __pid_t pid_t;
279290

280291
/* file descriptor flags (F_GETFD, F_SETFD) */
281292
#define FD_CLOEXEC 1 /* close-on-exec flag */
293+
#if __POSIX_VISIBLE >= 202405
294+
#define FD_CLOFORK 2 /* close-on-fork flag */
295+
#endif
282296

283297
/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
284298
#define F_RDLCK 1 /* shared or read lock */

sys/sys/filedesc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ struct filedesc_to_leader {
148148
* Per-process open flags.
149149
*/
150150
#define UF_EXCLOSE 0x01 /* auto-close on exec */
151+
#define UF_FOCLOSE 0x02 /* auto-close on fork */
151152

152153
#ifdef _KERNEL
153154

@@ -220,6 +221,7 @@ enum {
220221

221222
/* Flags for kern_dup(). */
222223
#define FDDUP_FLAG_CLOEXEC 0x1 /* Atomically set UF_EXCLOSE. */
224+
#define FDDUP_FLAG_CLOFORK 0x2 /* Atomically set UF_FOCLOSE. */
223225

224226
/* For backward compatibility. */
225227
#define falloc(td, resultfp, resultfd, flags) \

0 commit comments

Comments
 (0)