func findUnusedPid() int { for { pid := rand.Int31() ok, err := process.PidExists(pid) Expect(err).NotTo(HaveOccurred()) if !ok { return int(pid) } } }
func waitForTerm(command *ServiceCommand, timeout time.Duration) (bool, error) { for elapsed := time.Duration(0); elapsed <= timeout; elapsed += time.Millisecond * 100 { exists, err := process.PidExists(int32(command.Pid)) if err != nil { return false, errors.WithStack(err) } if !exists { return true, nil } time.Sleep(time.Millisecond * 100) } return false, nil }
func (sc *ServiceConfig) stopProcess(cfg OperationConfig, command *ServiceCommand, graceful bool) (success bool, err error) { pgid, err := syscall.Getpgid(command.Pid) if err != nil { return false, errors.WithStack(err) } if pgid == 0 || pgid == 1 { return false, errors.WithStack(errors.New("suspect pgid: " + strconv.Itoa(pgid))) } err = command.killGroup(cfg, pgid, graceful) if err != nil { return false, errors.WithStack(err) } // Check to see if the process is still running exists, err := process.PidExists(int32(command.Pid)) if err != nil { return false, errors.WithStack(err) } return !exists, nil }
func loadPid(filename string) (int32, error) { pidfile, err := os.Open(filename) if err != nil { return 0, err } b, err := ioutil.ReadAll(pidfile) if err != nil { return 0, err } if err != nil { warn(err) return 0, err } pid, err := strconv.Atoi(string(b)) if err != nil { return 0, err } if err != nil { warn(err) return 0, err } alive, err := process.PidExists(int32(pid)) if err != nil { return 0, err } if !alive { return 0, fmt.Errorf("Pid not exists: %v", pid) } return int32(pid), nil }
func (s *ServiceConfig) GetCommand() (*ServiceCommand, error) { s.printf("Building control command for: %v\n", s.Name) dir := home.EdwardConfig.LogDir logs := struct { Build string Run string Stop string }{ Build: path.Join(dir, s.Name+"-build.log"), Run: path.Join(dir, s.Name+".log"), Stop: path.Join(dir, s.Name+"-stop.log"), } path := "" if s.Path != nil { path = *s.Path } command := &ServiceCommand{ Service: s, Scripts: struct { Build Script Launch Script Stop Script }{ Build: Script{ Path: path, Command: s.Commands.Build, Log: logs.Build, }, Launch: Script{ Path: path, Command: s.Commands.Launch, Log: logs.Run, }, Stop: Script{ Path: path, Command: s.Commands.Stop, Log: logs.Stop, }, }, Logger: s.Logger, } // Retrieve the PID if available pidFile := command.getPidPath() s.printf("Checking pidfile for %v: %v\n", s.Name, pidFile) if _, err := os.Stat(pidFile); err == nil { dat, err := ioutil.ReadFile(pidFile) if err != nil { return nil, errors.WithStack(err) } pid, err := strconv.Atoi(string(dat)) if err != nil { return nil, errors.WithStack(err) } command.Pid = pid exists, err := process.PidExists(int32(command.Pid)) if err != nil { return nil, errors.WithStack(err) } if !exists { s.printf("Process for %v was not found, resetting.\n", s.Name) command.clearState() } proc, err := process.NewProcess(int32(command.Pid)) if err != nil { return nil, errors.WithStack(err) } cmdline, err := proc.Cmdline() if err != nil { return nil, errors.WithStack(err) } if !strings.Contains(cmdline, s.Name) { s.printf("Process for %v was not as expected (found %v), resetting.\n", s.Name, cmdline) command.clearState() } } else { s.printf("No pidfile for %v", s.Name) } // TODO: Set status return command, nil }