rakitzis / rc

rc shell -- independent re-implementation for Unix of the Plan 9 shell (from circa 1992)
Other
257 stars 23 forks source link

Uninsulated subshell when you return #68

Closed Nomarian closed 1 year ago

Nomarian commented 3 years ago
fn isdir { @{ cd $^*;return $status } }
isdir /

will set directory to / instead of being insulated from the command

Not only that, but when you return, it leaves you inside the subshell.

rakitzis commented 3 years ago

Crazy edge case. I will look at this when I get a chance.

borkovic commented 3 years ago

It seems that this would not happen without the return statement inside fn/@ -- is that correct?

Nomarian commented 3 years ago

Well, yeah, I've never used 9rc seriously but since it doesn't have return, you have to use exit. this makes you write the code correctly

fn isdir { @{ cd $^* >[2] /dev/null ;exit $status } }

Funnily enough, I think this might be a useful feature. create a subshell in a function and control it with other functions. its kind of dangerous but, might be nice.

Edit: Nope, scratch that, inconsistent behavior, suppose you have the script:

fn subshell {
 @{ return 0 }
}

echo hello
subshell
echo good
echo bye

and you run it

; rc subshells.brc 
hello
good
rc: read: Bad file descriptor
good
bye

but with cat

; cat subshells.brc | rc
hello
good
bye
good
bye
xyb3rt commented 1 year ago
fn foo {
    echo xxx
    return >/dev/null
    echo yyy
}
foo
xxx
^D
yyy

This leaves you in the subshell created for the redirection. Hitting Ctrl-D exits it and the parent shell continues executing the function.

rakitzis commented 1 year ago

This is an unintended side-effect of the strategy described in #62 . Best to keep this in mind while designing a fix.

xyb3rt commented 1 year ago

A possible fix for the original issue is to be more strict about where we'll allow break, continue and return. They already result in an error when outside a function. Can we also consider subshells in a function definition to be outside of the function?