Development record
The kill-by-search reading loses a pipe that feeds a group or a command string from outside it. A pipe INTO a brace or paren group feeds every command in the group, but the tokenizer hands it only to the commands before the first separator inside, so a process search piped into a group whose later command is an xargs kill (after a sleep, a read, or an and-list) allows silently while the one-command group blocks. In the same class, payloadInput hands a command string only its running shell's pipe, so a here-string or a process-substitution redirect carrying a search into a shell string whose xargs kills allows, while the same redirect into a plain xargs kill blocks. Found by review-drainG2 (tokenize.go group open/close, payload.go payloadInput).
The kill-by-search reading loses a pipe that feeds a group or a command string from outside it. A pipe INTO a brace or paren group feeds every command in the group, but the tokenizer hands it only to the commands before the first separator inside, so a process search piped into a group whose later command is an xargs kill (after a sleep, a read, or an and-list) allows silently while the one-command group blocks. In the same class, payloadInput hands a command string only its running shell's pipe, so a here-string or a process-substitution redirect carrying a search into a shell string whose xargs kills allows, while the same redirect into a plain xargs kill blocks. Found by review-drainG2 (tokenize.go group open/close, payload.go payloadInput).
Grounds
- pursued: every group and redirect spelling the review listed blocks as kill-by-search while every NO-LEAK probe of both reviews allows; a group- or redirect-fed kill that allows, or a NO-LEAK probe that blocks, would show it wrong
Frontmatter
| id | iss-2609270028388291 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2609270028388291-the-kill-by-search-reading-loses-a-pipe.md
open on GitHub ↗ · commit history ↗
mentions4
- dcn-26092700000000022026-09-27 — A pipe into a group and a redirect into a shell string reach every command there, and the reading keeps two over-blocks, recorded so they are not mistaken for defects (lane fix3-drainG, autonomous run A, on iss-2609270028388291 from review-drainG2). A pipe into a `{ … }` or `( … )` group is the standard input of every command in it, so each command emitted inside the group reads it, not only those before the group's first separator; a shell in the group reads it as a stream too. A command in a group is read as handed its group's input even when a pipe inside the group hands it another, because the command before that pipe may pass the group's input on (`cat`), and which commands do is not modelled; so `pgrep make | { true; echo 4242 | { xargs kill; }; }` blocks. The runs of the open groups are held as one covering run, which keeps each command's reading constant however deep groups nest, at the cost of also counting a search that sits inside an outer piped group before an inner one opens. A shell passes its standard input to the commands of its string, and a here-string or a process substitution redirected into the shell is that input, as a pipe is; the `<` that redirects a process substitution is not kept by the tokenizer, so a process substitution handed to the shell as an operand is read as its input as well, which is what `sh -c 'xargs kill < "$1"' _ <(pgrep make)` does with it.
- dcn-26092700000000052026-09-27 — A pipe into a group and a redirect into a shell string reach every command there, and the reading keeps two over-blocks, recorded so they are not mistaken for defects (lane fix3-drainG, autonomous run A, on iss-2609270028388291 from review-drainG2). A pipe into a `{ … }` or `( … )` group is the standard input of every command in it, so each command emitted inside the group reads it, not only those before the group's first separator; a shell in the group reads it as a stream too. A command in a group is read as handed its group's input even when a pipe inside the group hands it another, because the command before that pipe may pass the group's input on (`cat`), and which commands do is not modelled; so `pgrep make | { true; echo 4242 | { xargs kill; }; }` blocks. The runs of the open groups are held as one covering run, which keeps each command's reading constant however deep groups nest, at the cost of also counting a search that sits inside an outer piped group before an inner one opens. A shell passes its standard input to the commands of its string, and a here-string or a process substitution redirected into the shell is that input, as a pipe is; the `<` that redirects a process substitution is not kept by the tokenizer, so a process substitution handed to the shell as an operand is read as its input as well, which is what `sh -c 'xargs kill < "$1"' _ <(pgrep make)` does with it.
- iss-2609270036253187Two more paths by which a process search's output reaches a kill are not read by kill-by-search: an unquoted here-document whose body holds a command substitution, redirected into an xargs kill (a here-string of the same substitution blocks), and a command substitution inside a command that reads a pipe, which inherits that pipe as its standard input (an xargs kill in the substitution reads the search piped into its command). A third, a search handed to a shell string as a positional parameter the string's kill reads, is not read either: it is a pid carried through a variable, the half [dcn-2609250000000016](../../decisions/dcn-2609250000000016-correction-to-the-two-entries-above-on.md) (c) defers with iss-2609251824244354, unless it is read the way xargs's input to a string is ([dcn-2609270000000001](../../decisions/dcn-2609270000000001-the-kill-by-search-reading-follows-a.md)), which is a call for the next guard lane. Found while fixing iss-2609270028388291.
- iss-2609270036259517A stream piped into a brace or paren group reaches only the group's commands before its first separator as a stream, so a shell that reads its script from standard input placed after a separator inside a piped group allows under interpreter-reads-stream, while the same shell as the group's first command blocks. Same root as iss-2609270028388291 (the group's input is not handed to every command in it), found while fixing it.