fix bg/fg implementations

This commit is contained in:
Aidan 2020-06-28 17:00:44 -07:00
parent b5c7162555
commit 37c56cb322
No known key found for this signature in database
GPG key ID: 327711E983899316

View file

@ -30,6 +30,8 @@ import (
var bgProcs = make([]*exec.Cmd, 0) var bgProcs = make([]*exec.Cmd, 0)
var LastExitCode int var LastExitCode int
var sigs = []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGTSTP, syscall.SIGTTIN, syscall.SIGTTOU, syscall.SIGCONT}
func call(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { func call(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
if in == nil { if in == nil {
@ -63,7 +65,7 @@ func call(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
signalChan := make(chan os.Signal, 2) signalChan := make(chan os.Signal, 2)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) signal.Notify(signalChan, sigs...)
go func() { go func() {
sig := <-signalChan sig := <-signalChan
cmd.Process.Signal(sig) cmd.Process.Signal(sig)
@ -71,7 +73,7 @@ func call(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
err = cmd.Run() err = cmd.Run()
close(signalChan) close(signalChan)
signal.Reset(os.Interrupt, syscall.SIGTERM) signal.Reset(sigs...)
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok { if exitError, ok := err.(*exec.ExitError); ok {
LastExitCode = exitError.ExitCode() LastExitCode = exitError.ExitCode()
@ -113,7 +115,12 @@ func bgcall(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
bgProcs = append(bgProcs, cmd) bgProcs = append(bgProcs, cmd)
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Start() cmd.Start()
cmd.Process.Signal(syscall.SIGTSTP)
return nil return nil
} }
@ -125,19 +132,17 @@ func fg(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
cmd := bgProcs[0] cmd := bgProcs[0]
bgProcs = bgProcs[1:] bgProcs = bgProcs[1:]
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
signalChan := make(chan os.Signal, 2) signalChan := make(chan os.Signal, 2)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) signal.Notify(signalChan, sigs...)
go func() { go func() {
sig := <-signalChan sig := <-signalChan
cmd.Process.Signal(sig) cmd.Process.Signal(sig)
}() }()
cmd.Process.Signal(syscall.SIGCONT)
err := cmd.Wait() err := cmd.Wait()
close(signalChan) close(signalChan)
signal.Reset(os.Interrupt, syscall.SIGTERM) signal.Reset(sigs...)
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok { if exitError, ok := err.(*exec.ExitError); ok {
LastExitCode = exitError.ExitCode() LastExitCode = exitError.ExitCode()
@ -182,7 +187,7 @@ func read_cmd(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
signalChan := make(chan os.Signal, 2) signalChan := make(chan os.Signal, 2)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) signal.Notify(signalChan, sigs...)
go func() { go func() {
sig := <-signalChan sig := <-signalChan
cmd.Process.Signal(sig) cmd.Process.Signal(sig)
@ -190,7 +195,7 @@ func read_cmd(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
err = cmd.Run() err = cmd.Run()
close(signalChan) close(signalChan)
signal.Reset(os.Interrupt, syscall.SIGTERM) signal.Reset(sigs...)
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok { if exitError, ok := err.(*exec.ExitError); ok {
LastExitCode = exitError.ExitCode() LastExitCode = exitError.ExitCode()