func checkstatus(p *os.Process, pname string, timest string) bool { fmt.Println("checkstatus", pname, p) reportlog[timest]["status"] = pname + " running" reportlog[timest][pname+"start"] = time.Now().Format("20060102150405") liner, _ := json.Marshal(reportlog) ioutil.WriteFile("static/data/reportlog.json", liner, 0) pw, _ := p.Wait() fmt.Println("checkstatus over", p) fmt.Println("timest=", timest) reportlog[timest][pname+"stop"] = time.Now().Format("20060102150405") t1, _ := time.Parse("20060102150405", reportlog[timest][pname+"stop"]) t2, _ := time.Parse("20060102150405", reportlog[timest][pname+"start"]) reportlog[timest][pname+"time"] = strconv.Itoa(int(t1.Sub(t2)) / 1e9) fmt.Println("t1=", t1) fmt.Println("t2=", t2) fmt.Println("cost=", t1.Sub(t2)) status := pw.Success() if status == true { reportlog[timest]["status"] = pname + " success" fmt.Println("checkstatus over success ", pname, p) } else { reportlog[timest]["status"] = pname + " failed" fmt.Println("checkstatus over failed ", pname, p) } liner, _ = json.Marshal(reportlog) ioutil.WriteFile("static/data/reportlog.json", liner, 0) return status }
// Return the output from running the given command func GetOutput(args []string) (output string, error error) { var ( buffer *bytes.Buffer process *os.Process ) read_pipe, write_pipe, err := os.Pipe() if err != nil { goto Error } defer read_pipe.Close() process, err = os.StartProcess(args[0], args, &os.ProcAttr{ Dir: ".", Env: os.Environ(), Files: []*os.File{nil, write_pipe, nil}, }) if err != nil { write_pipe.Close() goto Error } _, err = process.Wait(0) write_pipe.Close() if err != nil { goto Error } buffer = &bytes.Buffer{} _, err = io.Copy(buffer, read_pipe) if err != nil { goto Error } output = buffer.String() return output, nil Error: return "", &CommandError{args[0], args} }
func runprog(argv []string) (filesize int64, mem int64, err error) { var attr os.ProcAttr var stat *os.ProcessState var proc *os.Process exepath, err := exec.LookPath(argv[0]) if err != nil { err = errors.New("can't find exe file.") return } proc, err = os.StartProcess(exepath, argv, &attr) if err != nil { return } fi, err := os.Stat(exepath) if err != nil { return } filesize = fi.Size() stat, err = proc.Wait() mem = int64(stat.SysUsage().(*syscall.Rusage).Maxrss) return }
func (ss *SubService) rerunner(rerunChan chan bool) { var proc *os.Process for rerun := range rerunChan { if !rerun { break } cmd := exec.Command(ss.binPath, ss.argv...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr startupTimer := time.NewTimer(RerunWait) cmd.Start() proc = cmd.Process // In another goroutine, wait for the process to complete and send a relaunch signal. // If this signal is sent after the stop signal, it is ignored. go func(proc *os.Process) { proc.Wait() select { case <-startupTimer.C: // we let it run long enough that it might not be a recurring error, try again rerunChan <- true default: // error happened too quickly - must be startup issue startupTimer.Stop() } }(proc) } proc.Kill() }
func run(ch chan bool, bin string, args []string) { go func() { var proc *os.Process for relaunch := range ch { if proc != nil { if err := proc.Signal(os.Interrupt); err != nil { proc.Kill() } proc.Wait() } if !relaunch { continue } cmd := exec.Command(bin, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { log("error: %s", err) } proc = cmd.Process } }() return }
// runBin runs the generated bin file with the arguments expected func runBin(bindir, bin string, args []string) chan bool { var relunch = make(chan bool) go func() { binfile := fmt.Sprintf("%s/%s", bindir, bin) // cmdline := append([]string{bin}, args...) var proc *os.Process for dosig := range relunch { if proc != nil { if err := proc.Signal(os.Interrupt); err != nil { log.Printf("Error in sending signal %s", err) proc.Kill() } proc.Wait() } if !dosig { continue } cmd := exec.Command(binfile, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { log.Printf("Error starting process: %s", err) } proc = cmd.Process } }() return relunch }
func run(binName, binPath string, args []string) (runch chan bool) { runch = make(chan bool) go func() { cmdline := append([]string{binName}, args...) var proc *os.Process for relaunch := range runch { if proc != nil { err := proc.Signal(os.Interrupt) if err != nil { log.Printf("error on sending signal to process: '%s', will now hard-kill the process\n", err) proc.Kill() } proc.Wait() } if !relaunch { continue } cmd := exec.Command(binPath, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr log.Print(cmdline) err := cmd.Start() if err != nil { log.Printf("error on starting process: '%s'\n", err) } proc = cmd.Process } }() return }
// Run the command in the given string and restart it after // a message was received on the buildDone channel. func runner(command string, buildDone <-chan struct{}) { var currentProcess *os.Process pipeChan := make(chan io.ReadCloser) go logger(pipeChan) for { <-buildDone if currentProcess != nil { if err := currentProcess.Kill(); err != nil { log.Fatal("Could not kill child process. Aborting due to danger of infinite forks.") } _, werr := currentProcess.Wait() if werr != nil { log.Fatal("Could not wait for child process. Aborting due to danger of infinite forks.") } } log.Println("Restarting the given command.") cmd, stdoutPipe, stderrPipe, err := startCommand(command) if err != nil { log.Fatal("Could not start command:", err) } pipeChan <- stdoutPipe pipeChan <- stderrPipe currentProcess = cmd.Process } }
func status(proc *os.Process) *Status { status, err := proc.Wait() if err != nil { return ExitFailure } return NewStatus(status.Sys().(plan9.Waitmsg).Msg) }
func JoinProcess(proc *os.Process) int { status, err := proc.Wait() if err != nil { return -1 } return status.Sys().(syscall.WaitStatus).ExitStatus() }
func status(proc *os.Process) *Status { status, err := proc.Wait() if err != nil { return ExitFailure } return NewStatus(int64(status.Sys().(windows.WaitStatus).ExitStatus())) }
// RunGo runs the generated binary file with the arguments expected func RunGo(gofile string, args []string, done, stopped func()) chan bool { var relunch = make(chan bool) // if runtime.GOOS == "windows" { gofile = filepath.Clean(gofile) // } go func() { // var cmdline = fmt.Sprintf("go run %s", gofile) cmdargs := append([]string{"run", gofile}, args...) // cmdline = strings.Joinappend([]string{}, "go run", gofile) var proc *os.Process for dosig := range relunch { if proc != nil { var err error if runtime.GOOS == "windows" { err = proc.Kill() } else { err = proc.Signal(os.Interrupt) } if err != nil { fmt.Printf("---> Error in Sending Kill Signal %s\n", err) proc.Kill() } proc.Wait() proc = nil } if !dosig { continue } fmt.Printf("--> Starting cmd: %s\n", cmdargs) cmd := exec.Command("go", cmdargs...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { fmt.Printf("---> Error starting process: %s\n", err) } proc = cmd.Process if done != nil { done() } } if stopped != nil { stopped() } }() return relunch }
// Go doesn't support signals in windows (pre Go 1.3) because windows doesn't have signals. // Non-windows implementation will use signals func stop(process *os.Process) error { err := process.Signal(os.Interrupt) if err != nil { log.Println("Error while sending SIGINT to running server:", err) return err } _, err = process.Wait() return err }
func killProcessHard(process *os.Process) { log.Println(okColor("Hard stopping the current process..")) if err := process.Kill(); err != nil { log.Fatal(failColor("Could not kill child process. Aborting due to danger of infinite forks.")) } if _, err := process.Wait(); err != nil { log.Fatal(failColor("Could not wait for child process. Aborting due to danger of infinite forks.")) } }
func endProcess(p *os.Process) error { if p == nil { return nil } if err := p.Signal(syscall.SIGTERM); err != nil { return err } _, err := p.Wait() if *verbose { log.Printf("Exiting pid %d.", p.Pid) } return err }
func exitWait(process *os.Process, done chan<- error) { for { ps, err := process.Wait() if err != nil { done <- err return } if ps.Exited() { done <- nil return } } }
// RunBin runs the generated binary file with the arguments expected func RunBin(binfile string, args []string, done, stopped func()) chan bool { var relunch = make(chan bool) go func() { // binfile := fmt.Sprintf("%s/%s", bindir, bin) // cmdline := append([]string{bin}, args...) var proc *os.Process for dosig := range relunch { if proc != nil { var err error if runtime.GOOS == "windows" { err = proc.Kill() } else { err = proc.Signal(os.Interrupt) } if err != nil { fmt.Printf("---> Error in Sending Kill Signal: %s\n", err) proc.Kill() } proc.Wait() proc = nil } if !dosig { continue } fmt.Printf("--> Starting bin: %s\n", binfile) cmd := exec.Command(binfile, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { fmt.Printf("---> Error starting process: %s -> %s\n", binfile, err) } proc = cmd.Process if done != nil { done() } } if stopped != nil { stopped() } }() return relunch }
func waitWithTimeout(timeout time.Duration, pr *os.Process) error { errc := make(chan error, 1) go func() { _, e := pr.Wait() errc <- e }() var err error select { case <-time.After(timeout): err = fmt.Errorf("timed out after %v", timeout) case err = <-errc: } return err }
func (ss *SubService) watchProcess(proc *os.Process, startupTimer *time.Timer) { proc.Wait() if !ss.running { startupTimer.Stop() return } select { case <-startupTimer.C: // we let it run long enough that it might not be a recurring error, try again if ss.running { ss.rerunChan <- true } default: // error happened too quickly - must be startup issue fmt.Println("Service died too quickly: " + ss.binPath) startupTimer.Stop() } }
func (ss *SubService) rerunner(rerunChan chan bool) { var proc *os.Process for rerun := range rerunChan { if !rerun { break } cmd := exec.Command(ss.binPath, ss.argv...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Start() proc = cmd.Process // In another goroutine, wait for the process to complete and send a relaunch signal. // If this signal is sent after the stop signal, it is ignored. go func(proc *os.Process) { proc.Wait() rerunChan <- true }(proc) } proc.Kill() }
func killProcessGracefully(process *os.Process) { done := make(chan error, 1) go func() { log.Println(okColor("Gracefully stopping the current process..")) if err := terminateGracefully(process); err != nil { done <- err return } _, err := process.Wait() done <- err }() select { case <-time.After(3 * time.Second): log.Println(failColor("Could not gracefully stop the current process, proceeding to hard stop.")) killProcessHard(process) <-done case err := <-done: if err != nil { log.Fatal(failColor("Could not kill child process. Aborting due to danger of infinite forks.")) } } }
func (m *MCP) restart(proc *os.Process) { _, err := proc.Wait() if err != nil { log.Fatal(err) } m.debugHandler("MCP#restart\tchild died") if atomic.LoadInt32(&m.stopped) == 1 { return } time.Sleep(clientRestartTimeout) if err := m.cleanup(); err != nil { log.Fatal(err) } m.debugHandler("MCP#restart\tchild cleaned") if err := m.startProc(); err != nil { log.Fatal(err) } m.debugHandler("MCP#restart\tchild restarted") }
func TrackProcess(proc *os.Process) { proc.Wait() panic("No") }
func killNetNsProc(proc *os.Process) { proc.Kill() proc.Wait() }