I have an executable that I need to run. Also, I want the parent process to send signal to the child process.
I have a soft timeout and a hardtimeout value.
The sequence should be:
? If child is still running after soft time, send SIGHUP, and log
? If child is still running after hard timeout, send SIGTERM, and log
? If child is still running, after 5 seconds, send SIGKILL, and log
Fairly new to go, this is the code I tried.
Do I need to call cmd.Wait() at the end of the program? Also, how do I check if the child process died because of the signal that I had sent. I did find Get exit code - Go but not quite convinced how to use it.
Also, does the code look correct?
I understand that the cmd.Wait() will return only once the child processes the signal it has received. But in the "testExecutable" code, how should it return to the parent(that it is dying now)
Here is my code:
func run() error{
cmd?:=?exec.Command("testExecutable",?"helpMe",?"-s",?"testMe")
????cmd.Stdout?=?os.Stdout
????cmd.Stderr?=?os.Stderr
???????cmd.SysProcAttr?=?&syscall.SysProcAttr{Setpgid:?true}
????startTime?:=?time.Now()
????if?err?:=?cmd.Start();?err?!=?nil?{
????????return?fmt.Errorf("Failed?to?start?the?executable")
????}???
????rChan?:=?make(chan?error,?1)
????go?func()?{
????????var?err?error
????????defer?func()?{
????????????if?err?!=?nil?{
????????????????fmt.Errorf(err.Error())
????????????}
????????????rChan?<-?err
????????}()?
????for?time.Now().Sub(startTime)?<?time.Duration(HardTimeout)?{
????????time.Sleep(time.Second)
????????if?time.Now().Sub(startTime)?<?time.Duration(SoftTimeout)?&&?cmd.ProcessState.Exited()?{
????????????fmt.Println("process?ended?before?soft?timeout")
????????????return
????????}?else?if?time.Now().Sub(startTime)?>?time.Duration(SoftTimeout)?&&?time.Now().Sub(startTime)?<?time.Duration(HardTimeout)?&&?!cmd.ProcessState.Exited()?{
????????????if?err?:=?syscall.Kill(-cmd.Process.Pid,?syscall.SIGHUP);?err?!=?nil?{
????????????????return?
????????????}
????????????if?cmd.ProcessState.Exited()?{
????????????????fmt.Println("?process?was?killed?after?soft?timeout")
????????????????return
????????????}
????????}?else?if?time.Now().Sub(startTime)?<?time.Duration(SoftTimeout)?{
????????????continue
????????}
????????if?time.Now().Sub(startTime)?>?time.Duration(HardTimeout)?&&?!cmd.ProcessState.Exited()?{
????????????if?err?:=?syscall.Kill(-cmd.Process.Pid,?syscall.SIGINT);?err?!=?nil?{
????????????????return?
????????????}
????????????time.Sleep(time.Second?*?5)
????????????if?!cmd.ProcessState.Exited()?{
????????????????if?err?:=?syscall.Kill(-cmd.Process.Pid,?syscall.SIGKILL);?err?!=?nil?{
????????????????????return?
????????????????}
????????????}else?{
????????????????fmt.Println("?process?was?killed?after?hard?timeout")
????????????????return?
????????????}
????????}?
????}???
}()
????var?ierr?error
????
ierr,_?=?<-?rChan
err?=?cmd.Wait()
????if?err?!=?nil?{
????????if?ierr?!=?nil?{
????????????return?fmt.Errorf(process?%d?Terminated",?cmd.Process.Pid)
????????}
????}
return?nil
}
question from:
https://stackoverflow.com/questions/65877324/sending-signals-to-child-process-using-package-exec 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…