i would like to launch a child process (written in Swift of course), and receive output from the process over a pipe. i cannot attach the pipe to stdout
or stderr
, because those are already being used for other things. so the pipe must be attached to a non-standard stream. is this possible?
Do you want the pipe specifically or could you use a TCP connection (e.g. via the loopback address)?
so the pipe must be attached to a non-standard stream. is this
possible?
On Apple platforms this is feasible to implement with posix_spawn
:
-
Set
POSIX_SPAWN_CLOEXEC_DEFAULT
. -
Use
posix_spawn_file_actions_addinherit_np
to mark the pipe as inherited.
I’m not sure how you’d do this in Linux. In C you’d call fork
then exec*
and do all the plumbing in between, but that’s challenging in Swift. I know that the folks working on Subprocess
have been wrangling similar issues on Linux, but I’m not sure where they landed.
Another option is to create a Unix domain socket on the parent side, pass it’s path to the child, and have the child connect to it. You can similar things with a FIFO (see the mkfifo
man page).
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
thanks Quinn, a FIFO worked well for me, and also enabled me to communicate interactive updates between the parent and child processes before the child process exit.
the only issue i ran into with the FIFO was a lack of swift-system support for mkfifo
. i worked around this by using posix_spawnp
to launch an instance of the mkfifo
command line utility.
a FIFO worked well for me
Yay!
i worked around this by using
posix_spawnp
to launch an
instance of themkfifo
command line utility.
That was easier that importing Darwin
/ Glibc
/ whatever?
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
i already had a library for launching subprocesses, so it was as simple as
try SystemProcess.init(command: "mkfifo", name)()
it probably incurs a small amount of overhead searching through executable search paths but it’s not like i was creating a ton of pipes.
calling it the hard way would have been faster but the conditional imports should really go in a library and i did not want to get sidetracked by a library design problem.