Can you pipe process output on a non-standard stream?

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?

1 Like

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

2 Likes

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.

1 Like

a FIFO worked well for me

Yay!

i worked around this by using posix_spawnp to launch an
instance of the mkfifo 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.

1 Like