Fix copy/paste issue in Windows console

This commit is contained in:
Justine Tunney 2023-10-14 15:27:04 -07:00
parent bd48e6c666
commit 06c6baaf50
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
7 changed files with 30 additions and 37 deletions

View file

@ -31,7 +31,6 @@
#include "libc/intrin/atomic.h" #include "libc/intrin/atomic.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/dll.h" #include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/nomultics.internal.h" #include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/strace.internal.h" #include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h" #include "libc/intrin/weaken.h"
@ -129,14 +128,14 @@ struct Keystroke {
struct Keystrokes { struct Keystrokes {
atomic_uint once; atomic_uint once;
bool end_of_file;
bool ohno_decckm;
uint16_t utf16hs;
atomic_int_fast16_t used;
int64_t cin, cot; int64_t cin, cot;
struct Dll *list; struct Dll *list;
struct Dll *line; struct Dll *line;
struct Dll *free; struct Dll *free;
bool end_of_file;
bool ohno_decckm;
unsigned char pc;
uint16_t utf16hs;
pthread_mutex_t lock; pthread_mutex_t lock;
const struct VirtualKey *vkt; const struct VirtualKey *vkt;
struct Keystroke pool[512]; struct Keystroke pool[512];
@ -156,6 +155,12 @@ static textwindows void OpenConsole(void) {
kNtFileShareWrite, 0, kNtOpenExisting, 0, 0); kNtFileShareWrite, 0, kNtOpenExisting, 0, 0);
} }
static textwindows int AddSignal(int sig) {
atomic_fetch_or_explicit(&__get_tls()->tib_sigpending, 1ull << (sig - 1),
memory_order_relaxed);
return 0;
}
static textwindows void InitConsole(void) { static textwindows void InitConsole(void) {
cosmo_once(&__keystroke.once, OpenConsole); cosmo_once(&__keystroke.once, OpenConsole);
} }
@ -295,9 +300,9 @@ static textwindows int ProcessKeyEvent(const struct NtInputRecord *r, char *p) {
// tcsetattr() lets anyone reconfigure these keybindings // tcsetattr() lets anyone reconfigure these keybindings
if (c && !(__ttyconf.magic & kTtyNoIsigs)) { if (c && !(__ttyconf.magic & kTtyNoIsigs)) {
if (c == __ttyconf.vintr) { if (c == __ttyconf.vintr) {
return __sig_enqueue(SIGINT); return AddSignal(SIGINT);
} else if (c == __ttyconf.vquit) { } else if (c == __ttyconf.vquit) {
return __sig_enqueue(SIGQUIT); return AddSignal(SIGQUIT);
} }
} }
@ -399,7 +404,7 @@ static textwindows int ConvertConsoleInputToAnsi(const struct NtInputRecord *r,
case kNtMouseEvent: case kNtMouseEvent:
return ProcessMouseEvent(r, p); return ProcessMouseEvent(r, p);
case kNtWindowBufferSizeEvent: case kNtWindowBufferSizeEvent:
return __sig_enqueue(SIGWINCH); return AddSignal(SIGWINCH);
default: default:
return 0; return 0;
} }
@ -409,8 +414,8 @@ static textwindows struct Keystroke *NewKeystroke(void) {
struct Dll *e; struct Dll *e;
struct Keystroke *k = 0; struct Keystroke *k = 0;
int i, n = ARRAYLEN(__keystroke.pool); int i, n = ARRAYLEN(__keystroke.pool);
if (atomic_load_explicit(&__keystroke.pc, memory_order_acquire) < n && if (atomic_load_explicit(&__keystroke.used, memory_order_acquire) < n &&
(i = atomic_fetch_add(&__keystroke.pc, 1)) < n) { (i = atomic_fetch_add(&__keystroke.used, 1)) < n) {
k = __keystroke.pool + i; k = __keystroke.pool + i;
} else { } else {
if ((e = dll_first(__keystroke.free))) { if ((e = dll_first(__keystroke.free))) {

View file

@ -91,7 +91,8 @@ textwindows void __sig_delete(int sig) {
BLOCK_SIGNALS; BLOCK_SIGNALS;
_pthread_lock(); _pthread_lock();
for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) { for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) {
POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending &= ~(1ull << (sig - 1)); atomic_fetch_and_explicit(&POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending,
~(1ull << (sig - 1)), memory_order_relaxed);
} }
_pthread_unlock(); _pthread_unlock();
ALLOW_SIGNALS; ALLOW_SIGNALS;
@ -157,7 +158,8 @@ static textwindows bool __sig_start(struct PosixThread *pt, int sig,
} }
if (pt->tib->tib_sigmask & (1ull << (sig - 1))) { if (pt->tib->tib_sigmask & (1ull << (sig - 1))) {
STRACE("enqueing %G on %d", sig, _pthread_tid(pt)); STRACE("enqueing %G on %d", sig, _pthread_tid(pt));
pt->tib->tib_sigpending |= 1ull << (sig - 1); atomic_fetch_or_explicit(&pt->tib->tib_sigpending, 1ull << (sig - 1),
memory_order_relaxed);
return false; return false;
} }
if (*rva == (intptr_t)SIG_DFL) { if (*rva == (intptr_t)SIG_DFL) {
@ -339,7 +341,8 @@ static int __sig_killer(struct PosixThread *pt, int sig, int sic) {
!((uintptr_t)__executable_start <= nc.Rip && !((uintptr_t)__executable_start <= nc.Rip &&
nc.Rip < (uintptr_t)__privileged_start)) { nc.Rip < (uintptr_t)__privileged_start)) {
STRACE("enqueing %G on %d rip %p", sig, _pthread_tid(pt), nc.Rip); STRACE("enqueing %G on %d rip %p", sig, _pthread_tid(pt), nc.Rip);
pt->tib->tib_sigpending |= 1ull << (sig - 1); atomic_fetch_or_explicit(&pt->tib->tib_sigpending, 1ull << (sig - 1),
memory_order_relaxed);
ResumeThread(th); ResumeThread(th);
__sig_cancel(pt, sig, flags); __sig_cancel(pt, sig, flags);
return 0; return 0;

View file

@ -55,7 +55,8 @@ int sigpending(sigset_t *pending) {
rc = 0; rc = 0;
} else if (IsWindows()) { } else if (IsWindows()) {
*pending = atomic_load_explicit(&__sig.pending, memory_order_acquire) | *pending = atomic_load_explicit(&__sig.pending, memory_order_acquire) |
__get_tls()->tib_sigpending; atomic_load_explicit(&__get_tls()->tib_sigpending,
memory_order_acquire);
rc = 0; rc = 0;
} else { } else {
rc = enosys(); rc = enosys();

View file

@ -15,7 +15,6 @@ COSMOPOLITAN_C_START_
} \ } \
while (0) while (0)
int __sig_enqueue(int);
sigset_t __sig_block(void); sigset_t __sig_block(void);
void __sig_unblock(sigset_t); void __sig_unblock(sigset_t);
void __sig_finishwait(sigset_t); void __sig_finishwait(sigset_t);

View file

@ -48,11 +48,6 @@ void __sig_unblock(sigset_t m) {
} }
} }
textwindows int __sig_enqueue(int sig) {
__get_tls()->tib_sigpending |= 1ull << (sig - 1);
return 0;
}
textwindows sigset_t __sig_beginwait(sigset_t waitmask) { textwindows sigset_t __sig_beginwait(sigset_t waitmask) {
return atomic_exchange_explicit(&__get_tls()->tib_sigmask, waitmask, return atomic_exchange_explicit(&__get_tls()->tib_sigmask, waitmask,
memory_order_acquire); memory_order_acquire);

View file

@ -16,24 +16,18 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h" #include "ape/sections.internal.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h" #include "libc/calls/sig.internal.h"
#include "libc/calls/state.internal.h" #include "libc/calls/state.internal.h"
#include "libc/calls/struct/fd.internal.h"
#include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h"
#include "libc/calls/wincrash.internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/directmap.internal.h" #include "libc/intrin/directmap.internal.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h" #include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h" #include "libc/intrin/weaken.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/nt/console.h"
#include "libc/nt/createfile.h" #include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h" #include "libc/nt/enum/creationdisposition.h"
@ -41,21 +35,17 @@
#include "libc/nt/enum/pageflags.h" #include "libc/nt/enum/pageflags.h"
#include "libc/nt/enum/startf.h" #include "libc/nt/enum/startf.h"
#include "libc/nt/errors.h" #include "libc/nt/errors.h"
#include "libc/nt/files.h"
#include "libc/nt/ipc.h" #include "libc/nt/ipc.h"
#include "libc/nt/memory.h" #include "libc/nt/memory.h"
#include "libc/nt/process.h" #include "libc/nt/process.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/nt/signals.h" #include "libc/nt/signals.h"
#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/nt/struct/ntexceptionpointers.h"
#include "libc/nt/synchronization.h"
#include "libc/nt/thread.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/proc/describefds.internal.h"
#include "libc/proc/ntspawn.h" #include "libc/proc/ntspawn.h"
#include "libc/proc/proc.internal.h" #include "libc/proc/proc.internal.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h" #include "libc/runtime/symbols.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"
@ -65,7 +55,6 @@
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#include "libc/thread/itimer.internal.h" #include "libc/thread/itimer.internal.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/tls.h" #include "libc/thread/tls.h"
#ifdef __x86_64__ #ifdef __x86_64__
@ -395,10 +384,9 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) {
__set_tls(tib); __set_tls(tib);
__morph_tls(); __morph_tls();
__tls_enabled_set(true); __tls_enabled_set(true);
// get new main thread handle // the child's pending signals is initially empty
// clear pending signals
tib->tib_sigpending = 0;
atomic_store_explicit(&__sig.pending, 0, memory_order_relaxed); atomic_store_explicit(&__sig.pending, 0, memory_order_relaxed);
atomic_store_explicit(&tib->tib_sigpending, 0, memory_order_relaxed);
// re-enable threads // re-enable threads
__enable_threads(); __enable_threads();
// re-apply code morphing for function tracing // re-apply code morphing for function tracing

View file

@ -23,6 +23,7 @@
#include "libc/log/check.h" #include "libc/log/check.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
#include "libc/x/x.h" #include "libc/x/x.h"
@ -48,5 +49,6 @@ TEST(getcwd, testWindows_addsFunnyPrefix) {
if (!IsWindows()) return; if (!IsWindows()) return;
char path[PATH_MAX]; char path[PATH_MAX];
ASSERT_NE(0, getcwd(path, sizeof(path))); ASSERT_NE(0, getcwd(path, sizeof(path)));
EXPECT_STARTSWITH("/C/", path); path[1] = tolower(path[1]);
EXPECT_STARTSWITH("/c/", path);
} }