Spawning two interactive shells as child processes causes parent to be stopped

I have discovered some very peculiar behavior I don't understand.

I have a tool which needs to run various shells as child processes.

I have noticed that when I spawn two of these shells, the entire parent process and its children are stopped like if one would press ^Z.

fn main() {
    Command::new("sh")
        .args(["-i"])
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .unwrap();

    Command::new("sh")
        .args(["-i"])
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .unwrap();

    loop {}
}

When executed it prints

[1]+  Stopped                 cargo run

It can be resumed using fg.

This behavior is somehow caused by sh being invoked as interactive.

This is the same exact "bug" as discussed here: My command execution put to the background

However it was left unsolved

It appears I solved this by using

unsafe { cmd.pre_exec(|| { libc::setsid(); Ok(()) }); }

to run the commands in a new session.

There is a proposal to make this part of the Command api: Tracking Issue for `process_setsid` · Issue #105376 · rust-lang/rust · GitHub