mirror of
https://github.com/apple/container.git
synced 2026-09-22 07:35:36 +00:00
Add support for reading env from named pipes (#974)
This is a fix for [issue#956](https://github.com/apple/container/issues/956) `FileManager.default.contents(atPath:)` returns `nil` for named pipes (FIFOs) and process substitutions like `/dev/fd/XX` because: 1. It expects regular files with a known size 2. Named pipes are stream-based and block until data arrives ## Solution Use `FileHandle(forReadingFrom:)` instead, which: - Properly handles blocking I/O - Works with named pipes, process substitutions, and regular files (mentioned in the [doc](https://developer.apple.com/documentation/foundation/filehandle)) Co-authored-by: Bortniak Volodymyr <Bortnyak@users.noreply.github.com>
This commit is contained in:
co-authored by
Bortniak Volodymyr
parent
3c3a83c98a
commit
9c239aa36c
@@ -493,10 +493,12 @@ struct ParserTest {
|
||||
#expect {
|
||||
_ = try Parser.envFile(path: "/nonexistent/foo_bar_baz")
|
||||
} throws: { error in
|
||||
guard let error = error as? ContainerizationError else {
|
||||
guard let error = error as? ContainerizationError,
|
||||
let cause = error.cause
|
||||
else {
|
||||
return false
|
||||
}
|
||||
return error.description.contains("not found")
|
||||
return String(describing: cause).contains("No such file or directory")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +581,41 @@ struct ParserTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func testParseEnvFileFromNamedPipe() throws {
|
||||
let pipePath = FileManager.default.temporaryDirectory
|
||||
.appendingPathComponent("envfile-pipe-\(UUID().uuidString)")
|
||||
|
||||
// Create a named pipe (FIFO)
|
||||
let result = mkfifo(pipePath.path, 0o600)
|
||||
guard result == 0 else {
|
||||
throw POSIXError(POSIXErrorCode(rawValue: errno) ?? .EPERM)
|
||||
}
|
||||
defer { try? FileManager.default.removeItem(at: pipePath) }
|
||||
|
||||
let group = DispatchGroup()
|
||||
|
||||
group.enter()
|
||||
DispatchQueue.global().async {
|
||||
do {
|
||||
let handle = try FileHandle(forWritingTo: pipePath)
|
||||
try handle.write(contentsOf: "SECRET_KEY=value123\n".data(using: .utf8)!)
|
||||
try handle.close()
|
||||
} catch {
|
||||
Issue.record(error)
|
||||
}
|
||||
group.leave()
|
||||
}
|
||||
|
||||
// Read from pipe (blocks until writer connects)
|
||||
let lines = try Parser.envFile(path: pipePath.path)
|
||||
|
||||
// Wait for write to complete
|
||||
group.wait()
|
||||
|
||||
#expect(lines == ["SECRET_KEY=value123"])
|
||||
}
|
||||
|
||||
// MARK: Network Parser Tests
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user