Make stdin pollable on Windows

You can now play Super Mario Bros in CMD.EXE using Cosmopolitan! This is
thanks to a new worker thread that's spawned on Windows whenever any one
of poll(), select(), or ioctl(FIONREAD) is linked.
This commit is contained in:
Justine Tunney 2023-08-13 22:42:25 -07:00
parent ef6387ee5e
commit 9c0821def7
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
15 changed files with 280 additions and 58 deletions

View file

@ -183,6 +183,10 @@ textwindows void WinMainForked(void) {
uint32_t i, varlen, oldprot, savepid;
long mapcount, mapcapacity, specialz;
struct StdinRelay stdin;
struct Fds *fds = __veil("r", &g_fds);
stdin = fds->stdin;
// check to see if the process was actually forked
// this variable should have the pipe handle numba
varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar));
@ -261,7 +265,7 @@ textwindows void WinMainForked(void) {
// rewrap the stdin named pipe hack
// since the handles closed on fork
struct Fds *fds = __veil("r", &g_fds);
fds->stdin = stdin;
fds->p[0].handle = GetStdHandle(kNtStdInputHandle);
fds->p[1].handle = GetStdHandle(kNtStdOutputHandle);
fds->p[2].handle = GetStdHandle(kNtStdErrorHandle);
@ -310,7 +314,7 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) {
tib = __tls_enabled ? __get_tls() : 0;
if (!setjmp(jb)) {
pid = untrackpid = __reservefd_unlocked(-1);
reader = CreateNamedPipe(CreatePipeName(pipename), kNtPipeAccessInbound,
reader = CreateNamedPipe(__create_pipe_name(pipename), kNtPipeAccessInbound,
kNtPipeTypeByte | kNtPipeReadmodeByte, 1, PIPE_BUF,
PIPE_BUF, 0, &kNtIsInheritable);
writer = CreateFile(pipename, kNtGenericWrite, 0, 0, kNtOpenExisting, 0, 0);