@@ -108,8 +108,7 @@ struct FileHandle: ~Copyable, Sendable {
108
108
///
109
109
/// By default, the resulting file handle is not inherited by any child
110
110
/// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and
111
- /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call
112
- /// ``setInherited()``.
111
+ /// `HANDLE_FLAG_INHERIT` is cleared on Windows.).
113
112
init ( forReadingAtPath path: String ) throws {
114
113
try self . init ( atPath: path, mode: " reb " )
115
114
}
@@ -123,8 +122,7 @@ struct FileHandle: ~Copyable, Sendable {
123
122
///
124
123
/// By default, the resulting file handle is not inherited by any child
125
124
/// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and
126
- /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make it inheritable, call
127
- /// ``setInherited()``.
125
+ /// `HANDLE_FLAG_INHERIT` is cleared on Windows.).
128
126
init ( forWritingAtPath path: String ) throws {
129
127
try self . init ( atPath: path, mode: " web " )
130
128
}
@@ -492,8 +490,7 @@ extension FileHandle {
492
490
///
493
491
/// By default, the resulting file handles are not inherited by any child
494
492
/// processes (that is, `FD_CLOEXEC` is set on POSIX-like systems and
495
- /// `HANDLE_FLAG_INHERIT` is cleared on Windows.) To make them inheritable,
496
- /// call ``setInherited()``.
493
+ /// `HANDLE_FLAG_INHERIT` is cleared on Windows.).
497
494
static func makePipe( readEnd: inout FileHandle ? , writeEnd: inout FileHandle ? ) throws {
498
495
#if !os(Windows)
499
496
var pipe2Called = false
@@ -533,8 +530,8 @@ extension FileHandle {
533
530
if !pipe2Called {
534
531
// pipe2() is not available. Use pipe() instead and simulate O_CLOEXEC
535
532
// to the best of our ability.
536
- try _setFileDescriptorInherited ( fdReadEnd , false )
537
- try _setFileDescriptorInherited ( fdWriteEnd , false )
533
+ try setFD_CLOEXEC ( true , onFileDescriptor : fdReadEnd )
534
+ try setFD_CLOEXEC ( true , onFileDescriptor : fdWriteEnd )
538
535
}
539
536
#endif
540
537
@@ -612,72 +609,6 @@ extension FileHandle {
612
609
#endif
613
610
}
614
611
#endif
615
-
616
- #if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android)
617
- /// Set whether or not the given file descriptor is inherited by child processes.
618
- ///
619
- /// - Parameters:
620
- /// - fd: The file descriptor.
621
- /// - inherited: Whether or not `fd` is inherited by child processes
622
- /// (ignoring overriding functionality such as Apple's
623
- /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.)
624
- ///
625
- /// - Throws: Any error that occurred while setting the flag.
626
- private static func _setFileDescriptorInherited( _ fd: CInt , _ inherited: Bool ) throws {
627
- switch swt_getfdflags ( fd) {
628
- case - 1 :
629
- // An error occurred reading the flags for this file descriptor.
630
- throw CError ( rawValue: swt_errno ( ) )
631
- case let oldValue:
632
- let newValue = if inherited {
633
- oldValue & ~ FD_CLOEXEC
634
- } else {
635
- oldValue | FD_CLOEXEC
636
- }
637
- if oldValue == newValue {
638
- // No need to make a second syscall as nothing has changed.
639
- return
640
- }
641
- if - 1 == swt_setfdflags ( fd, newValue) {
642
- // An error occurred setting the flags for this file descriptor.
643
- throw CError ( rawValue: swt_errno ( ) )
644
- }
645
- }
646
- }
647
- #endif
648
-
649
- /// Set whether or not this file handle is inherited by child processes.
650
- ///
651
- /// - Parameters:
652
- /// - inherited: Whether or not this file handle is inherited by child
653
- /// processes (ignoring overriding functionality such as Apple's
654
- /// `POSIX_SPAWN_CLOEXEC_DEFAULT` flag.)
655
- ///
656
- /// - Throws: Any error that occurred while setting the flag.
657
- func setInherited( _ inherited: Bool ) throws {
658
- #if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android)
659
- try withUnsafePOSIXFileDescriptor { fd in
660
- guard let fd else {
661
- throw SystemError ( description: " Cannot set whether a file handle is inherited unless it is backed by a file descriptor. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new " )
662
- }
663
- try withLock {
664
- try Self . _setFileDescriptorInherited ( fd, inherited)
665
- }
666
- }
667
- #elseif os(Windows)
668
- return try withUnsafeWindowsHANDLE { handle in
669
- guard let handle else {
670
- throw SystemError ( description: " Cannot set whether a file handle is inherited unless it is backed by a Windows file handle. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new " )
671
- }
672
- let newValue = inherited ? DWORD ( HANDLE_FLAG_INHERIT) : 0
673
- guard SetHandleInformation ( handle, DWORD ( HANDLE_FLAG_INHERIT) , newValue) else {
674
- throw Win32Error ( rawValue: GetLastError ( ) )
675
- }
676
- }
677
- #else
678
- #warning("Platform-specific implementation missing: cannot set whether a file handle is inherited")
679
- #endif
680
- }
681
612
}
682
613
683
614
// MARK: - General path utilities
@@ -757,4 +688,35 @@ func canonicalizePath(_ path: String) -> String? {
757
688
return nil
758
689
#endif
759
690
}
691
+
692
+ #if SWT_TARGET_OS_APPLE || os(Linux) || os(FreeBSD) || os(OpenBSD) || os(Android)
693
+ /// Set the given file descriptor's `FD_CLOEXEC` flag.
694
+ ///
695
+ /// - Parameters:
696
+ /// - flag: The new value of `fd`'s `FD_CLOEXEC` flag.
697
+ /// - fd: The file descriptor.
698
+ ///
699
+ /// - Throws: Any error that occurred while setting the flag.
700
+ func setFD_CLOEXEC( _ flag: Bool , onFileDescriptor fd: CInt ) throws {
701
+ switch swt_getfdflags ( fd) {
702
+ case - 1 :
703
+ // An error occurred reading the flags for this file descriptor.
704
+ throw CError ( rawValue: swt_errno ( ) )
705
+ case let oldValue:
706
+ let newValue = if flag {
707
+ oldValue & ~ FD_CLOEXEC
708
+ } else {
709
+ oldValue | FD_CLOEXEC
710
+ }
711
+ if oldValue == newValue {
712
+ // No need to make a second syscall as nothing has changed.
713
+ return
714
+ }
715
+ if - 1 == swt_setfdflags ( fd, newValue) {
716
+ // An error occurred setting the flags for this file descriptor.
717
+ throw CError ( rawValue: swt_errno ( ) )
718
+ }
719
+ }
720
+ }
721
+ #endif
760
722
#endif
0 commit comments