feat: extend kmain with globTypeGlobcatCommand and globDriverThread
This commit is contained in:
1 parent
fbd54b7c31
commit
68907b39ec
1 file changed
+173
+173
@@ -1542,6 +1542,179 @@ static void globTypeEchoSkipCommand(void)
|
||||
injectKeyPress(scancodeMakeP);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeMakeG);
|
||||
injectKeyPress(scancodeMakeD);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeCPressMake);
|
||||
injectKeyPress(scancodeMakeDot);
|
||||
injectKeyPress(scancodeMakeL);
|
||||
injectKeyPress(scancodeMakeO);
|
||||
injectKeyPress(scancodeMakeG);
|
||||
injectKeyPress(scancodeMakeEnter);
|
||||
}
|
||||
|
||||
static void globTypeGlobcatCommand(void)
|
||||
{
|
||||
injectKeyPress(scancodeMakeG);
|
||||
injectKeyPress(scancodeMakeL);
|
||||
injectKeyPress(scancodeMakeO);
|
||||
injectKeyPress(scancodeMakeB);
|
||||
injectKeyPress(scancodeCPressMake);
|
||||
injectKeyPress(scancodeMakeA);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeSpace);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeM);
|
||||
injectKeyPress(scancodeMakeP);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeMakeG);
|
||||
injectKeyPress(scancodeMakeD);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectShiftedKeyPress(scancodeMakeEight);
|
||||
injectKeyPress(scancodeMakeDot);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeX);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeEnter);
|
||||
}
|
||||
|
||||
/* 15000ms clears envDriverThread's own total budget (12500 initial +
|
||||
3*400 settle = 13700ms, above its own real spawn/run/reap time), the same
|
||||
"next demo's initial delay clears the previous demo's total budget"
|
||||
convention every driver thread above already establishes. Settle is
|
||||
300ms per step, matching redirDriverThread's own choice for similarly
|
||||
trivial commands (a single mkdir or a single short file write, none of
|
||||
which ever sleeps or blocks on a timer) -- comfortable headroom to let
|
||||
the shell finish running each FOREGROUND command before the next one's
|
||||
keystrokes are typed into the same shared 32-byte console-reader ring
|
||||
buffer (keyboard.c). */
|
||||
#define globDriverInitialDelayMs 15000
|
||||
#define globDriverStepSettleMs 300
|
||||
|
||||
/*
|
||||
* Live ring-3 proof for shell.c's new wildcard glob expansion
|
||||
* (shellExpandGlobs, shellGlobMatch/shellTokenHasGlob/shellSplitGlobToken):
|
||||
* types four setup commands at the real interactive shell (mkdir, then
|
||||
* three "echo X > /tmp/gd/NAME" writes -- two matching *.txt, one
|
||||
* deliberately a *.log that must NOT match), then "globcat /tmp/gd/ *.txt".
|
||||
* shell.c resolves that last argv token against the real tmpfs directory
|
||||
* /tmp/gd (vfsChild/vfsNext, the exact traversal the `ls` builtin already
|
||||
* uses) and replaces it with however many real paths matched BEFORE
|
||||
* globcat.c (loaded on demand, like envprint/hcat/pipecat above) ever runs
|
||||
* a single instruction -- so globcat.c's own argc/argv and each file's
|
||||
* content are the actual proof: exactly 2 files (never 3 -- c.log must be
|
||||
* filtered out by pattern, not just "everything in the directory"), each
|
||||
* one's real resolved path and its own distinct content. The actual
|
||||
* pass/fail proof is entirely globcat.c's own doing; this thread's only job
|
||||
* is to type the five commands and give the scheduler real time between
|
||||
* them.
|
||||
*/
|
||||
static void globDriverThread(void)
|
||||
{
|
||||
threadSleep(globDriverInitialDelayMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
kprintf("[kbd] typing shell commands for the wildcard glob demo\n");
|
||||
jobctlTypeFlushLine();
|
||||
|
||||
globTypeMkdirCommand();
|
||||
threadSleep(globDriverStepSettleMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
globTypeEchoACommand();
|
||||
threadSleep(globDriverStepSettleMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
globTypeEchoBCommand();
|
||||
threadSleep(globDriverStepSettleMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
globTypeEchoSkipCommand();
|
||||
threadSleep(globDriverStepSettleMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
globTypeGlobcatCommand();
|
||||
threadSleep(globDriverStepSettleMs);
|
||||
while (currentThread()->state == threadSleeping)
|
||||
halt();
|
||||
|
||||
for (;;)
|
||||
halt();
|
||||
}
|
||||
|
||||
/* 19500ms clears globDriverThread's own total budget (15000 initial +
|
||||
5*300 settle = 16500ms, plus the real time globcat.c itself needs to
|
||||
spawn/run/read two files/print/exit after that last keystroke) -- the
|
||||
same "next demo's initial delay clears the previous demo's total budget
|
||||
with margin" convention every driver thread above establishes. A single
|
||||
settle step is enough -- see the file comment on lsDriverThread below
|
||||
for why this demo types only ONE command, unlike every prior driver
|
||||
thread's multi-command setup sequence: tools/ci-test.sh's QEMU timeout
|
||||
is a fixed 25 REAL (host wall-clock) seconds shared by the entire boot,
|
||||
and this is already the last of well over a dozen shell-driven demos
|
||||
stacked at increasing absolute timestamps in that same fixed window, so
|
||||
minimizing this demo's own keystroke count directly buys back margin
|
||||
for the whole chain instead of spending it. */
|
||||
#define lsDriverInitialDelayMs 19500
|
||||
#define lsDriverStepSettleMs 300
|
||||
|
||||
static void lsTypeLongListCommand(void)
|
||||
{
|
||||
injectKeyPress(scancodeMakeL);
|
||||
injectKeyPress(scancodeMakeS);
|
||||
injectKeyPress(scancodeMakeSpace);
|
||||
injectKeyPress(scancodeMakeHyphen);
|
||||
injectKeyPress(scancodeMakeL);
|
||||
injectKeyPress(scancodeMakeSpace);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeMakeM);
|
||||
injectKeyPress(scancodeMakeN);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeSlash);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeI);
|
||||
injectKeyPress(scancodeMakeM);
|
||||
injectKeyPress(scancodeMakeE);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeE);
|
||||
injectKeyPress(scancodeMakeS);
|
||||
injectKeyPress(scancodeMakeT);
|
||||
injectKeyPress(scancodeMakeEnter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Live proof for shell.c's new generalized `ls`/`ls -l` (listDir/
|
||||
* printLsEntry): types `ls -l /mnt/timetest` at the real interactive
|
||||
* shell. `/mnt/timetest` is deliberately NOT created by this demo --
|
||||
* timetest.c (FALA 39, boot-time synchronous, long finished by the time
|
||||
* any shell-driven demo runs) already left it behind with two real files
|
||||
* (data.txt, and alias.txt, a hardlink sharing the same inode/mtime) once
|
||||
* `timetest: PASS` prints, so this demo needs exactly ONE typed command
|
||||
* instead of the usual "mkdir + write setup, then the command under test"
|
||||
* shape every earlier shell demo used -- both a deliberate budget saving
|
||||
* (see lsDriverInitialDelayMs's own comment) and, incidentally, a second
|
||||
* independent proof that `ls -l`'s real stat data (size, mtime) matches
|
||||
* what timetest.c's own syscall-level userStat already established for
|
||||
* the exact same on-disk inode, through a completely different code path
|
||||
* (the interactive shell builtin instead of a ring-3 program's syscalls).
|
||||
* `/mnt`, not `/tmp`, is the whole point -- the OLD `ls` only ever
|
||||
* understood the tmpfs VfsNode tree via vfsLookup/vfsChild/vfsNext, so any
|
||||
* `/mnt` directory silently reported "no such path" no matter what it
|
||||
* actually held (fstest.c/linktest.c could only ever prove SFS directory
|
||||
* listing through a raw userGetdents syscall, never through this
|
||||
* builtin). The needles tools/ci-test.sh checks for are the deterministic
|
||||
* type+size+name prefix of each `-l` output line ("f <N> data.txt " and
|
||||
* "f <N> alias.txt ", both files' real on-disk size) plus a "20" year-
|
||||
* prefix right after one of them, proving a real mtime got formatted and
|
||||
* printed (sfs.h's on-disk timestamp, rtc.c's new rtcCivilFromEpoch)
|
||||
* rather than silently falling back to the "no timestamp" dash this same
|
||||
* code path prints for tmpfs/dev entries.
|
||||
*/
|
||||
}
|
||||
|
||||
void kmain(uint32 magic, uint64 multibootInfo)
|
||||
|
||||
Reference in new issue
Block a user