Skip to content

Commit b125643

Browse files
committed
fix: isolate stdout/stderr calls for Linux concurrency safety
Move fflush/dup/dup2 calls into FlushOutput.swift which imports the C library directly without Foundation, allowing @preconcurrency to suppress strict concurrency errors on Linux.
1 parent bdc60b1 commit b125643

3 files changed

Lines changed: 30 additions & 31 deletions

File tree

Sources/mtpx/Commands/Transfer.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ import ArgumentParser
22
import Foundation
33
import SwiftMTPAsync
44

5-
#if canImport(Glibc)
6-
@preconcurrency import Glibc
7-
#elseif canImport(Musl)
8-
@preconcurrency import Musl
9-
#endif
10-
115
struct Transfer: AsyncParsableCommand {
126
static let configuration = CommandConfiguration(
137
commandName: "transfer",
@@ -244,7 +238,7 @@ struct Transfer: AsyncParsableCommand {
244238
if pct != lastPct {
245239
lastPct = pct
246240
print("\r\(name): \(pct)%", terminator: " ")
247-
fflush(stdout)
241+
flushStdout()
248242
}
249243
return .continue
250244
}

Sources/mtpx/Completions.swift

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ import ArgumentParser
22
import Foundation
33
import SwiftMTPAsync
44

5-
#if canImport(Glibc)
6-
@preconcurrency import Glibc
7-
#elseif canImport(Musl)
8-
@preconcurrency import Musl
9-
#endif
10-
115
enum Completions {
126
static func remotePath(
137
_ words: [String],
@@ -151,24 +145,6 @@ enum Completions {
151145
}
152146
}
153147

154-
private static func muteStderr() -> Int32 {
155-
fflush(stderr)
156-
let saved = dup(STDERR_FILENO)
157-
let devNull = open("/dev/null", O_WRONLY)
158-
if devNull >= 0 {
159-
dup2(devNull, STDERR_FILENO)
160-
close(devNull)
161-
}
162-
return saved
163-
}
164-
165-
private static func restoreStderr(_ saved: Int32) {
166-
guard saved >= 0 else { return }
167-
fflush(stderr)
168-
dup2(saved, STDERR_FILENO)
169-
close(saved)
170-
}
171-
172148
private static func pathCompletions(for input: String) async -> [String] {
173149
guard let remote = RemotePath(parsing: input) else { return [] }
174150

Sources/mtpx/FlushOutput.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#if canImport(Darwin)
2+
import Darwin
3+
#elseif canImport(Glibc)
4+
@preconcurrency import Glibc
5+
#elseif canImport(Musl)
6+
@preconcurrency import Musl
7+
#endif
8+
9+
func flushStdout() {
10+
fflush(stdout)
11+
}
12+
13+
func muteStderr() -> Int32 {
14+
fflush(stderr)
15+
let saved = dup(STDERR_FILENO)
16+
let devNull = open("/dev/null", O_WRONLY)
17+
if devNull >= 0 {
18+
dup2(devNull, STDERR_FILENO)
19+
close(devNull)
20+
}
21+
return saved
22+
}
23+
24+
func restoreStderr(_ saved: Int32) {
25+
guard saved >= 0 else { return }
26+
fflush(stderr)
27+
dup2(saved, STDERR_FILENO)
28+
close(saved)
29+
}

0 commit comments

Comments
 (0)