@@ -510,6 +510,11 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
510
510
error = kern_dup (td , FDDUP_FCNTL , FDDUP_FLAG_CLOEXEC , fd , tmp );
511
511
break ;
512
512
513
+ case F_DUPFD_CLOFORK :
514
+ tmp = arg ;
515
+ error = kern_dup (td , FDDUP_FCNTL , FDDUP_FLAG_CLOFORK , fd , tmp );
516
+ break ;
517
+
513
518
case F_DUP2FD :
514
519
tmp = arg ;
515
520
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)
520
525
error = kern_dup (td , FDDUP_FIXED , FDDUP_FLAG_CLOEXEC , fd , tmp );
521
526
break ;
522
527
528
+ case F_DUP2FD_CLOFORK :
529
+ tmp = arg ;
530
+ error = kern_dup (td , FDDUP_FIXED , FDDUP_FLAG_CLOFORK , fd , tmp );
531
+ break ;
532
+
523
533
case F_GETFD :
524
534
error = EBADF ;
525
535
FILEDESC_SLOCK (fdp );
526
536
fde = fdeget_noref (fdp , fd );
527
537
if (fde != NULL ) {
528
538
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 );
530
541
error = 0 ;
531
542
}
532
543
FILEDESC_SUNLOCK (fdp );
@@ -537,8 +548,10 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
537
548
FILEDESC_XLOCK (fdp );
538
549
fde = fdeget_noref (fdp , fd );
539
550
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 );
542
555
error = 0 ;
543
556
}
544
557
FILEDESC_XUNLOCK (fdp );
@@ -938,7 +951,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
938
951
fdp = p -> p_fd ;
939
952
oioctls = NULL ;
940
953
941
- MPASS ((flags & ~(FDDUP_FLAG_CLOEXEC )) == 0 );
954
+ MPASS ((flags & ~(FDDUP_FLAG_CLOEXEC | FDDUP_FLAG_CLOFORK )) == 0 );
942
955
MPASS (mode < FDDUP_LASTMODE );
943
956
944
957
AUDIT_ARG_FD (old );
@@ -963,8 +976,10 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
963
976
goto unlock ;
964
977
if (mode == FDDUP_FIXED && old == new ) {
965
978
td -> td_retval [0 ] = new ;
966
- if (flags & FDDUP_FLAG_CLOEXEC )
979
+ if (( flags & FDDUP_FLAG_CLOEXEC ) != 0 )
967
980
fdp -> fd_ofiles [new ].fde_flags |= UF_EXCLOSE ;
981
+ if ((flags & FDDUP_FLAG_CLOFORK ) != 0 )
982
+ fdp -> fd_ofiles [new ].fde_flags |= UF_FOCLOSE ;
968
983
error = 0 ;
969
984
goto unlock ;
970
985
}
@@ -1039,10 +1054,9 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
1039
1054
fde_copy (oldfde , newfde );
1040
1055
filecaps_copy_finish (& oldfde -> fde_caps , & newfde -> fde_caps ,
1041
1056
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 );
1046
1060
#ifdef CAPABILITIES
1047
1061
seqc_write_end (& newfde -> fde_seqc );
1048
1062
#endif
@@ -2163,7 +2177,8 @@ _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
2163
2177
seqc_write_begin (& fde -> fde_seqc );
2164
2178
#endif
2165
2179
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 );
2167
2182
if (fcaps != NULL )
2168
2183
filecaps_move (fcaps , & fde -> fde_caps );
2169
2184
else
@@ -2423,6 +2438,7 @@ fdcopy(struct filedesc *fdp)
2423
2438
newfdp -> fd_freefile = fdp -> fd_freefile ;
2424
2439
FILEDESC_FOREACH_FDE (fdp , i , ofde ) {
2425
2440
if ((ofde -> fde_file -> f_ops -> fo_flags & DFLAG_PASSABLE ) == 0 ||
2441
+ ((ofde -> fde_flags & UF_FOCLOSE ) != 0 ) ||
2426
2442
!fhold (ofde -> fde_file )) {
2427
2443
if (newfdp -> fd_freefile == fdp -> fd_freefile )
2428
2444
newfdp -> fd_freefile = i ;
0 commit comments