mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 19:28:29 +00:00
Make the Windows Console work better
The stdio reader thread now appears to be working recursively along cosmopolitan subprocesses. For example, it's now possible to launch vim.com from the unbourne.com bestline repl, thanks to hacks plus a bug fix to select() timeouts.
This commit is contained in:
parent
032b1f3449
commit
8bdaddd81d
68 changed files with 580 additions and 346 deletions
|
@ -23,10 +23,14 @@
|
|||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/comms.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -45,18 +49,48 @@ static const char *DescribeFlush(char buf[12], int action) {
|
|||
}
|
||||
|
||||
static dontinline textwindows int sys_tcflush_nt(int fd, int queue) {
|
||||
bool32 ok;
|
||||
int64_t h;
|
||||
if (!__isfdopen(fd)) return ebadf();
|
||||
ok = true;
|
||||
h = g_fds.p[fd].handle;
|
||||
if (queue == TCIFLUSH || queue == TCIOFLUSH) {
|
||||
ok &= !!PurgeComm(h, kNtPurgeRxclear);
|
||||
if (!__isfdopen(fd)) {
|
||||
return ebadf();
|
||||
}
|
||||
if (queue == TCOFLUSH || queue == TCIOFLUSH) {
|
||||
ok &= !!PurgeComm(h, kNtPurgeTxclear);
|
||||
int64_t hConin;
|
||||
if (__isfdkind(fd, kFdConsole)) {
|
||||
hConin = g_fds.p[fd].handle;
|
||||
} else if (fd == 0 || fd == 1 || fd == 2) {
|
||||
hConin = g_fds.p[(fd = 0)].handle;
|
||||
} else {
|
||||
return enotty();
|
||||
}
|
||||
return ok ? 0 : __winerr();
|
||||
uint32_t inmode;
|
||||
if (!GetConsoleMode(hConin, &inmode)) {
|
||||
return enotty();
|
||||
}
|
||||
if (queue == TCOFLUSH) {
|
||||
return 0; // windows console output is never buffered
|
||||
}
|
||||
FlushConsoleInputBuffer(hConin);
|
||||
int rc = 0;
|
||||
int e = errno;
|
||||
int oldflags = g_fds.p[fd].flags;
|
||||
g_fds.p[fd].flags |= O_NONBLOCK;
|
||||
for (;;) {
|
||||
char buf[512];
|
||||
ssize_t got = sys_read_nt_impl(fd, buf, 512, -1);
|
||||
if (!got) {
|
||||
break;
|
||||
} else if (got == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
errno = e;
|
||||
} else if (errno == EINTR) {
|
||||
errno = e;
|
||||
continue;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_fds.p[fd].flags = oldflags;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +111,9 @@ static dontinline textwindows int sys_tcflush_nt(int fd, int queue) {
|
|||
*/
|
||||
int tcflush(int fd, int queue) {
|
||||
int rc;
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
if (queue != TCIFLUSH && queue != TCOFLUSH && queue != TCIOFLUSH) {
|
||||
rc = einval();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = enotty();
|
||||
} else if (IsLinux()) {
|
||||
rc = sys_ioctl(fd, TCFLSH, queue);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue