diff --git a/kernel/src/Api/Syscall.cpp b/kernel/src/Api/Syscall.cpp index 1a2f3e2..c392599 100644 --- a/kernel/src/Api/Syscall.cpp +++ b/kernel/src/Api/Syscall.cpp @@ -626,6 +626,8 @@ namespace montauk::abi { return 0; } + case SYS_TERMINAL_ATTACHED: + return Sys_TerminalAttached(); default: return -1; } @@ -652,7 +654,8 @@ namespace montauk::abi { Hal::WriteMSR(Hal::IA32_FMASK, 0x200); Kt::KernelLogStream(Kt::OK, "Syscall") << "SYSCALL/SYSRET initialized (LSTAR=" - << kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 171 syscall slots)"; + << kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", " + << (SYS_TERMINAL_ATTACHED + 1) << " syscall slots)"; } } diff --git a/kernel/src/Api/Syscall.hpp b/kernel/src/Api/Syscall.hpp index f0ec4dd..7ac5c31 100644 --- a/kernel/src/Api/Syscall.hpp +++ b/kernel/src/Api/Syscall.hpp @@ -160,6 +160,9 @@ namespace montauk::abi { /* Userspace log */ static constexpr uint64_t SYS_LOG_WRITE = 176; + /* Process terminal attachment */ + static constexpr uint64_t SYS_TERMINAL_ATTACHED = 177; + // Audio control commands (for SYS_AUDIOCTL). // // Commands 0..3 act on the stream named by the handle argument. diff --git a/kernel/src/Api/Terminal.hpp b/kernel/src/Api/Terminal.hpp index 5f85543..90e922b 100644 --- a/kernel/src/Api/Terminal.hpp +++ b/kernel/src/Api/Terminal.hpp @@ -12,6 +12,11 @@ namespace montauk::abi { + static int Sys_TerminalAttached() { + auto* proc = Sched::GetCurrentProcessPtr(); + return proc != nullptr && proc->redirected && proc->ioOutHandle >= 0; + } + static void Sys_Print(const char* text) { auto* proc = Sched::GetCurrentProcessPtr(); if (proc && proc->redirected) { diff --git a/programs/include/Api/Syscall.hpp b/programs/include/Api/Syscall.hpp index 90a5722..7d87f9f 100644 --- a/programs/include/Api/Syscall.hpp +++ b/programs/include/Api/Syscall.hpp @@ -240,6 +240,7 @@ namespace montauk::abi { static constexpr uint64_t SYS_SPAWN_ENV = 173; static constexpr uint64_t SYS_LOG_WRITE = 176; // (logMessage) -> 0 + static constexpr uint64_t SYS_TERMINAL_ATTACHED = 177; // () -> 1 when connected to a userspace terminal // Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM). static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz diff --git a/programs/include/libc/montauk.h b/programs/include/libc/montauk.h index 496ac6f..7f20e03 100644 --- a/programs/include/libc/montauk.h +++ b/programs/include/libc/montauk.h @@ -69,7 +69,7 @@ extern "C" { #define MTK_SYS_TERMSCALE 43 #define MTK_SYS_RESOLVE 44 #define MTK_SYS_GETRANDOM 45 -#define MTK_SYS_LOG 46 +#define MTK_SYS_LOG 46 #define MTK_SYS_MOUSESTATE 47 #define MTK_SYS_SETMOUSEBOUNDS 48 #define MTK_SYS_SPAWN_REDIR 49 @@ -200,6 +200,7 @@ extern "C" { #define MTK_SYS_SETSESSION 174 #define MTK_SYS_KILLSESSION 175 #define MTK_SYS_LOG_WRITE 176 +#define MTK_SYS_TERMINAL_ATTACHED 177 /* @SYSCALLS-END */ #define MTK_SOCK_TCP 1 @@ -419,6 +420,10 @@ static inline int mtk_getpid(void) { return (int)_mtk_syscall0(MTK_SYS_GETPID); } +static inline int mtk_terminal_attached(void) { + return (int)_mtk_syscall0(MTK_SYS_TERMINAL_ATTACHED) != 0; +} + static inline int mtk_spawn(const char *path, const char *args) { return (int)_mtk_syscall2(MTK_SYS_SPAWN, (long)path, (long)args); } diff --git a/programs/include/montauk/syscall.h b/programs/include/montauk/syscall.h index 4b14202..1069447 100644 --- a/programs/include/montauk/syscall.h +++ b/programs/include/montauk/syscall.h @@ -438,6 +438,11 @@ namespace montauk { return syscall1(montauk::abi::SYS_LOG_WRITE, (uint64_t)logMessage); } + // True when stdout is connected to a redirected userspace terminal. + inline bool terminal_attached() { + return syscall0(montauk::abi::SYS_TERMINAL_ATTACHED) != 0; + } + // I/O redirection inline int spawn_redir(const char* path, const char* args = nullptr) { return (int)syscall2(montauk::abi::SYS_SPAWN_REDIR, (uint64_t)path, (uint64_t)args); diff --git a/programs/man/syscalls.2 b/programs/man/syscalls.2 index e3e993c..a8e3240 100644 --- a/programs/man/syscalls.2 +++ b/programs/man/syscalls.2 @@ -422,6 +422,10 @@ Read from the kernel ring log buffer. int64_t montauk::read_log(char* buf, uint64_t size); +.B SYS_LOG_WRITE (176) + Append a userspace message to the system log. + int64_t montauk::write_log(const char* message); + .SH I/O REDIRECTION Used by the terminal app and similar programs to run a child process with its console I/O captured instead of going directly @@ -447,6 +451,11 @@ Tell a redirected child its terminal dimensions changed. int montauk::childio_settermsz(int childPid, int cols, int rows); +.B SYS_TERMINAL_ATTACHED (177) + Return 1 when the calling process has a redirected userspace + terminal output stream, otherwise return 0. + bool montauk::terminal_attached(); + .SH WINDOW SERVER Window server syscalls are used by GUI programs to create and drive an on-screen window (see montauk/Window.hpp for the diff --git a/template/docs/syscalls.md b/template/docs/syscalls.md index 22b0932..975335a 100644 --- a/template/docs/syscalls.md +++ b/template/docs/syscalls.md @@ -32,6 +32,7 @@ void exit(int code); // Terminate process (nore void yield(); // Yield CPU to scheduler void sleep_ms(uint64_t ms); // Sleep for milliseconds int getpid(); // Get current process ID +bool terminal_attached(); // Whether stdout is connected to a userspace terminal int spawn(const char* path, const char* args); // Spawn child, inheriting environment int waitpid(int pid); // Wait for process to exit int kill(int pid); // Kill a process diff --git a/template/sysroot/include/Api/Syscall.hpp b/template/sysroot/include/Api/Syscall.hpp index 90a5722..7d87f9f 100644 --- a/template/sysroot/include/Api/Syscall.hpp +++ b/template/sysroot/include/Api/Syscall.hpp @@ -240,6 +240,7 @@ namespace montauk::abi { static constexpr uint64_t SYS_SPAWN_ENV = 173; static constexpr uint64_t SYS_LOG_WRITE = 176; // (logMessage) -> 0 + static constexpr uint64_t SYS_TERMINAL_ATTACHED = 177; // () -> 1 when connected to a userspace terminal // Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM). static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz diff --git a/template/sysroot/include/libc/montauk.h b/template/sysroot/include/libc/montauk.h index 496ac6f..7f20e03 100644 --- a/template/sysroot/include/libc/montauk.h +++ b/template/sysroot/include/libc/montauk.h @@ -69,7 +69,7 @@ extern "C" { #define MTK_SYS_TERMSCALE 43 #define MTK_SYS_RESOLVE 44 #define MTK_SYS_GETRANDOM 45 -#define MTK_SYS_LOG 46 +#define MTK_SYS_LOG 46 #define MTK_SYS_MOUSESTATE 47 #define MTK_SYS_SETMOUSEBOUNDS 48 #define MTK_SYS_SPAWN_REDIR 49 @@ -200,6 +200,7 @@ extern "C" { #define MTK_SYS_SETSESSION 174 #define MTK_SYS_KILLSESSION 175 #define MTK_SYS_LOG_WRITE 176 +#define MTK_SYS_TERMINAL_ATTACHED 177 /* @SYSCALLS-END */ #define MTK_SOCK_TCP 1 @@ -419,6 +420,10 @@ static inline int mtk_getpid(void) { return (int)_mtk_syscall0(MTK_SYS_GETPID); } +static inline int mtk_terminal_attached(void) { + return (int)_mtk_syscall0(MTK_SYS_TERMINAL_ATTACHED) != 0; +} + static inline int mtk_spawn(const char *path, const char *args) { return (int)_mtk_syscall2(MTK_SYS_SPAWN, (long)path, (long)args); } diff --git a/template/sysroot/include/montauk/syscall.h b/template/sysroot/include/montauk/syscall.h index 4b14202..1069447 100644 --- a/template/sysroot/include/montauk/syscall.h +++ b/template/sysroot/include/montauk/syscall.h @@ -438,6 +438,11 @@ namespace montauk { return syscall1(montauk::abi::SYS_LOG_WRITE, (uint64_t)logMessage); } + // True when stdout is connected to a redirected userspace terminal. + inline bool terminal_attached() { + return syscall0(montauk::abi::SYS_TERMINAL_ATTACHED) != 0; + } + // I/O redirection inline int spawn_redir(const char* path, const char* args = nullptr) { return (int)syscall2(montauk::abi::SYS_SPAWN_REDIR, (uint64_t)path, (uint64_t)args);