The shim steps past a PATH shim of somebody else's that hands the command back to it, rather than looping through it - #193
Conversation
…mand back to it, rather than looping through it The shim finds the real command by walking PATH past its own file and past any link that lands on another uphold. A third kind of file is neither: a shim that belongs to somebody else and resolves the command the same way, by walking PATH. mise installs one named for every tool it has heard of, a link to a binary called `mise`, and it walks PATH skipping only its own directory. With that directory ahead of the shim's, the walk returned it as the real `gh` and exec'd it, mise found the uphold link first and exec'd that, and every arrival was a fresh invocation: nothing in the loop was an uphold probe, so `UPHOLD_SHIM_INNER` was never set and its limit never tripped. Each round ran the checks again, and the alias probe each round made spawned the same loop under itself, which is where the twenty-nine thousand `gh alias list` processes came from. The exec of the real command is now marked as well. `UPHOLD_SHIM_HANDED` carries the shim's own pid, the command's name, and the file identities the walk has already handed that command to. The pid is the key because it is what the loop repeats and a genuine nested use cannot: an exec keeps the pid, so the shim, the foreign shim and the shim again are one process, while a hook that the real command runs, which runs the command again, is a fork and arrives under a pid of its own and is judged like any other invocation. The name is part of the key because a wrapper exec'd as `gh` that execs `git` keeps the pid too, and that `git` has not been checked. An invocation that carries its own pid under its own name is the hand-off having come back around: it is handed straight through rather than checked twice, and the walk it makes steps past every identity the marker lists, printing one line on stderr with the path it stepped past so the extra hop is not read as a slow gate. Nothing is named, so the next shim manager needs no entry. The alias probe ran the resolved path directly with no marker, and the resolved path can be the foreign shim, which resolves the name again. It is marked `UPHOLD_SHIM_INNER` through `inner_tool` like every other probe, which now takes a path as well as a name. Measured against the installed mise shim with `PATH=<link dir>: ~/.local/share/mise/shims:/usr/bin`: `timeout 20 gh --version` was killed at exit 124 under the released binary, and returns the version in about fifty milliseconds under this one, with the notice naming `~/.local/share/mise/shims/gh`. mise passes the environment and argv through intact and execs rather than forks, so the marker and the pid both survive the hop. Two hand-off tests reproduce the shape with a PATH-walking stub ahead of the real command and the uphold link ahead of both, under the process group and timeout the suite already uses: one shows the real command runs once and the notice is printed, where the released binary ran until `timeout` killed it; the other shows a nested invocation from the real command is refused by the rule rather than handed through as the loop's second arrival. Closes #188
|
Warning Review limit reachedNext included review available in 48 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (77.90%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #193 +/- ##
==========================================
- Coverage 93.68% 93.61% -0.08%
==========================================
Files 44 44
Lines 16934 17013 +79
==========================================
+ Hits 15865 15927 +62
- Misses 1069 1086 +17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The shim finds the real command by walking PATH past its own file and
past any link that lands on another uphold. A third kind of file is
neither: a shim that belongs to somebody else and resolves the command
the same way, by walking PATH. mise installs one named for every tool
it has heard of, a link to a binary called
mise, and it walks PATHskipping only its own directory. With that directory ahead of the
shim's, the walk returned it as the real
ghand exec'd it, mise foundthe uphold link first and exec'd that, and every arrival was a fresh
invocation: nothing in the loop was an uphold probe, so
UPHOLD_SHIM_INNERwas never set and its limit never tripped. Eachround ran the checks again, and the alias probe each round made spawned
the same loop under itself, which is where the twenty-nine thousand
gh alias listprocesses came from.The exec of the real command is now marked as well.
UPHOLD_SHIM_HANDEDcarries the shim's own pid, the command's name, and the file identities
the walk has already handed that command to. The pid is the key because
it is what the loop repeats and a genuine nested use cannot: an exec
keeps the pid, so the shim, the foreign shim and the shim again are one
process, while a hook that the real command runs, which runs the
command again, is a fork and arrives under a pid of its own and is
judged like any other invocation. The name is part of the key because a
wrapper exec'd as
ghthat execsgitkeeps the pid too, and thatgithas not been checked. An invocation that carries its own pidunder its own name is the hand-off having come back around: it is
handed straight through rather than checked twice, and the walk it
makes steps past every identity the marker lists, printing one line on
stderr with the path it stepped past so the extra hop is not read as a
slow gate. Nothing is named, so the next shim manager needs no entry.
The alias probe ran the resolved path directly with no marker, and the
resolved path can be the foreign shim, which resolves the name again.
It is marked
UPHOLD_SHIM_INNERthroughinner_toollike every otherprobe, which now takes a path as well as a name.
Measured against the installed mise shim with
PATH=<link dir>: ~/.local/share/mise/shims:/usr/bin:timeout 20 gh --versionwaskilled at exit 124 under the released binary, and returns the version
in about fifty milliseconds under this one, with the notice naming
~/.local/share/mise/shims/gh. mise passes the environment and argvthrough intact and execs rather than forks, so the marker and the pid
both survive the hop.
Two hand-off tests reproduce the shape with a PATH-walking stub ahead of
the real command and the uphold link ahead of both, under the process
group and timeout the suite already uses: one shows the real command
runs once and the notice is printed, where the released binary ran
until
timeoutkilled it; the other shows a nested invocation from thereal command is refused by the rule rather than handed through as the
loop's second arrival.
Closes #188