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(scancodeMakeP);
|
||||||
injectKeyPress(scancodeMakeSlash);
|
injectKeyPress(scancodeMakeSlash);
|
||||||
injectKeyPress(scancodeMakeG);
|
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)
|
void kmain(uint32 magic, uint64 multibootInfo)
|
||||||
|
|||||||
Reference in new issue
Block a user