mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Make improvements
- You can now run `make -j8 toolchain` on Windows - You can now run `make -j` on MacOS ARM64 and BSD OSes - You can now use our Emacs dev environment on MacOS/Windows - Fix bug where the x16 register was being corrupted by --ftrace - The programs under build/bootstrap/ are updated as fat binaries - The Makefile now explains how to download cosmocc-0.0.12 toolchain - The build scripts under bin/ now support "cosmo" branded toolchains - stat() now goes faster on Windows (shaves 100ms off `make` latency) - Code cleanup and added review on the Windows signal checking code - posix_spawnattr_setrlimit() now works around MacOS ARM64 bugs - Landlock Make now favors posix_spawn() on non-Linux/OpenBSD - posix_spawn() now has better --strace logging on Windows - fstatat() can now avoid EACCES in more cases on Windows - fchmod() can now change the readonly bit on Windows
This commit is contained in:
parent
06c6baaf50
commit
c9fecf3a55
109 changed files with 1188 additions and 454 deletions
|
@ -37,6 +37,7 @@
|
|||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -151,10 +152,11 @@ static textwindows bool spawnfds_exists(struct SpawnFds *fds, int fildes) {
|
|||
return fildes + 0u < fds->n && fds->p[fildes].kind;
|
||||
}
|
||||
|
||||
static textwindows void spawnfds_close(struct SpawnFds *fds, int fildes) {
|
||||
static textwindows errno_t spawnfds_close(struct SpawnFds *fds, int fildes) {
|
||||
if (spawnfds_exists(fds, fildes)) {
|
||||
fds->p[fildes] = (struct Fd){0};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static textwindows errno_t spawnfds_dup2(struct SpawnFds *fds, int fildes,
|
||||
|
@ -181,8 +183,8 @@ static textwindows errno_t spawnfds_dup2(struct SpawnFds *fds, int fildes,
|
|||
}
|
||||
|
||||
static textwindows errno_t spawnfds_open(struct SpawnFds *fds, int64_t dirhand,
|
||||
int fildes, const char *path,
|
||||
int oflag, int mode) {
|
||||
const char *path, int oflag, int mode,
|
||||
int fildes) {
|
||||
int64_t h;
|
||||
errno_t err;
|
||||
char16_t path16[PATH_MAX];
|
||||
|
@ -283,42 +285,47 @@ static textwindows errno_t posix_spawn_nt_impl(
|
|||
// apply user file actions
|
||||
if (file_actions) {
|
||||
for (struct _posix_faction *a = *file_actions; a && !err; a = a->next) {
|
||||
char errno_buf[30];
|
||||
char oflags_buf[128];
|
||||
char openmode_buf[15];
|
||||
(void)errno_buf;
|
||||
(void)oflags_buf;
|
||||
(void)openmode_buf;
|
||||
switch (a->action) {
|
||||
case _POSIX_SPAWN_CLOSE:
|
||||
spawnfds_close(&fds, a->fildes);
|
||||
err = spawnfds_close(&fds, a->fildes);
|
||||
STRACE("spawnfds_close(%d) → %s", a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_DUP2:
|
||||
err = spawnfds_dup2(&fds, a->fildes, a->newfildes);
|
||||
if (err) {
|
||||
STRACE("spawnfds_dup2(%d, %d) failed", a->fildes, a->newfildes);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_dup2(%d, %d) → %s", a->fildes, a->newfildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_OPEN:
|
||||
err = spawnfds_open(&fds, dirhand, a->fildes, a->path, a->oflag,
|
||||
a->mode);
|
||||
if (err) {
|
||||
STRACE("spawnfds_open(%d, %#s) failed", a->fildes, a->path);
|
||||
goto ReturnErr;
|
||||
}
|
||||
err = spawnfds_open(&fds, dirhand, a->path, a->oflag, a->mode,
|
||||
a->fildes);
|
||||
STRACE("spawnfds_open(%#s, %s, %s, %d) → %s", a->path,
|
||||
(DescribeOpenFlags)(oflags_buf, a->oflag),
|
||||
(DescribeOpenMode)(openmode_buf, a->oflag, a->mode), a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_CHDIR:
|
||||
err = spawnfds_chdir(&fds, dirhand, a->path, &dirhand);
|
||||
if (err) {
|
||||
STRACE("spawnfds_chdir(%#s) failed", a->path);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_chdir(%#s) → %s", a->path,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_FCHDIR:
|
||||
err = spawnfds_fchdir(&fds, a->fildes, &dirhand);
|
||||
if (err) {
|
||||
STRACE("spawnfds_fchdir(%d) failed", a->fildes);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_fchdir(%d) → %s", a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
if (err) {
|
||||
goto ReturnErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,9 +579,13 @@ errno_t posix_spawn(int *pid, const char *path,
|
|||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETRLIMIT) {
|
||||
for (int rez = 0; rez <= ARRAYLEN((*attrp)->rlim); ++rez) {
|
||||
if ((*attrp)->rlimset & (1u << rez)) {
|
||||
if (setrlimit(rez, (*attrp)->rlim + rez)) {
|
||||
int rlimset = (*attrp)->rlimset;
|
||||
while (rlimset) {
|
||||
int resource = _bsf(rlimset);
|
||||
rlimset &= ~(1u << resource);
|
||||
if (setrlimit(resource, (*attrp)->rlim + resource)) {
|
||||
// MacOS ARM64 RLIMIT_STACK always returns EINVAL
|
||||
if (!IsXnuSilicon()) {
|
||||
goto ChildFailed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ struct _posix_spawna {
|
|||
bool schedparam_isset;
|
||||
bool schedpolicy_isset;
|
||||
int pgroup;
|
||||
int rlimset;
|
||||
int schedpolicy;
|
||||
int rlimset;
|
||||
struct sched_param schedparam;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigdefault;
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions,
|
||||
int fildes) {
|
||||
if (fildes < 0) return EBADF;
|
||||
if (IsWindows() && fildes > 2) return 0;
|
||||
return __posix_spawn_add_file_action(file_actions,
|
||||
(struct _posix_faction){
|
||||
.action = _POSIX_SPAWN_CLOSE,
|
||||
|
|
|
@ -26,14 +26,12 @@
|
|||
*
|
||||
* @param file_actions was initialized by posix_spawn_file_actions_init()
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise ENOMEM if we require more vespene gas
|
||||
* @raise EBADF if 'fildes' or `newfildes` is negative
|
||||
* @raise ENOTSUP if `newfildes` isn't 0, 1, or 2 on Windows
|
||||
* @raise ENOMEM if insufficient memory was available
|
||||
*/
|
||||
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions,
|
||||
int fildes, int newfildes) {
|
||||
if (fildes < 0 || newfildes < 0) return EBADF;
|
||||
if (IsWindows() && newfildes > 2) return ENOTSUP;
|
||||
return __posix_spawn_add_file_action(file_actions,
|
||||
(struct _posix_faction){
|
||||
.action = _POSIX_SPAWN_DUP2,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/proc/posix_spawn.h"
|
||||
#include "libc/proc/posix_spawn.internal.h"
|
||||
#include "libc/stdio/sysparam.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
|
||||
/**
|
||||
* Gets resource limit for spawned process.
|
||||
|
@ -31,7 +33,7 @@
|
|||
*/
|
||||
int posix_spawnattr_getrlimit(const posix_spawnattr_t *attr, int resource,
|
||||
struct rlimit *rlim) {
|
||||
if ((0 <= resource && resource < ARRAYLEN((*attr)->rlim))) {
|
||||
if (0 <= resource && resource < MIN(RLIM_NLIMITS, ARRAYLEN((*attr)->rlim))) {
|
||||
if (((*attr)->rlimset & (1u << resource))) {
|
||||
*rlim = (*attr)->rlim[resource];
|
||||
return 0;
|
||||
|
|
|
@ -37,9 +37,10 @@
|
|||
*/
|
||||
int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) {
|
||||
if (flags &
|
||||
~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF |
|
||||
POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSCHEDPARAM |
|
||||
POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETSID)) {
|
||||
~(POSIX_SPAWN_USEVFORK | POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP |
|
||||
POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK |
|
||||
POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER |
|
||||
POSIX_SPAWN_SETSID | POSIX_SPAWN_SETRLIMIT)) {
|
||||
return EINVAL;
|
||||
}
|
||||
(*attr)->flags = flags;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/proc/posix_spawn.h"
|
||||
#include "libc/proc/posix_spawn.internal.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
|
||||
/**
|
||||
* Sets resource limit on spawned process.
|
||||
|
@ -32,7 +33,7 @@
|
|||
*/
|
||||
int posix_spawnattr_setrlimit(posix_spawnattr_t *attr, int resource,
|
||||
const struct rlimit *rlim) {
|
||||
if (0 <= resource && resource < ARRAYLEN((*attr)->rlim)) {
|
||||
if (0 <= resource && resource < MIN(RLIM_NLIMITS, ARRAYLEN((*attr)->rlim))) {
|
||||
(*attr)->flags |= POSIX_SPAWN_SETRLIMIT;
|
||||
(*attr)->rlimset |= 1u << resource;
|
||||
(*attr)->rlim[resource] = *rlim;
|
||||
|
|
|
@ -103,12 +103,8 @@ static textwindows dontinstrument uint32_t __proc_worker(void *arg) {
|
|||
__proc_unlock();
|
||||
|
||||
// wait for win32 to report any status change
|
||||
millis = n == 64 ? __SIG_PROC_INTERVAL_MS : -1u;
|
||||
i = WaitForMultipleObjects(n, handles, false, millis);
|
||||
if (i == -1u) {
|
||||
STRACE("PROC WORKER DYING: WAIT FAILED: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
millis = n == 64 ? 20 : -1u;
|
||||
unassert((i = WaitForMultipleObjects(n, handles, false, millis)) != -1u);
|
||||
i &= ~kNtWaitAbandoned;
|
||||
if (!i || i == kNtWaitTimeout) continue;
|
||||
GetExitCodeProcess(handles[i], &status);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue