Skip to content

Commit

Permalink
Wire up ctx through system() (#119)
Browse files Browse the repository at this point in the history
This wires up ctx (for when using ExecuteContext) through `system()` and
simplifies the error handling in the `system()` implementation a bit.
  • Loading branch information
benhoyt committed May 18, 2022
1 parent 5f3b124 commit a9bdabf
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 17 deletions.
7 changes: 5 additions & 2 deletions interp/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,11 @@ func (p *interp) execShell(code string) *exec.Cmd {
executable := p.shellCommand[0]
args := p.shellCommand[1:]
args = append(args, code)
cmd := exec.Command(executable, args...)
return cmd
if p.checkCtx {
return exec.CommandContext(p.ctx, executable, args...)
} else {
return exec.Command(executable, args...)
}
}

// Get input Scanner to use for "getline" based on file name
Expand Down
2 changes: 1 addition & 1 deletion interp/newexecute.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (p *Interpreter) ResetRand() {
// system() won't be interrupted.
func (p *Interpreter) ExecuteContext(ctx context.Context, config *Config) (int, error) {
p.interp.resetCore()
p.interp.checkCtx = ctx != context.Background()
p.interp.checkCtx = ctx != context.Background() && ctx != context.TODO()
p.interp.ctx = ctx
p.interp.ctxDone = ctx.Done()
p.interp.ctxOps = 0
Expand Down
10 changes: 10 additions & 0 deletions interp/newexecute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ func TestExecuteContextCancel(t *testing.T) {
}
}

func TestExecuteContextSystemTimeout(t *testing.T) {
interpreter := newInterp(t, `BEGIN { print system("sleep 4") }`)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
defer cancel()
_, err := interpreter.ExecuteContext(ctx, nil)
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("expected DeadlineExceeded error, got: %v", err)
}
}

func newInterp(t *testing.T, src string) *interp.Interpreter {
t.Helper()
prog, err := parser.ParseProgram([]byte(src), nil)
Expand Down
23 changes: 9 additions & 14 deletions interp/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,22 +1071,17 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
cmd.Stdout = p.output
cmd.Stderr = p.errorOutput
_ = p.flushAll() // ensure synchronization
err := cmd.Start()
var ret float64
err := cmd.Run()
ret := 0.0
if err != nil {
p.printErrorf("%s\n", err)
ret = -1
} else {
err = cmd.Wait()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
ret = float64(exitErr.ProcessState.ExitCode())
} else {
p.printErrorf("unexpected error running command %q: %v\n", cmdline, err)
ret = -1
}
if p.checkCtx && p.ctx.Err() != nil {
return p.ctx.Err()
}
if exitErr, ok := err.(*exec.ExitError); ok {
ret = float64(exitErr.ProcessState.ExitCode())
} else {
ret = 0
p.printErrorf("%v\n", err)
ret = -1
}
}
p.replaceTop(num(ret))
Expand Down

0 comments on commit a9bdabf

Please sign in to comment.