fixed background process execution

This commit is contained in:
Aidan 2020-07-23 19:54:36 -07:00
parent f34c9070c8
commit 5d538d4a0b
No known key found for this signature in database
GPG key ID: 327711E983899316
3 changed files with 43 additions and 35 deletions

View file

@ -22,7 +22,6 @@ import (
"io"
"fmt"
"bytes"
"errors"
"os/exec"
"context"
"syscall"
@ -68,7 +67,7 @@ var LastExitCode int
func signalHandler() {
for {
<- sigChan
log.Log(log.INFO,
log.Log(log.DEBUG,
"caught SIGINT",
"jobctl")
@ -78,27 +77,6 @@ func signalHandler() {
}
}
func waitHandler() {
for {
w := <- waitChan
exit := 0
if w != nil {
log.Log(log.ERR,
"Child returned: " + w.Error(),
"jobctl")
// something outrageous
exit = -1024
var e *exec.ExitError
if errors.As(w, &e) {
exit = e.ExitCode()
}
LastExitCode = exit
}
}
}
// for some reason not implemented in stdlib
func tcsetpgrp(fd int, pgrp int) error {
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pgrp)
@ -120,7 +98,6 @@ func InitShellFeatures() bool {
waitChan = make(chan error, 5)
go signalHandler()
go waitHandler()
setSigState()
pid = os.Getpid()
@ -161,6 +138,35 @@ func TeardownShell() {
}
}
/* Check background processes states
* If any have finished, reap them
*/
func CheckBGProcs() {
for key, proc := range JobMap {
maybeFilePath := fmt.Sprintf("/proc/%d", key)
_, err := os.Stat(maybeFilePath)
if os.IsNotExist(err) {
if err := proc.Ctl.Process.Release(); err != nil {
log.Log(log.ERR,
fmt.Sprintf("Failed to release exited process %d: %s",
key, err.Error()),
"jobctl")
} else {
// not actually an error, just abusing default visibility
log.Log(log.ERR,
fmt.Sprintf("Child [%d] exited", key),
"jobctl")
delete(JobMap, key)
}
} else if err != nil {
log.Log(log.DEBUG,
"Error checking if process exists in proc: " + err.Error(),
"jobctl")
}
}
}
/* Makes and stores a new process in the job control
* uses os/exec Cmd object. sets SysProcAttr.Foreground
* calls Cmd.Start()
@ -204,14 +210,7 @@ func LaunchProcess(
JobMap[cpid] = Proc{ Ctl: cmd, Cancel: cancel }
CurCancel = &cancel
if background {
cmd.Process.Signal(syscall.SIGTSTP)
go func(){
waitChan <- cmd.Wait()
delete(JobMap, cpid)
CurCancel = nil
}()
} else {
if !background {
cmd.Wait()
tcsetpgrp(0, pgid)
delete(JobMap, cpid)
@ -322,7 +321,7 @@ func Fg(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
}
ipid := int(pid)
_, ok := JobMap[ipid]
proc, ok := JobMap[ipid]
if !ok {
log.Log(log.ERR,
"Process not found, was it started by this shell?",
@ -330,7 +329,14 @@ func Fg(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
return nil
}
tcsetpgrp(0, ipid)
if err := tcsetpgrp(0, ipid); err != nil {
log.Log(log.ERR,
"Error foregrounding process: " + err.Error(),
"fg")
return nil
}
proc.Ctl.Wait()
return nil
}