mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 08:18:30 +00:00
Rewrite Windows console input handling
This change removes our use of ENABLE_VIRTUAL_TERMINAL_INPUT (which isn't very good) in favor of having read() translate Windows Console input events to ANSI/XTERM sequences by hand. This makes it possible to capture important keystrokes (e.g. ctrl-space) that weren't possible before. Most importantly this change also removes the stdin/sigwinch worker threads, which never really worked that well. Interactive TTY sessions will now work reliably when a Cosmo process spawns or forks another Cosmo process, e.g. unbourne.com launching emacs.com.
This commit is contained in:
parent
ececec4c94
commit
d6c2830850
27 changed files with 635 additions and 464 deletions
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/console.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
@ -47,8 +49,6 @@
|
|||
|
||||
#ifdef __x86_64__
|
||||
|
||||
__static_yoink("WinMainStdin");
|
||||
|
||||
/*
|
||||
* Polls on the New Technology.
|
||||
*
|
||||
|
@ -59,8 +59,8 @@ __static_yoink("WinMainStdin");
|
|||
textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
|
||||
const sigset_t *sigmask) {
|
||||
bool ok;
|
||||
uint32_t avail;
|
||||
sigset_t oldmask;
|
||||
uint32_t avail, cm;
|
||||
struct sys_pollfd_nt pipefds[8];
|
||||
struct sys_pollfd_nt sockfds[64];
|
||||
int pipeindices[ARRAYLEN(pipefds)];
|
||||
|
@ -98,7 +98,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
|
|||
}
|
||||
} else if (pn < ARRAYLEN(pipefds)) {
|
||||
pipeindices[pn] = i;
|
||||
pipefds[pn].handle = __resolve_stdin_handle(g_fds.p[fds[i].fd].handle);
|
||||
pipefds[pn].handle = g_fds.p[fds[i].fd].handle;
|
||||
pipefds[pn].events = 0;
|
||||
pipefds[pn].revents = 0;
|
||||
switch (g_fds.p[fds[i].fd].flags & O_ACCMODE) {
|
||||
|
@ -151,6 +151,19 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
|
|||
} else {
|
||||
pipefds[i].revents |= POLLERR;
|
||||
}
|
||||
} else if (GetConsoleMode(pipefds[i].handle, &cm)) {
|
||||
int e = errno;
|
||||
avail = CountConsoleInputBytes(pipefds[i].handle);
|
||||
if (avail > 0) {
|
||||
pipefds[i].revents |= POLLIN;
|
||||
} else if (avail == -1u) {
|
||||
if (errno == ENODATA) {
|
||||
pipefds[i].revents |= POLLIN;
|
||||
} else {
|
||||
pipefds[i].revents |= POLLERR;
|
||||
}
|
||||
errno = e;
|
||||
}
|
||||
} else {
|
||||
// we have no way of polling if a non-socket is readable yet
|
||||
// therefore we assume that if it can happen it shall happen
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue