feat: extend kmain with redirDriverThread and stderrTypePath

This commit is contained in:
dualfroz committed 2026-09-04 22:03:22 +02:00
1 parent a59ae7a9f8
commit 31dce591f3
1 file changed
+173
+173
View File
@@ -850,6 +850,179 @@ static void redirTypeReadCommand(void)
* "redirwriter >> /tmp/redir.txt" (append, same path) leaves a real tmpfs
* file holding two back-to-back copies of redirwriter.c's own payload;
* "redirreader < /tmp/redir.txt" then reads that file back through a
* REAL redirected stdin and compares it byte-for-byte against exactly
* that doubled payload. The actual pass/fail proof is entirely
* redirreader.c's own doing (its "payload-ok" needle only prints on an
* exact match) -- this thread's only job is to type the three commands
* and give the scheduler real time between them.
*/
static void redirDriverThread(void)
{
threadSleep(redirDriverInitialDelayMs);
while (currentThread()->state == threadSleeping)
halt();
kprintf("[kbd] typing shell commands for the file redirection demo\n");
jobctlTypeFlushLine();
redirTypeWriteTruncateCommand();
threadSleep(redirDriverStepSettleMs);
while (currentThread()->state == threadSleeping)
halt();
redirTypeWriteAppendCommand();
threadSleep(redirDriverStepSettleMs);
while (currentThread()->state == threadSleeping)
halt();
redirTypeReadCommand();
threadSleep(redirDriverStepSettleMs);
while (currentThread()->state == threadSleeping)
halt();
for (;;)
halt();
}
/* Digit needed only by stderrDriverThread's own three commands below --
same cross-checked-against-scancodeLower sourcing as every block above
(index 0x03 is '2', unshifted -- scancodeLower[3] == '2' in keyboard.c's
own table, no shift key involved unlike the '>'/'<' operators reused
from redirDriverThread's own scancodeMakeDot/scancodeMakeComma below). */
#define scancodeMakeTwo 0x03
/* "/tmp/err.txt" -- deliberately SHORTER than redirDriverThread's own
"/tmp/redir.txt" (12 vs 14 chars): "stderrwriter"/"stderrreader" are
already one character longer than "redirwriter"/"redirreader", and the
`2>`/`2>>` operators are one/two characters longer than `>`/`>>` -- with
the same path length as the file-redirection demo, the LONGEST typed
line here ("stderrwriter 2>> /tmp/err.txt\n", 30 bytes incl. newline)
would land right at keyboard.c's 32-byte per-thread console reader ring
buffer (consoleReaderBufferSize) with almost no margin left. A first
attempt at this demo used "/tmp/stderr.txt" (15 chars) and landed
EXACTLY at (and, for the `2>>` line, one byte OVER) that 32-byte
capacity -- ringPush (ring.c) silently drops a byte on a full buffer
with no retry, so the trailing '\n' itself was lost, and the shell's
line reader never saw a line terminator until the NEXT typed command's
bytes arrived, silently concatenating three separate typed commands
into one garbled line. Shortening the path restores the same few-bytes-
of-headroom margin redirDriverThread's own commands already prove works
(its longest line is 30 bytes incl. newline against the same 32-byte
capacity) instead of running right up against the boundary. */
static void stderrTypePath(void)
{
injectKeyPress(scancodeMakeSlash);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeM);
injectKeyPress(scancodeMakeP);
injectKeyPress(scancodeMakeSlash);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeDot);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeX);
injectKeyPress(scancodeMakeT);
}
static void stderrTypeWriterName(void)
{
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeD);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeW);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeI);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
}
static void stderrTypeReaderName(void)
{
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeD);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeA);
injectKeyPress(scancodeMakeD);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
}
static void stderrTypeWriteTruncateCommand(void)
{
stderrTypeWriterName();
injectKeyPress(scancodeMakeSpace);
injectKeyPress(scancodeMakeTwo);
injectShiftedKeyPress(scancodeMakeDot);
injectKeyPress(scancodeMakeSpace);
stderrTypePath();
injectKeyPress(scancodeMakeEnter);
}
static void stderrTypeWriteAppendCommand(void)
{
stderrTypeWriterName();
injectKeyPress(scancodeMakeSpace);
injectKeyPress(scancodeMakeTwo);
injectShiftedKeyPress(scancodeMakeDot);
injectShiftedKeyPress(scancodeMakeDot);
injectKeyPress(scancodeMakeSpace);
stderrTypePath();
injectKeyPress(scancodeMakeEnter);
}
static void stderrTypeReadCommand(void)
{
stderrTypeReaderName();
injectKeyPress(scancodeMakeSpace);
injectShiftedKeyPress(scancodeMakeComma);
injectKeyPress(scancodeMakeSpace);
stderrTypePath();
injectKeyPress(scancodeMakeEnter);
}
#define stderrDriverInitialDelayMs 5500
#define stderrDriverStepSettleMs 300
/* Letter/symbol needed only by hereDriverThread's own command below -- same
cross-checked-against-scancodeLower sourcing as every block above (index
0x23 is 'h', 0x0C is '-', both unshifted -- keyboard.c's own
scancodeLower[0x23] == 'h' and scancodeLower[0x0C] == '-'). Every other
letter the command needs (e,r,s,t,o,k) is already defined by an earlier
block above. */
#define scancodeMakeH 0x23
#define scancodeMakeHyphen 0x0C
static void hereTypeCommand(void)
{
injectKeyPress(scancodeMakeH);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeR);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeE);
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeT);
injectKeyPress(scancodeMakeSpace);
injectShiftedKeyPress(scancodeMakeComma);
injectShiftedKeyPress(scancodeMakeComma);
injectShiftedKeyPress(scancodeMakeComma);
injectKeyPress(scancodeMakeSpace);
injectKeyPress(scancodeMakeH);
injectKeyPress(scancodeMakeS);
injectKeyPress(scancodeMakeHyphen);
injectKeyPress(scancodeMakeO);
injectKeyPress(scancodeMakeK);
}
void kmain(uint32 magic, uint64 multibootInfo)