feat: libc - add SYS_GETCHAR_NB and a non-blocking stdin readiness probe
Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NQRTGoYgnZQsh7uCh6Jsxm
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 91
|
||||
#define MONTAUK_BUILD_NUMBER 92
|
||||
|
||||
@@ -15,9 +15,14 @@ namespace montauk::abi {
|
||||
static bool Sys_IsKeyAvailable() {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc && proc->redirected) {
|
||||
Ipc::HandleSnapshot snapshot;
|
||||
Ipc::Mailbox* mailbox = GetRedirKeyMailbox(proc, snapshot);
|
||||
if (mailbox != nullptr) return Ipc::MailboxHasMessage(mailbox);
|
||||
Ipc::HandleSnapshot inputSnapshot;
|
||||
Ipc::HandleSnapshot mailboxSnapshot;
|
||||
Ipc::Stream* input = GetRedirInStream(proc, inputSnapshot);
|
||||
Ipc::Mailbox* mailbox = GetRedirKeyMailbox(proc, mailboxSnapshot);
|
||||
if (input != nullptr || mailbox != nullptr) {
|
||||
if (input != nullptr && Ipc::StreamHasData(input)) return true;
|
||||
return mailbox != nullptr && Ipc::MailboxHasMessage(mailbox);
|
||||
}
|
||||
}
|
||||
return Drivers::PS2::Keyboard::IsKeyAvailable();
|
||||
}
|
||||
@@ -97,4 +102,41 @@ namespace montauk::abi {
|
||||
}
|
||||
return Drivers::PS2::Keyboard::GetChar();
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-blocking counterpart of Sys_GetChar: returns the next character, or
|
||||
* 0 when none is pending. IsKeyAvailable is not enough to make GetChar
|
||||
* safe to call -- a queued key-release or modifier event reports as
|
||||
* "available" but carries no ascii, and GetChar would go on to block. So
|
||||
* the drain has to happen on this side of the syscall boundary.
|
||||
*/
|
||||
static char Sys_GetCharNb() {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc && proc->redirected) {
|
||||
Ipc::HandleSnapshot inputSnapshot;
|
||||
Ipc::HandleSnapshot mailboxSnapshot;
|
||||
Ipc::Stream* input = GetRedirInStream(proc, inputSnapshot);
|
||||
Ipc::Mailbox* mailbox = GetRedirKeyMailbox(proc, mailboxSnapshot);
|
||||
if (input != nullptr || mailbox != nullptr) {
|
||||
if (input != nullptr) {
|
||||
uint8_t c = 0;
|
||||
if (Ipc::StreamRead(input, &c, 1, true) > 0) return (char)c;
|
||||
}
|
||||
|
||||
while (mailbox != nullptr) {
|
||||
KeyEvent ev{};
|
||||
uint16_t len = sizeof(ev);
|
||||
if (Ipc::MailboxRecv(mailbox, nullptr, &ev, &len, true) <= 0) break;
|
||||
if (ev.pressed && ev.ascii != 0) return ev.ascii;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (Drivers::PS2::Keyboard::IsKeyAvailable()) {
|
||||
auto k = Drivers::PS2::Keyboard::GetKey();
|
||||
if (k.Pressed && k.Ascii != 0) return k.Ascii;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,6 +134,8 @@ namespace montauk::abi {
|
||||
return 0;
|
||||
case SYS_GETCHAR:
|
||||
return (int64_t)Sys_GetChar();
|
||||
case SYS_GETCHAR_NB:
|
||||
return (int64_t)Sys_GetCharNb();
|
||||
case SYS_PING:
|
||||
return (int64_t)Sys_Ping((uint32_t)frame->arg1, (uint32_t)frame->arg2);
|
||||
case SYS_SPAWN:
|
||||
|
||||
@@ -307,6 +307,9 @@ namespace montauk::abi {
|
||||
static constexpr uint64_t SYS_WIFI_CONNECT_ASYNC = 164; // (ssid, password) -> 0 accepted, <0 on error
|
||||
static constexpr uint64_t SYS_NETIFS = 165; // (NetIfInfo*, maxCount) -> count
|
||||
|
||||
/* Keyboard.hpp */
|
||||
static constexpr uint64_t SYS_GETCHAR_NB = 166; // () -> ascii, 0 if nothing pending; never blocks
|
||||
|
||||
// Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM).
|
||||
static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz
|
||||
static constexpr int SDR_PARAM_SAMPLE_RATE = 1; // sample rate, Hz
|
||||
|
||||
Reference in New Issue
Block a user