better handling of interrupt

This commit is contained in:
Aidan 2020-07-22 22:30:56 -07:00
parent e098a8812c
commit f69532d54c
No known key found for this signature in database
GPG key ID: 327711E983899316

View file

@ -44,6 +44,11 @@ var JobMap = map[int]Proc{}
*/ */
var pgid, pid int var pgid, pid int
/* cancel func for current running process
*/
var CurCancel *context.CancelFunc
/* Holds an os/exec Cmd object and its context cancel function /* Holds an os/exec Cmd object and its context cancel function
*/ */
type Proc struct { type Proc struct {
@ -62,12 +67,13 @@ var LastExitCode int
// Job control handlers // Job control handlers
func signalHandler() { func signalHandler() {
for { for {
sig := <- sigChan <- sigChan
switch sig {
case syscall.SIGINT:
log.Log(log.DEBUG, log.Log(log.DEBUG,
"caught SIGINT", "caught SIGINT",
"jobctl") "jobctl")
if CurCancel != nil {
(*CurCancel)()
} }
} }
} }
@ -78,7 +84,7 @@ func waitHandler() {
exit := 0 exit := 0
if w != nil { if w != nil {
log.Log(log.ERR, log.Log(log.ERR,
"Child returned error: " + w.Error(), "Child returned: " + w.Error(),
"jobctl") "jobctl")
// something outrageous // something outrageous
@ -90,10 +96,6 @@ func waitHandler() {
LastExitCode = exit LastExitCode = exit
} }
log.Log(log.DEBUG,
"handled sigchld!",
"jobctl")
} }
} }
@ -105,7 +107,7 @@ func tcsetpgrp(fd int, pgrp int) error {
// wrapper for convenience // wrapper for convenience
func setSigState() { func setSigState() {
signal.Ignore(syscall.SIGTTOU, syscall.SIGTTIN, syscall.SIGTSTP) signal.Ignore(syscall.SIGTTOU, syscall.SIGTTIN, syscall.SIGTSTP)
signal.Notify(sigChan, syscall.SIGINT) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGQUIT)
} }
/* Sets pgid /* Sets pgid
@ -189,20 +191,24 @@ func LaunchProcess(
cmd.Stderr = stderr cmd.Stderr = stderr
cmd.Start() cmd.Start()
pid := cmd.Process.Pid cpid := cmd.Process.Pid
// TODO: check for clobber? // TODO: check for clobber?
// unlikely, but PIDs do reset after a while // unlikely, but PIDs do reset after a while
JobMap[pid] = Proc{ Ctl: cmd, Cancel: cancel } JobMap[cpid] = Proc{ Ctl: cmd, Cancel: cancel }
CurCancel = &cancel
if background { if background {
go func(){ go func(){
waitChan <- cmd.Wait() waitChan <- cmd.Wait()
tcsetpgrp(0, pgid) delete(JobMap, cpid)
CurCancel = nil
}() }()
} else { } else {
cmd.Wait() cmd.Wait()
tcsetpgrp(0, pgid) tcsetpgrp(0, pgid)
delete(JobMap, cpid)
CurCancel = nil
} }
} }