fixed background process execution
This commit is contained in:
parent
f34c9070c8
commit
5d538d4a0b
3 changed files with 43 additions and 35 deletions
|
|
@ -136,6 +136,8 @@ func main() {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
setLogLvl(vars)
|
setLogLvl(vars)
|
||||||
|
stdlib.CheckBGProcs()
|
||||||
|
|
||||||
var prePrompt string
|
var prePrompt string
|
||||||
if dyn_prompt != nil {
|
if dyn_prompt != nil {
|
||||||
p_tok := dyn_prompt.CallFunction(nil, vars, funcs)
|
p_tok := dyn_prompt.CallFunction(nil, vars, funcs)
|
||||||
|
|
|
||||||
|
|
@ -51,5 +51,5 @@ func Log(lvl int, msg, context string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[" + context + "]\033[3m " + msg + "\033[0m")
|
fmt.Println("[" + context + "]\033[3m " + msg + "\033[0m ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"fmt"
|
"fmt"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"context"
|
"context"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
@ -68,7 +67,7 @@ var LastExitCode int
|
||||||
func signalHandler() {
|
func signalHandler() {
|
||||||
for {
|
for {
|
||||||
<- sigChan
|
<- sigChan
|
||||||
log.Log(log.INFO,
|
log.Log(log.DEBUG,
|
||||||
"caught SIGINT",
|
"caught SIGINT",
|
||||||
"jobctl")
|
"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
|
// for some reason not implemented in stdlib
|
||||||
func tcsetpgrp(fd int, pgrp int) error {
|
func tcsetpgrp(fd int, pgrp int) error {
|
||||||
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pgrp)
|
return unix.IoctlSetPointerInt(fd, unix.TIOCSPGRP, pgrp)
|
||||||
|
|
@ -120,7 +98,6 @@ func InitShellFeatures() bool {
|
||||||
waitChan = make(chan error, 5)
|
waitChan = make(chan error, 5)
|
||||||
|
|
||||||
go signalHandler()
|
go signalHandler()
|
||||||
go waitHandler()
|
|
||||||
|
|
||||||
setSigState()
|
setSigState()
|
||||||
pid = os.Getpid()
|
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
|
/* Makes and stores a new process in the job control
|
||||||
* uses os/exec Cmd object. sets SysProcAttr.Foreground
|
* uses os/exec Cmd object. sets SysProcAttr.Foreground
|
||||||
* calls Cmd.Start()
|
* calls Cmd.Start()
|
||||||
|
|
@ -204,14 +210,7 @@ func LaunchProcess(
|
||||||
JobMap[cpid] = Proc{ Ctl: cmd, Cancel: cancel }
|
JobMap[cpid] = Proc{ Ctl: cmd, Cancel: cancel }
|
||||||
CurCancel = &cancel
|
CurCancel = &cancel
|
||||||
|
|
||||||
if background {
|
if !background {
|
||||||
cmd.Process.Signal(syscall.SIGTSTP)
|
|
||||||
go func(){
|
|
||||||
waitChan <- cmd.Wait()
|
|
||||||
delete(JobMap, cpid)
|
|
||||||
CurCancel = nil
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
tcsetpgrp(0, pgid)
|
tcsetpgrp(0, pgid)
|
||||||
delete(JobMap, cpid)
|
delete(JobMap, cpid)
|
||||||
|
|
@ -322,7 +321,7 @@ func Fg(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
|
||||||
}
|
}
|
||||||
|
|
||||||
ipid := int(pid)
|
ipid := int(pid)
|
||||||
_, ok := JobMap[ipid]
|
proc, ok := JobMap[ipid]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Log(log.ERR,
|
log.Log(log.ERR,
|
||||||
"Process not found, was it started by this shell?",
|
"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
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue