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:
Volodymyr Bortniak
2025-12-19 15:36:02 -08:00
committed by GitHub
co-authored by Bortniak Volodymyr
parent 3c3a83c98a
commit 9c239aa36c
3 changed files with 111 additions and 10 deletions
+10 -8
View File
@@ -110,17 +110,19 @@ public struct Parser {
// This is a somewhat faithful Go->Swift port of Moby's envfile
// parsing in the cli:
// https://github.com/docker/cli/blob/f5a7a3c72eb35fc5ba9c4d65a2a0e2e1bd216bf2/pkg/kvfile/kvfile.go#L81
guard FileManager.default.fileExists(atPath: path) else {
throw ContainerizationError(
.notFound,
message: "envfile at \(path) not found"
)
}
guard let data = FileManager.default.contents(atPath: path) else {
let data: Data
do {
// Use FileHandle to support named pipes (FIFOs) and process substitutions
// like --env-file <(echo "KEY=value")
let fileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
defer { try? fileHandle.close() }
data = try fileHandle.readToEnd() ?? Data()
} catch {
throw ContainerizationError(
.invalidArgument,
message: "failed to read envfile at \(path)"
message: "failed to read envfile at \(path)",
cause: error
)
}