You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
[...]
} elseif (pid == 0) {
interr = fcntl(child2parent[1], F_SETFD, FD_CLOEXEC); /* This fd will be closed on exec */interrno_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_tsuc_write = write(child2parent[1], &errno_save, sizeof(typeof(errno)));
errno_save = errno;
if (suc_write > 0 && suc_write < sizeof(typeof(errno)));
/* implement write retry ;) */
} elseif (suc_write == 0) {
/* preconditionFailure("EOF?!"); */abort();
} elseif (suc_write < 0) {
preconditionFailure("write failed, errno %d", errno_save);
abort();
}
close(child2parent[1]);
}
[...]
The text was updated successfully, but these errors were encountered:
Additional Detail from JIRA
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 toposix_spawn
.posix_spawn
will give you a propererrno
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 befcntl
'd toFD_CLOEXEC
. That means ifexecve
succeeds, it will be closed automatically and that means the parent will read EOF. Ifexecve
fails, we just writeexecve
'serrno
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 isexecve
'serrno
value and can return that to the caller.@weissi even provides some pseudo-C code to demonstrate:
The text was updated successfully, but these errors were encountered: