Skip to content
Advertisement

Running bash using posix instead of fork/execv

I have a CLI, one of the commands is entering into Linux bash shell. This is the code which does it using fork & execv:

JavaScript

I want to replace the fork/execv and to use posix_spawn instead:

JavaScript

But it doesn’t work. Any help?

Advertisement

Answer

Let’s look at what the code in the original fork/exec does:

  • close all file descriptors
  • open the tty, which will coincidentally get an fd of 0, i.e. it’s stdin
  • duplicate this fd twice (dup(0)), which puts them into stdout and stderr
  • exec the shell command

Your new code doesn’t follow the same pattern at all. What you want to do is repeat the process, but be more explicit:

close all the FDs:

JavaScript

open the tty into STDIN_FILENO:

JavaScript

duplicate the STDIN_FILENO into STDOUT_FILENO and STDERR_FILENO:

JavaScript

Then the posix_spawn should take place in the correct context.

For the old fork/exec process, you should have done something like:

JavaScript

It’s more explicit in intent.

The reason for the ifs is to prevent the accidental dup2 of the original fd into the new fd number. The only one that really should have that problem is the first one because fd == STDIN_FILENO because you don’t have any other file descriptors open at that point.

To combine this into a small piece of code, with echo something rather than an invocation of bash we have:

JavaScript

This needs to be compiled with -D_GNU_SOURCE, as otherwise POSIX_SPAWN_USEVFORK is not defined.

Advertisement