SerenityOS / serenity

The Serenity Operating System 🐞
https://serenityos.org
BSD 2-Clause "Simplified" License
30.35k stars 3.17k forks source link

Background process groups confuse...something #2988

Open nico opened 4 years ago

nico commented 4 years ago

Put this in Base/home/anon/spawn.cpp, then run ninja image && ninja run, and then in Serenity run gcc spawn.cpp && ./a.out. The program doesn't wait() for its child that's running in a new process group.

Somehow, the Shell never gets control back. On Linux, this works fine.

I don't know what correct behavior is though, maybe hanging like this is fine.

#include <errno.h>
#include <spawn.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    posix_spawnattr_t attr;
    if ((errno = posix_spawnattr_init(&attr)) != 0) {
      perror("posix_spawnattr_init:");
      return 1;
    }

    if ((errno =posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK)) != 0) {
      perror("posix_spawnattr_init:");
      return 1;
    }

    const char* argv[] = { "sh", "-c", "ls", nullptr };
    pid_t child_pid;
    if ((errno = posix_spawn(&child_pid, "/bin/sh", nullptr, &attr, const_cast<char**>(argv), environ)) != 0) {
        perror("posix_spawn");
        return 1;
    }

    if ((errno = posix_spawnattr_destroy(&attr) != 0) {
        perror("posix_spawnattr_destroy");
        return 1;
    }
}

If I add this to the bottom (and includes for sys/types.h and sys/wait.h at the top), everything's fine:

    int wstatus;
    if (waitpid(child_pid, &wstatus, 0) < 0) {
        perror("waitpid");
        return 1;
    }
alimpfard commented 4 years ago

This might be the shell's fault:

<snip>
Shell(22): Command "./a.out" finished in 59 ms
Shell(40): Command "ls" finished in 10 ms
Terminal::execute_escape_sequence: Unhandled final 'R'
<snip>

Oddly enough, all this happens only the first time ./a.out is run - in any terminal.