better handling of interrupt
This commit is contained in:
parent
e098a8812c
commit
f69532d54c
1 changed files with 21 additions and 15 deletions
|
|
@ -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 {
|
log.Log(log.DEBUG,
|
||||||
case syscall.SIGINT:
|
"caught SIGINT",
|
||||||
log.Log(log.DEBUG,
|
"jobctl")
|
||||||
"caught SIGINT",
|
|
||||||
"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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue