feat: extend jobctl
This commit is contained in:
1 parent
0bdc393f39
commit
ed74e6df9b
1 file changed
+84
@@ -146,3 +146,87 @@ bool jobctlRunBackgroundRedirected(const char* path, const char* const* argv, in
|
||||
const char* errPath, bool errAppend,
|
||||
uint32* outPid);
|
||||
|
||||
/* Generalizes jobctlSpawnPiped for shell.c's new `cmd1 <<< TEXT | cmd2`
|
||||
pipeline syntax, the same way jobctlSpawnPiped itself generalizes
|
||||
jobctlSpawnForeground/jobctlRunBackground: spawns `path` with fd 0 wired
|
||||
to a brand-new here-string pipe (`text` plus a trailing newline, written
|
||||
and closed by THIS kernel thread before returning, exactly like
|
||||
jobctlSpawnForegroundHereString below) instead of the console, AND
|
||||
`stdoutHandle`/`joinPgid` passed straight through to jobctlSpawnPiped so
|
||||
the spawned process can simultaneously be a pipeline's first stage --
|
||||
-1/threadInvalidId for either one leaves that side at jobctlSpawnPiped's
|
||||
own plain defaults (console stdout, new group leader). shell.c's
|
||||
runPipeline uses this for a pipeline's LEFT stage when it was written
|
||||
with `<<< TEXT` instead of a plain stdin; every other here-string caller
|
||||
in this file (jobctlSpawnForegroundHereString/jobctlRunBackgroundHereString
|
||||
below) is a thin wrapper passing -1/threadInvalidId, matching
|
||||
jobctlSpawnForeground/jobctlRunBackground's own relationship to
|
||||
jobctlSpawnPiped. Returns threadInvalidId on the same load/spawn
|
||||
failures as jobctlSpawnPiped, or if the pipe table itself is exhausted
|
||||
(vfsPipeCreateHandle, maxPipes slots all in use) -- both leave nothing
|
||||
spawned. */
|
||||
uint32 jobctlSpawnPipedHereString(const char* path, const char* const* argv, int argc,
|
||||
const char* text, int stdoutHandle, uint32 joinPgid);
|
||||
|
||||
/* Same as jobctlSpawnForegroundRedirected, but for shell.c's new `NAME
|
||||
[ARGS] <<< TEXT [> OUT | >> OUT] [2> ERR | 2>> ERR]` here-string syntax
|
||||
instead of `< IN`: `text` (plus a trailing newline, matching a real
|
||||
shell's own `<<<` behavior) is fed directly into the child's fd 0
|
||||
through a real anonymous pipe (jobctlSpawnPipedHereString above) that
|
||||
THIS kernel thread itself writes and closes -- unlike jobctlApplyRedirects'
|
||||
inPath, there is no file opened at all, so `outPath`/`errPath` are still
|
||||
applied exactly as jobctlApplyRedirects already does (fd 0 is simply
|
||||
pre-wired to the here-string pipe instead of left at the console before
|
||||
that call runs). The write end is closed (real EOF, not a lingering open
|
||||
pipe) BEFORE this function ever returns, so by the time the child
|
||||
actually gets a timeslice to read its own fd 0 it sees exactly `text`
|
||||
followed by one newline followed by true end-of-file, with no
|
||||
possibility of racing the shell thread for more data that will never
|
||||
arrive. Returns threadInvalidId on the same load/spawn/redirect failures
|
||||
as jobctlSpawnForegroundRedirected, plus a pipe-table-exhaustion failure
|
||||
(vfsPipeCreateHandle, maxPipes slots all in use) -- both leave nothing
|
||||
spawned. */
|
||||
uint32 jobctlSpawnForegroundHereString(const char* path, const char* const* argv, int argc,
|
||||
const char* text, const char* outPath, bool outAppend,
|
||||
const char* errPath, bool errAppend);
|
||||
|
||||
/* Same as jobctlRunBackgroundRedirected, but with the same here-string
|
||||
stdin support as jobctlSpawnForegroundHereString above -- shell.c's
|
||||
`NAME [ARGS] <<< TEXT [> OUT | >> OUT] [2> ERR | 2>> ERR] &`. Returns
|
||||
false (touching *outPid not at all) on the same load/spawn/redirect/
|
||||
pipe-exhaustion failures as jobctlSpawnForegroundHereString. */
|
||||
bool jobctlRunBackgroundHereString(const char* path, const char* const* argv, int argc,
|
||||
const char* text, const char* outPath, bool outAppend,
|
||||
const char* errPath, bool errAppend,
|
||||
uint32* outPid);
|
||||
|
||||
/* Runs `path` to completion with its stdout wired to a real pipe THIS
|
||||
kernel thread reads back as a string -- shell.c's new `$(cmd)` command
|
||||
substitution, the mirror image of jobctlSpawnForegroundHereString's
|
||||
"write a fixed string into the child's stdin" above. stdin is left at
|
||||
its plain default (never redirected), and the terminal is never granted
|
||||
to the child (unlike every foreground job above) -- command substitution
|
||||
is not itself "the" foreground job, only a synchronous helper run while
|
||||
building one. Joins the child FIRST, then drains its captured stdout --
|
||||
not "read until EOF, then join": this kernel only ever releases a dead
|
||||
thread's own fds (reclaimOpenFds, sched.c) from inside threadReap
|
||||
(threadJoin's last step), never at threadExit/threadKill itself, so
|
||||
reading first would block forever waiting for an end-of-file that only
|
||||
the very threadJoin call coming after it could ever produce. Joining
|
||||
first instead means `path`'s own combined stdout must fit within one
|
||||
pipe buffer's worth (pipeBufferSize, pipe.h) without ever blocking on
|
||||
free space while it runs -- the same margin jobctlSpawnPipedHereString
|
||||
already relies on for a here-string write, applied here to a captured
|
||||
read instead -- an honestly-scoped limit on how chatty a substituted
|
||||
command may be, not a silent hang for anything that stays under it.
|
||||
Copies at most outCap-1 captured bytes into outBuf (NUL-terminated,
|
||||
truncating silently like every other fixed-capacity buffer in this
|
||||
kernel), draining and discarding anything beyond that rather than
|
||||
leaving it sitting in the pipe. *outStatus receives the child's real
|
||||
exit code. Returns false, touching neither outBuf nor *outStatus, on
|
||||
the same load/spawn/pipe-exhaustion failures as jobctlSpawnPiped/
|
||||
vfsPipeCreateHandle. */
|
||||
bool jobctlCaptureOutput(const char* path, const char* const* argv, int argc,
|
||||
char* outBuf, int outCap, int64* outStatus);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user