Console mode is a Neolith extension that treats standard input and output as a connected interactive user. It is mainly used for local development, debugging, and scripted testing.
Use -c (or --console-mode) when starting the driver:
neolith -f neolith.conf -cWhen console mode is enabled:
- The normal startup path runs (master load, epilog, preload).
- The backend initializes runtime I/O.
- The driver creates a console interactive and calls master
connect(0). - If accepted by mudlib
connect(), normallogon()flow continues.
Console user behavior:
- Console connection is interactive but does not use TELNET protocol.
input_to()andget_char()are supported.- If the console user disconnects in a real terminal session, stdin stays open and ENTER can reconnect.
- Ctrl-C handling follows normal terminal behavior.
Console mode uses async runtime plus a dedicated console worker.
- Backend creates
async_runtime_t. - Network descriptors are registered with async runtime.
- Console input is handled by
console_worker(worker thread). - Worker pushes completed lines to
async_queue_t. - Worker posts completions (
CONSOLE_COMPLETION_KEY) to wake backend. - Backend drains queued lines into the console interactive command buffer once per
process_io()cycle.
Completion behavior:
- Console completion events are wake-up signals.
- Queue draining is unconditional in
process_io()so queued input does not starve if completion edges are coalesced or missed. - Console EOF is also posted as a wake-up signal and consumed on the backend thread.
This keeps command processing unified while avoiding platform-specific stdin blocking in the backend thread.
Console worker detects stdin type at startup:
CONSOLE_TYPE_REAL: interactive terminal or console.CONSOLE_TYPE_PIPE: piped stdin.CONSOLE_TYPE_FILE: redirected file stdin.CONSOLE_TYPE_NONE: no usable stdin.
Detection uses:
- Windows:
GetConsoleMode()andGetFileType(). - POSIX:
isatty()andfstat().
POSIX builds with termios use termios for echo and single-char mode.
Windows builds use shared helpers in lib/async/console_mode.h:
set_console_input_line_mode(context, echo)set_console_input_echo(context, echo)set_console_input_single_char(context, single)enable_console_output_ansi()
These helpers are used by:
- Console worker startup.
- Console reconnect path in backend.
- Console path in
set_input_echo(). - Console branch of
set_input_single_char().
For pipe and file stdin, helper calls are no-op by design, preserving scripted input behavior.
- EOF is detected by the console worker and handled on the backend thread.
- Backend EOF handling removes the console interactive through
remove_interactive(). remove_interactive()invokes the interactivenet_dead()apply.- Pipe or file stdin: teardown sets shutdown flow after console removal.
- Real terminal stdin: reconnect prompt path remains available.
For piped/file console input, net_dead() returns before the driver proceeds
with shutdown.
This split supports both interactive use and deterministic automation.
See docs/manual/dev.md for build and configuration setup.
# Linux or WSL
neolith -f neolith.conf -c
# Windows
neolith.exe -f neolith.conf -cQuick checks:
- Startup reaches logon prompt via
connect(0). - Normal commands execute.
input_to()no-echo prompts work.get_char()paths work (if mudlib uses them).- Disconnect and press ENTER to verify reconnect (real terminal only).
Piped input:
# Linux or WSL
echo -e "admin\npassword\nsay test\nshutdown" | neolith -f neolith.conf -c
# Windows PowerShell
"admin`npassword`nsay test`nshutdown" | .\neolith.exe -f neolith.conf -cRedirected input:
# Linux or WSL
echo -e "admin\npassword\nsay test\nshutdown" > commands.txt
neolith -f neolith.conf -c < commands.txt
# Windows PowerShell
"admin`npassword`nsay test`nshutdown" | Out-File commands.txt
Get-Content commands.txt | .\neolith.exe -f neolith.conf -cThe driver processes commands until EOF and then shuts down for pipe or file modes.
In mudlib terms, console EOF now follows the same disconnect apply path as other
interactive teardown: net_dead() is called during removal.
Current console-mode coverage is in tests/test_console_worker:
- tests/test_console_worker/test_console_worker_detection.cpp
- tests/test_console_worker/test_console_worker_lifecycle.cpp
- tests/test_console_worker/test_async_runtime_console.cpp
Related interactive behavior coverage (input flags and single-char flow):
Run focused tests:
# Linux
ctest --preset ut-linux -R "ConsoleWorker|AsyncRuntimeConsole|InputToGetChar"
# Windows
ctest --preset ut-vs16-x64 -R "ConsoleWorker|AsyncRuntimeConsole|InputToGetChar"Driver exits immediately:
- Verify mudlib path and config values.
- Verify master object compiles.
- Check startup logs.
No input accepted:
- Confirm stdin mode (real console vs pipe/file).
- Check console worker initialization logs.
- On Windows, check console handle availability from
GetStdHandle(STD_INPUT_HANDLE).
Unicode issues:
- Windows console path configures UTF-8 output mode for real consoles.
- On POSIX, verify locale settings.