GSoC 2020 - Notes on sh(1)

Misc notes on the 3 relevant files for adding posix_spawn usage to sh, from and summary from today’s IRC meeting with my mentors. This week and last week I’ve read through sh’s code, with no clue how to start replacing the logic.

We have 3 files (jobs, exec, eval) which seem to contain the main logic i need to investigate. Between fork and exec we sometimes fork before we exec and have too much disconnection between those two, or sometimes we exec in a vforked shell, and I need to understand more about what is going on or just start testing.

  • jobs.c:

    • fork() for forkshell
      • in job control shells, only in root shell
  • exec.c:

    • is a user of:
      • shellexec()
      • tryexec()
        • both have an argument of type int named ‘vforked’
  • eval.c:

    • shellexec() uses tryexec()
    • tryexec():
      • does execve(cmd, argv, envp), if errno (of execve?) is ENOEXEC and vfork is set, exraise().

According to Riastradh the shell is going to seem a bit more complicated because it often forks subshells without directly reducing to exec. The low-hanging fruit is where it vforks, because you can’t do much besides exec after vfork – so that’s the path that is already an opportunity for posix_spawn, because pretty much the only things it will do are set up signals and file descriptors and exec. In evalcommand, the relevant path is limited to the case where cmdentry.cmdtype == CMDNORMAL and (!cmd->ncmd.backgnd or cmd->ncmd.redirect == NULL), in which case it does listmklocal, forkchild, redirect, and shellexec. It’s really down to what’s between VFORK_BLOCK, and the case CMDNORMAL of switch (cmdentry.cmdtype) down below (which is the ‘default’ of the switch). This is mostly just redirect and shellexec. The easiest approach would probably be to rip out everything in VFORK_BLOCK/END and replace it by posix_spawn, don’t bother falling through to the switch below; just incorporate the redirect and shellexec into posix_spawn there.