Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-1746] Improve fork/exec behavior for StdlibUnittest on Android #44355

Open
modocache mannequin opened this issue Jun 14, 2016 · 0 comments
Open

[SR-1746] Improve fork/exec behavior for StdlibUnittest on Android #44355

modocache mannequin opened this issue Jun 14, 2016 · 0 comments
Labels
Android Platform: Android improvement standard library Area: Standard library umbrella

Comments

@modocache
Copy link
Mannequin

modocache mannequin commented Jun 14, 2016

Previous ID SR-1746
Radar None
Original Reporter @modocache
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Improvement, Android
Assignee None
Priority Medium

md5: 39e5ab0006e8a8b50df0dcd12c77e44c

Issue Description:

As pointed out by @weissi in this GitHub comment, the Android logic in stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift has different semantics to posix_spawn. posix_spawn will give you a proper errno value if the spawn failed, whereas the Android logic just exits the child process. I.e. spawning ["/bin/zsh", "-c", "exit 126;"] will be indistinguishable for the caller.

@weissi proposes opening a separate pipe, called child2parent or so which will be fcntl'd to FD_CLOEXEC. That means if execve succeeds, it will be closed automatically and that means the parent will read EOF. If execve fails, we just write execve's errno to that pipe so the parent can read it and learns what went wrong in the child. So the parent waits until it can read, if it reads EOF (read returns 0) it knows, the child spawned successfully, if it reads anything else, it knows that this is execve's errno value and can return that to the caller.

@weissi even provides some pseudo-C code to demonstrate:

    [...]
    } else if (pid == 0) {
        int err = fcntl(child2parent[1], F_SETFD, FD_CLOEXEC); /* This fd will be closed on exec */
        int errno_save = errno;
        if (err) {
           preconditionFailure("fcntl failed, errno: %d", errno_save);
           abort();
        }
        execve(...);
        errno_save = errno;
        /* execve returned, this is an error that we need to communicate back to the parent */
        ssize_t suc_write = write(child2parent[1], &errno_save, sizeof(typeof(errno)));
        errno_save = errno;
        if (suc_write > 0 && suc_write < sizeof(typeof(errno)));
            /* implement write retry ;) */
        } else if (suc_write == 0) {
            /* preconditionFailure("EOF?!"); */
            abort();
        } else if (suc_write < 0) {
            preconditionFailure("write failed, errno %d", errno_save);
            abort();
        }
        close(child2parent[1]);
    }
    [...]
@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Platform: Android improvement standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

0 participants