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:
Justine Tunney 2023-09-07 16:03:19 -07:00
parent 032b1f3449
commit 8bdaddd81d
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
68 changed files with 580 additions and 346 deletions

View file

@ -22,79 +22,87 @@
#include "libc/calls/struct/termios.h"
#include "libc/calls/ttydefaults.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/consolemodeflags.h"
#include "libc/nt/struct/consolescreenbufferinfoex.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/baud.internal.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
textwindows int tcgetattr_nt(int ignored, struct termios *tio) {
int64_t in, out;
bool32 inok, outok;
uint32_t inmode = 0, outmode = 0;
inok = GetConsoleMode((in = __getfdhandleactual(0)), &inmode);
outok = GetConsoleMode((out = __getfdhandleactual(1)), &outmode);
if (inok | outok) {
bzero(tio, sizeof(*tio));
textwindows int tcgetattr_nt(int fd, struct termios *tio) {
int64_t hInput, hOutput;
uint32_t inmode, outmode;
tio->c_cc[VMIN] = 1;
tio->c_cc[VINTR] = __vintr;
tio->c_cc[VQUIT] = __vquit;
tio->c_cc[VERASE] = CTRL('?');
tio->c_cc[VWERASE] = CTRL('W');
tio->c_cc[VKILL] = CTRL('U');
tio->c_cc[VEOF] = CTRL('D');
tio->c_cc[VMIN] = CTRL('A');
tio->c_cc[VSTART] = _POSIX_VDISABLE;
tio->c_cc[VSTOP] = _POSIX_VDISABLE;
tio->c_cc[VSUSP] = _POSIX_VDISABLE;
tio->c_cc[VREPRINT] = CTRL('R');
tio->c_cc[VDISCARD] = CTRL('O');
tio->c_cc[VLNEXT] = CTRL('V');
tio->c_iflag = IUTF8;
tio->c_lflag = ECHOE;
tio->c_cflag = CS8 | CREAD;
tio->_c_ispeed = B38400;
tio->_c_ospeed = B38400;
if (inok) {
if (inmode & kNtEnableLineInput) {
tio->c_lflag |= ICANON;
}
// kNtEnableEchoInput only works with kNtEnableLineInput enabled.
if ((inmode & kNtEnableEchoInput) || (__ttymagic & kFdTtyEchoing)) {
tio->c_lflag |= ECHO;
}
// The Windows console itself always echos control codes as ASCII.
if ((inmode & kNtEnableEchoInput) || !(__ttymagic & kFdTtyEchoRaw)) {
tio->c_lflag |= ECHOCTL;
}
if (!(__ttymagic & kFdTtyNoCr2Nl)) {
tio->c_iflag |= ICRNL;
}
if (!(__ttymagic & kFdTtyNoIsigs)) {
tio->c_lflag |= ISIG;
}
if ((inmode & kNtEnableProcessedInput) || (__ttymagic & kFdTtyMunging)) {
tio->c_lflag |= IEXTEN;
}
}
if (outok) {
if (outmode & kNtEnableProcessedOutput) {
tio->c_oflag |= OPOST;
}
if (!(outmode & kNtDisableNewlineAutoReturn)) {
tio->c_oflag |= OPOST | ONLCR;
}
}
return 0;
if (__isfdkind(fd, kFdConsole)) {
hInput = g_fds.p[fd].handle;
hOutput = g_fds.p[fd].extra;
} else if (fd == STDIN_FILENO || //
fd == STDOUT_FILENO || //
fd == STDERR_FILENO) {
hInput = g_fds.p[STDIN_FILENO].handle;
hOutput = g_fds.p[MAX(STDOUT_FILENO, fd)].handle;
} else {
return enotty();
}
if (!GetConsoleMode(hInput, &inmode) || !GetConsoleMode(hOutput, &outmode)) {
return enotty();
}
bzero(tio, sizeof(*tio));
tio->c_cc[VMIN] = 1;
tio->c_cc[VINTR] = __vintr;
tio->c_cc[VQUIT] = __vquit;
tio->c_cc[VERASE] = CTRL('?');
tio->c_cc[VWERASE] = CTRL('W');
tio->c_cc[VKILL] = CTRL('U');
tio->c_cc[VEOF] = CTRL('D');
tio->c_cc[VMIN] = CTRL('A');
tio->c_cc[VSTART] = _POSIX_VDISABLE;
tio->c_cc[VSTOP] = _POSIX_VDISABLE;
tio->c_cc[VSUSP] = _POSIX_VDISABLE;
tio->c_cc[VREPRINT] = CTRL('R');
tio->c_cc[VDISCARD] = CTRL('O');
tio->c_cc[VLNEXT] = CTRL('V');
tio->c_iflag = IUTF8;
tio->c_lflag = ECHOE;
tio->c_cflag = CS8 | CREAD;
tio->_c_ispeed = B38400;
tio->_c_ospeed = B38400;
if (inmode & kNtEnableLineInput) {
tio->c_lflag |= ICANON;
}
// kNtEnableEchoInput only works with kNtEnableLineInput enabled.
if ((inmode & kNtEnableEchoInput) || (__ttymagic & kFdTtyEchoing)) {
tio->c_lflag |= ECHO;
}
// The Windows console itself always echos control codes as ASCII.
if ((inmode & kNtEnableEchoInput) || !(__ttymagic & kFdTtyEchoRaw)) {
tio->c_lflag |= ECHOCTL;
}
if (!(__ttymagic & kFdTtyNoCr2Nl)) {
tio->c_iflag |= ICRNL;
}
if (!(__ttymagic & kFdTtyNoIsigs)) {
tio->c_lflag |= ISIG;
}
if ((inmode & kNtEnableProcessedInput) || (__ttymagic & kFdTtyMunging)) {
tio->c_lflag |= IEXTEN;
}
if (outmode & kNtEnableProcessedOutput) {
tio->c_oflag |= OPOST;
}
if (!(outmode & kNtDisableNewlineAutoReturn)) {
tio->c_oflag |= OPOST | ONLCR;
}
return 0;
}