Overhaul process spawning

This commit is contained in:
Justine Tunney 2023-09-10 08:12:43 -07:00
parent 99dc1281f5
commit 26e254fb4d
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
96 changed files with 1848 additions and 1541 deletions

View file

@ -155,6 +155,11 @@ static char *Finish(void) {
}
}
static int Pause(void) {
pause();
return 0;
}
static int True(void) {
return 0;
}
@ -671,6 +676,7 @@ static int TryBuiltin(void) {
if (!strcmp(args[0], "true")) return True();
if (!strcmp(args[0], "test")) return Test();
if (!strcmp(args[0], "kill")) return Kill();
if (!strcmp(args[0], "pause")) return Pause();
if (!strcmp(args[0], "flock")) return Flock();
if (!strcmp(args[0], "chmod")) return Chmod();
if (!strcmp(args[0], "touch")) return Touch();

View file

@ -16,9 +16,11 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/utmp.h"
@ -28,23 +30,37 @@
/**
* Prepares terminal for login.
*
* After this operation `fd` will be used for all stdio handles.
*
* @return 0 on success, or -1 w/ errno
* @raise EPERM if terminal is already controlling another sid?
* @raise EPERM if pledge() was used without tty
* @raise ENOTTY if `fd` isn't a teletypewriter
* @raise ENOSYS on Windows and Metal
* @raise EPERM if terminal is already controlling another sid
* @raise EBADF if `fd` isn't open
*/
int login_tty(int fd) {
int i, rc;
if (IsLinux() || IsBsd()) {
setsid();
if (!sys_ioctl(fd, TIOCSCTTY, 0)) {
for (i = 0; i < 3; ++i) dup2(fd, i);
if (fd > 2) close(fd);
rc = 0;
} else {
rc = -1;
}
} else {
int rc;
if (!IsLinux() && !IsBsd()) {
rc = enosys();
} else if (!isatty(fd)) {
rc = -1; // validate before changing the process's state
} else {
// become session leader
// we don't care if it fails due to already being the one
int e = errno;
sys_setsid();
errno = e;
// take control of teletypewriter (requires being leader)
if ((rc = sys_ioctl(fd, TIOCSCTTY, 0)) != -1) {
unassert(!sys_dup2(fd, 0, 0));
unassert(!sys_dup2(fd, 1, 0));
unassert(!sys_dup2(fd, 2, 0));
if (fd > 2) {
unassert(!sys_close(fd));
}
rc = 0;
}
}
STRACE("login_tty(%d) → %d% m", fd, rc);
return rc;

View file

@ -76,6 +76,7 @@ o/$(MODE)/libc/runtime/ftracer.o: private \
o/$(MODE)/libc/runtime/cosmo2.o \
o/$(MODE)/libc/runtime/fork-nt.o \
o/$(MODE)/libc/runtime/enable_tls.o \
o/$(MODE)/libc/runtime/printmemoryintervals.o \
o/$(MODE)/libc/runtime/findmemoryinterval.o \
o/$(MODE)/libc/runtime/sys_mprotect.greg.o \
@ -92,6 +93,7 @@ o/$(MODE)/libc/runtime/print.greg.o \
o/$(MODE)/libc/runtime/stackchkfail.o \
o/$(MODE)/libc/runtime/stackchkfaillocal.o \
o/$(MODE)/libc/runtime/winmain.greg.o \
o/$(MODE)/libc/runtime/interceptflag.greg.o \
o/$(MODE)/libc/runtime/opensymboltable.o: private \
CFLAGS += \
-Os \

View file

@ -60,7 +60,8 @@ static textexit void LogStackUse(void) {
if (!PLEDGED(STDIO) || !PLEDGED(WPATH) || !PLEDGED(CPATH)) return;
usage = GetStackUsage((char *)GetStackAddr(), GetStackSize());
e = errno;
if ((fd = open(stacklog, O_APPEND | O_CREAT | O_WRONLY, 0644)) != -1) {
if ((fd = open(stacklog, O_APPEND | O_CREAT | O_WRONLY | O_CLOEXEC, 0644)) !=
-1) {
p = FormatUint64(stacklog, usage);
for (i = 0; i < __argc; ++i) {
n = strlen(__argv[i]);

View file

@ -21,6 +21,8 @@
#include "libc/calls/state.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/getenv.internal.h"
#include "libc/intrin/weaken.h"
@ -176,6 +178,27 @@ __msabi static textwindows wontreturn void WinInit(const char16_t *cmdline) {
struct WinArgs *wa =
(struct WinArgs *)(stackaddr + (stacksize - sizeof(struct WinArgs)));
// allocate asan memory if needed
if (IsAsan()) {
uintptr_t shadowaddr = 0x7fff8000 + (stackaddr >> 3);
uintptr_t shadowend = 0x7fff8000 + ((stackaddr + stacksize) >> 3);
uintptr_t shallocaddr = ROUNDDOWN(shadowaddr, FRAMESIZE);
uintptr_t shallocend = ROUNDUP(shadowend, FRAMESIZE);
uintptr_t shallocsize = shallocend - shallocaddr;
__imp_MapViewOfFileEx(
(_mmi.p[1].h =
__imp_CreateFileMappingW(-1, &kNtIsInheritable, kNtPageReadwrite,
shallocsize >> 32, shallocsize, NULL)),
kNtFileMapWrite, 0, 0, shallocsize, (void *)shallocaddr);
_mmi.p[1].x = shallocaddr >> 16;
_mmi.p[1].y = (shallocaddr >> 16) + ((shallocsize - 1) >> 16);
_mmi.p[1].prot = PROT_READ | PROT_WRITE;
_mmi.p[1].flags = 0x00000022; // private+anonymous
_mmi.p[1].size = shallocsize;
_mmi.i = 2;
__asan_poison((void *)stackaddr, GetGuardSize(), kAsanStackOverflow);
}
// parse utf-16 command into utf-8 argv array in argument block
int count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock),
wa->argv, ARRAYLEN(wa->argv));
@ -231,13 +254,13 @@ __msabi textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
// sloppy flag-only check for early initialization
if (__strstr16(cmdline, u"--strace")) ++__strace;
#endif
if (_weaken(WinSockInit)) {
_weaken(WinSockInit)();
}
DeduplicateStdioHandles();
if (_weaken(WinMainStdin)) {
_weaken(WinMainStdin)();
}
if (_weaken(WinSockInit)) {
_weaken(WinSockInit)();
}
if (_weaken(WinMainForked)) {
_weaken(WinMainForked)();
}