cmd,proc,terminal,debugger: Support default file descriptor redirects

Adds features to support default file descriptor redirects for the
target process:

1. A new command line flag '--redirect' and '-r' are added to specify
   file redirects for the target process
2. New syntax is added to the 'restart' command to specify file
   redirects.
3. Interactive instances will check if stdin/stdout and stderr are
   terminals and print a helpful error message if they aren't.
This commit is contained in:
aarzilli
2020-08-21 16:14:02 +02:00
committed by Alessandro Arzilli
parent f90134eb4d
commit 7555d1c063
43 changed files with 766 additions and 271 deletions

View File

@ -1138,3 +1138,50 @@ func TestPrintCastToInterface(t *testing.T) {
t.Logf("%q", out)
})
}
func TestParseNewArgv(t *testing.T) {
testCases := []struct {
in string
tgtargs string
tgtredir string
tgterr string
}{
{"-noargs", "", " | | ", ""},
{"-noargs arg1", "", "", "too many arguments to restart"},
{"arg1 arg2", "arg1 | arg2", " | | ", ""},
{"arg1 arg2 <input.txt", "arg1 | arg2", "input.txt | | ", ""},
{"arg1 arg2 < input.txt", "arg1 | arg2", "input.txt | | ", ""},
{"<input.txt", "", "input.txt | | ", ""},
{"< input.txt", "", "input.txt | | ", ""},
{"arg1 < input.txt > output.txt 2> error.txt", "arg1", "input.txt | output.txt | error.txt", ""},
{"< input.txt > output.txt 2> error.txt", "", "input.txt | output.txt | error.txt", ""},
{"arg1 <input.txt >output.txt 2>error.txt", "arg1", "input.txt | output.txt | error.txt", ""},
{"<input.txt >output.txt 2>error.txt", "", "input.txt | output.txt | error.txt", ""},
{"<input.txt <input2.txt", "", "", "redirect error: stdin redirected twice"},
}
for _, tc := range testCases {
resetArgs, newArgv, newRedirects, err := parseNewArgv(tc.in)
t.Logf("%q -> %q %q %v\n", tc.in, newArgv, newRedirects, err)
if tc.tgterr != "" {
if err == nil {
t.Errorf("Expected error %q, got no error", tc.tgterr)
} else if errstr := err.Error(); errstr != tc.tgterr {
t.Errorf("Expected error %q, got error %q", tc.tgterr, errstr)
}
} else {
if !resetArgs {
t.Errorf("parse error, resetArgs is false")
continue
}
argvstr := strings.Join(newArgv, " | ")
if argvstr != tc.tgtargs {
t.Errorf("Expected new arguments %q, got %q", tc.tgtargs, argvstr)
}
redirstr := strings.Join(newRedirects[:], " | ")
if redirstr != tc.tgtredir {
t.Errorf("Expected new redirects %q, got %q", tc.tgtredir, redirstr)
}
}
}
}