Skip to content

fork or posix_spawn return EAGAIN, should return ENOSYS #14124

Closed
@ijackson

Description

@ijackson

Hi. I've come here to try to upstream a bug report about emscripten's behaviour which we experienced in the Rust CI. I hope this is appreciated.

tl;dr: I think, based on the behaviour of an emscripten test which runs in the Rust CI, and cursory inspection of library.js, that either fork or posix_spawn sets errno to EAGAIN/EWOULDBLOCK. IMO this is not correct. The correct response is ENOSYS.

I had a look through the emscripten issues and MRs, and found #3819 where posix_spawn was stubbed out, and based on that I think the fix is to edit library.js. I can prepare a drive-by MR for that if you like.

More detailed information

As I say I am prompted by a failing test case in the Rust CI. The Rust code looks like this:

    let got = catch_unwind(|| {
        let mut c = Command::new("echo");
        c.arg("hi");
        unsafe {
            c.pre_exec(|| panic!("{}", "crash now!"));
        }
        let st = c.status().expect("failed to get command status");
        dbg!(st);
        st
    });
    dbg!(&got);
    let status = got.expect("panic unexpectedly propagated");
    dbg!(status);
    let signal = status.signal().expect("expected child process to die of signal");
    assert!(signal == libc::SIGABRT || signal == libc::SIGILL);

This failed:
rust-lang/rust#85032 (comment)

The error message includes this:

  thread 'main' panicked at 'failed to get command status: Os { code: 6, kind: WouldBlock, message: "Resource temporarily unavailable" }', library/std/src/sys/unix/process/process_unix/tests.rs:47:29

Evidently Command:status() gave an error with ErrorKind::WouldBlock. That is wrong. It should be Unsupported. Rust has its own error number mapping. Here WouldBlock came from EAGAIN or EWOULDBLOCK.

The code in the implementation of Command is not entirely trivial. I was working on it as part of rust-lang/rust#81858 so I'm reasonably familiar with it. I won't walk you through it, but basically, it first tries posix_spawn and then falls back to fork.

Thanks for your attention. Let me know if you want me to make an MR to change this in emscripten.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions