Meet SwiftCommand, a new Swift package that makes creating child processes very easy!

Very cool, congrats on releasing this! I felt I should do a write up of some problems I ran into while building something similar, which may cause problems in your implementation depending on how it is used.


It looks like you are using Process to actually launch the child process. You should be aware that there is currently a bug on Linux where if you are launching processes concurrently, you may unintentionally leak file descriptors into the child process. This can cause problems (including deadlock) if a process depends on its stdin to be closed to detect completion, but the stdin file descriptor is leaked into another process (such as in a context-switch immediately before this line).

The issue is that the following code in Foundation is not atomic, and file descriptors may be opened in a context switch after findMaximumOpenFD() returns but before the process executes (meaning the corresponding AddClose won't be called and the file descriptor will remain open).

In my project, GitHub - GeorgeLyon/Shwift: Shell scripting in Swift, I work around this by providing a custom implementation of spawning a child process (found here, feel free to steal). I also have a test which can somewhat reliably detect when this causes a deadlock.


A second thing to note is that you read the output data all at once, which may be problematic for large inputs. Shwift uses swift-nio to process input as it becomes available. This functionality is tested here: Shwift/Main.swift at 46ea4106ddd9b8ce557c95090ca31d5139d3641a · GeorgeLyon/Shwift · GitHub

5 Likes