points by ridiculous_fish 3 years ago

fish shell uses posix_spawn sometimes because of its performance benefits. We can't use it in the following cases:

1. No analog to tcsetpgrp, so it's no good if job control is enabled

2. No analog to fchdir, meaning you have to synchronize with fchdir elsewhere in the progarm

3. Error codes do not convey enough information for good error messages (e.g. if a file doesn't exist, posix_spawn doesn't tell you which file)

4. Inconsistent behavior around dup2 fd redirections and CLO_EXEC.

5. Inconsistent behavior for shebangless scripts

These are basically deal-breakers so fish also supports a fork/exec path. However the performance benefits of posix_spawn are too real to ignore so fish uses posix_spawn when it can, and fork/exec when it must.

lgg 3 years ago

Not sure if it worth the platform specific code, but for #2 macOS 10.15+ has `posix_spawn_file_actions_addfchdir_np()`.

I think most of these are deficiencies in the available posix_spawn actions, not anything inherent. Of course getting all the relevant OSes to add new functionality is a huge pain. The error handling seems bad though.

chubot 3 years ago

OK very interesting ... is the performance benefit on certain platforms, or everywhere? A previous thread says Ninja is faster on OS X and Solaris because of it.

Though that does seem like a large number of corner cases, probably learned through painful experience :-/

cryptonector 3 years ago

Shells should really use `vfork()` to exec, and `fork()` for subshells (maybe).

  • mort96 3 years ago

    Except that the set of things you are allowed to do after vfork() and before exec() is extremely small. I agree that things should use vfork or posix_spawn when possible, but it wouldn't surprise me at all if there's a similar list of cases when a vfork() path wouldn't be possible.

    • cryptonector 3 years ago

      That set was made artificially small by the Open Group, but is not actually that small.

jepler 3 years ago

ah a good list as a companion to my simple posix_spawn pipe example in another sub-thread here! thank you!