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,
|
const char* errPath, bool errAppend,
|
||||||
uint32* outPid);
|
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