feat: extend kmain with pipelineDriverThread and redirTypePath
This commit is contained in:
1 parent
750354f099
commit
a59ae7a9f8
1 file changed
+173
+173
@@ -677,6 +677,179 @@ static void pipelineTypeCommand(void)
|
|||||||
injectKeyPress(scancodeMakeSpace);
|
injectKeyPress(scancodeMakeSpace);
|
||||||
injectShiftedKeyPress(scancodeMakeBackslash);
|
injectShiftedKeyPress(scancodeMakeBackslash);
|
||||||
injectKeyPress(scancodeMakeSpace);
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeS);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeN);
|
||||||
|
injectKeyPress(scancodeMakeK);
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The live ring-3 proof for shell.c's new `cmd1 | cmd2` pipeline syntax
|
||||||
|
* (jobctl.h's jobctlSpawnPiped/jobctlWaitPipelineStages do the actual
|
||||||
|
* fd-baking and multi-wait work): types "pipesrc | pipesink" at the real interactive
|
||||||
|
* shell through the same injected-keystroke mechanism jobctlDriverThread
|
||||||
|
* above already uses, well after that thread's own demo has fully
|
||||||
|
* finished with the shell's shared line buffer (both threads' typed
|
||||||
|
* characters go through the exact same broadcast keyboardHandleScancode
|
||||||
|
* path, so they cannot safely interleave -- pipelineDriverInitialDelayMs
|
||||||
|
* is chosen with a comfortable margin over jobctlDriverThread's own total
|
||||||
|
* ~1550ms explicit sleep budget above to guarantee that). The actual
|
||||||
|
* pass/fail proof is entirely pipesink.c's own doing (its "payload-ok"
|
||||||
|
* needle only prints once it has verified, byte for byte, the exact
|
||||||
|
* payload pipesrc.c wrote through the real pipe) -- this thread's only job
|
||||||
|
* is to type the command and give the two spawned processes (neither of
|
||||||
|
* which ever sleeps or waits on a real timer, unlike alarmtest/polltest) a
|
||||||
|
* comfortable amount of real scheduled time to run to completion.
|
||||||
|
*/
|
||||||
|
static void pipelineDriverThread(void)
|
||||||
|
{
|
||||||
|
threadSleep(pipelineDriverInitialDelayMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
kprintf("[kbd] typing shell command for the pipeline demo\n");
|
||||||
|
jobctlTypeFlushLine();
|
||||||
|
pipelineTypeCommand();
|
||||||
|
|
||||||
|
threadSleep(pipelineDriverSettleMs);
|
||||||
|
while (currentThread()->state == threadSleeping)
|
||||||
|
halt();
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Additional letters/symbols needed only by redirDriverThread's own three
|
||||||
|
commands below -- same cross-checked-against-scancodeLower sourcing as
|
||||||
|
every block above (index 0x20 is 'd', 0x11 is 'w', 0x32 is 'm', 0x2D is
|
||||||
|
'x', 0x34 is '.', 0x35 is '/', 0x1E is 'a', 0x33 is ',' -- '>' is
|
||||||
|
shift+'.' and '<' is shift+',' on a real US keyboard, scancodeUpper's
|
||||||
|
own mapping for those two indices, the same way scancodeMakeSeven is
|
||||||
|
shifted into '&' and scancodeMakeBackslash into '|' above). */
|
||||||
|
#define scancodeMakeD 0x20
|
||||||
|
#define scancodeMakeW 0x11
|
||||||
|
#define scancodeMakeM 0x32
|
||||||
|
#define scancodeMakeX 0x2D
|
||||||
|
#define scancodeMakeDot 0x34
|
||||||
|
#define scancodeMakeSlash 0x35
|
||||||
|
#define scancodeMakeA 0x1E
|
||||||
|
#define scancodeMakeComma 0x33
|
||||||
|
|
||||||
|
static void redirTypePath(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeSlash);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeM);
|
||||||
|
injectKeyPress(scancodeMakeP);
|
||||||
|
injectKeyPress(scancodeMakeSlash);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeD);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeDot);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeX);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirTypeWriterName(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeD);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeW);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeT);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirTypeReaderName(void)
|
||||||
|
{
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeD);
|
||||||
|
injectKeyPress(scancodeMakeI);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeA);
|
||||||
|
injectKeyPress(scancodeMakeD);
|
||||||
|
injectKeyPress(scancodeMakeE);
|
||||||
|
injectKeyPress(scancodeMakeR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirTypeWriteTruncateCommand(void)
|
||||||
|
{
|
||||||
|
redirTypeWriterName();
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeDot);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
redirTypePath();
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirTypeWriteAppendCommand(void)
|
||||||
|
{
|
||||||
|
redirTypeWriterName();
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeDot);
|
||||||
|
injectShiftedKeyPress(scancodeMakeDot);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
redirTypePath();
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirTypeReadCommand(void)
|
||||||
|
{
|
||||||
|
redirTypeReaderName();
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
injectShiftedKeyPress(scancodeMakeComma);
|
||||||
|
injectKeyPress(scancodeMakeSpace);
|
||||||
|
redirTypePath();
|
||||||
|
injectKeyPress(scancodeMakeEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define redirDriverInitialDelayMs 3600
|
||||||
|
#define redirDriverStepSettleMs 300
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The live ring-3 proof for shell.c's new `cmd < IN` / `cmd > OUT` /
|
||||||
|
* `cmd >> OUT` file redirection (jobctlApplyRedirects/
|
||||||
|
* jobctlSpawnForegroundRedirected, jobctl.h): types three commands, one at
|
||||||
|
* a time, at the real interactive shell through the same injected-
|
||||||
|
* keystroke mechanism jobctlDriverThread/pipelineDriverThread above
|
||||||
|
* already use -- redirDriverInitialDelayMs gives pipelineDriverThread's
|
||||||
|
* own total ~3000ms budget (2500ms initial + 500ms settle) a comfortable
|
||||||
|
* margin before this thread ever touches the same shared keyboard buffer.
|
||||||
|
*
|
||||||
|
* Unlike pipelineDriverThread's single typed line, this is THREE separate
|
||||||
|
* commands, each one run to completion in the FOREGROUND (the shell
|
||||||
|
* genuinely blocks inside jobctlWaitForeground for each), so
|
||||||
|
* redirDriverStepSettleMs between them is not just cosmetic pacing --
|
||||||
|
* typing the next command's keystrokes while the shell is still mid-line
|
||||||
|
* on the previous one would queue them in the same 32-byte console-reader
|
||||||
|
* ring buffer (keyboard.c) that a real user's own typing shares, with no
|
||||||
|
* guarantee they would not overflow it or be echoed against the wrong
|
||||||
|
* still-open line. Each settle is comfortably longer than
|
||||||
|
* redirwriter/redirreader's own trivial one-shot work (a single write or
|
||||||
|
* read-to-EOF, neither ever sleeps or blocks on a timer) needs to spawn,
|
||||||
|
* run, exit, and be reaped, the same safety margin philosophy every
|
||||||
|
* other injected multi-step demo above already uses.
|
||||||
|
*
|
||||||
|
* "redirwriter > /tmp/redir.txt" (create/truncate) followed by
|
||||||
|
* "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
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmain(uint32 magic, uint64 multibootInfo)
|
void kmain(uint32 magic, uint64 multibootInfo)
|
||||||
|
|||||||
Reference in new issue
Block a user