func TestDeath(t *testing.T) { defer log.Flush() Convey("Validate death happens cleanly", t, func() { death := NewDeath(syscall.SIGTERM) syscall.Kill(os.Getpid(), syscall.SIGTERM) death.WaitForDeath() }) Convey("Validate death happens with other signals", t, func() { death := NewDeath(syscall.SIGHUP) closeMe := &CloseMe{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(closeMe) So(closeMe.Closed, ShouldEqual, 1) }) Convey("Validate death gives up after timeout", t, func() { death := NewDeath(syscall.SIGHUP) death.setTimeout(10 * time.Millisecond) neverClose := &neverClose{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(neverClose) }) }
func (c *command) kill() { // We started the process in its own process group and now kill the whole group. // This solves a potential problem with strace: // if we kill just strace, executor still runs and ReadAll below hangs. syscall.Kill(-c.cmd.Process.Pid, syscall.SIGKILL) syscall.Kill(c.cmd.Process.Pid, syscall.SIGKILL) }
func (c *Cmd) cleanupProcessGroup() { if !c.started { return } c.cleanupMu.Lock() defer c.cleanupMu.Unlock() if c.calledCleanup { return } c.calledCleanup = true // Send SIGINT first; then, after a grace period, send SIGKILL to any // process that is still running. if err := syscall.Kill(-c.Pid(), syscall.SIGINT); err == syscall.ESRCH { return } for i := 0; i < 10; i++ { time.Sleep(100 * time.Millisecond) if err := syscall.Kill(-c.Pid(), 0); err == syscall.ESRCH { return } } syscall.Kill(-c.Pid(), syscall.SIGKILL) }
// scheduleTermination schedules termination with sigterm // of a previous haproxy instance after configured amount of time func (c *HaproxyConfigurator) scheduleTermination(pid int) { log.Printf("scheduling termination for haproxy with pid %d in %s\n", pid, c.timeout) deadline := time.Now().Add(c.timeout) go func() { for { err := syscall.Kill(pid, 0) if err != nil { if err == syscall.ESRCH { log.Printf("haproxy with pid %d gracefully exited before we killed it\n", pid) } else { log.Println("error checking that haproxy with pid %d is still running: %s\n", pid, err) } break } if time.Now().After(deadline) { log.Printf("killing haproxy with pid %d with sigterm\n", pid) err := syscall.Kill(pid, syscall.SIGTERM) if err != nil { log.Printf("error killing haproxy with pid %d: %s\n", pid, err) } break } time.Sleep(time.Second) } }() }
func TestServerWithBasicAuth(t *testing.T) { cmd := exec.Cmd{ Path: os.Getenv("GOPATH") + "/bin/docker-builder", Args: []string{"docker-builder", "serve", "--username", "foo", "--password", "bar"}, } if err := cmd.Start(); err != nil { t.Errorf("error start server: %s\n", err.Error()) } go func() { time.Sleep(100 * time.Millisecond) syscall.Kill(cmd.Process.Pid, syscall.SIGUSR1) time.Sleep(100 * time.Millisecond) syscall.Kill(cmd.Process.Pid, syscall.SIGTERM) }() if err := cmd.Wait(); err != nil { if exiterr, ok := err.(*exec.ExitError); ok { if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { if status.ExitStatus() != 166 { t.Errorf("server exited unexpectedly and/or did not start correctly") } } else { t.Errorf("unable to get process exit code") } } else { t.Errorf("error waiting on server: %s\n", err.Error()) } } }
func TestSighupHandler(t *testing.T) { ranHandler := make(chan bool, 1) handler := func(d daemon.Daemon) { ranHandler <- true } conf, _ := config.New("example.yaml") d, _ := daemon.New(conf) setupSighupHandler(d, handler) // Need to sleep here so that the goroutine has time to set up the signal listener, otherwise // the signal gets missed time.Sleep(1 * time.Second) syscall.Kill(syscall.Getpid(), syscall.SIGHUP) // Give the syscall 1 second to be handled, should be more than enough time timeout := make(chan bool, 1) go func() { time.Sleep(time.Duration(1 * time.Second)) timeout <- true }() select { case <-ranHandler: case <-timeout: t.Fatal("Didn't run handler") } // Try calling again and make sure it still happens syscall.Kill(syscall.Getpid(), syscall.SIGHUP) select { case <-ranHandler: case <-timeout: t.Fatal("Didn't run handler second time") } }
// Test that basic signal handling works. func TestSignal(t *testing.T) { // Ask for SIGHUP c := make(chan os.Signal, 1) Notify(c, syscall.SIGHUP) defer Stop(c) // Send this process a SIGHUP t.Logf("sighup...") syscall.Kill(syscall.Getpid(), syscall.SIGHUP) waitSig(t, c, syscall.SIGHUP) // Ask for everything we can get. c1 := make(chan os.Signal, 1) Notify(c1) // Send this process a SIGWINCH t.Logf("sigwinch...") syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) waitSig(t, c1, syscall.SIGWINCH) // Send two more SIGHUPs, to make sure that // they get delivered on c1 and that not reading // from c does not block everything. t.Logf("sighup...") syscall.Kill(syscall.Getpid(), syscall.SIGHUP) waitSig(t, c1, syscall.SIGHUP) t.Logf("sighup...") syscall.Kill(syscall.Getpid(), syscall.SIGHUP) waitSig(t, c1, syscall.SIGHUP) // The first SIGHUP should be waiting for us on c. waitSig(t, c, syscall.SIGHUP) }
// stop attempts to stop the process, first with SIGTERM, then if the process // is still running after KILLPAUSE nanoseconds with SIGKILL. It returns the // Waitmsg generated when the process died. func (kp *KickitProcess) stop() (msg *os.Waitmsg, err os.Error) { kp.wantDown = true if kp.process == nil { return nil, ErrNotRunning } // If an error occurs here it indicates the process already died. This // is fine, as it means a Waitmsg is waiting for us when we hit the select syscall.Kill(kp.process.Pid, syscall.SIGTERM) // Give the process KILLPAUSE ns to die timer := time.NewTimer(KILLPAUSE) select { case msg = <-kp.waitChan: timer.Stop() log.Printf("%s stopped\n", kp.name) kp.process = nil return msg, nil case <-timer.C: } // Same situation, an error means the process already died - its ok syscall.Kill(kp.process.Pid, syscall.SIGKILL) msg = <-kp.waitChan log.Printf("%s stopped\n", kp.name) kp.process = nil return msg, nil }
func TestSameProcessLock(t *testing.T) { lock, err := New("/tmp/lockfile.smaeprocess.lock") assert := assert.New(t) if os.Getenv("PARENTPID") == "" { //parent os.Setenv("PARENTPID", strconv.Itoa(os.Getpid())) cmd := exec.Command(os.Args[0], os.Args[1:]...) cmd.Env = os.Environ() cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Start() c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGUSR1) <-c assert.NotNil(lock.TryLock()) syscall.Kill(cmd.Process.Pid, syscall.SIGUSR1) cmd.Wait() assert.Nil(lock.TryLock()) assert.Nil(lock.TryLock()) } else { //child c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGUSR1) ppid, _ := strconv.Atoi(os.Getenv("PARENTPID")) assert.Nil(err) assert.Nil(lock.TryLock()) syscall.Kill(ppid, syscall.SIGUSR1) <-c } }
func (r *remote) Cleanup() { if r.daemonPid == -1 { return } r.rpcConn.Close() // Ask the daemon to quit syscall.Kill(r.daemonPid, syscall.SIGTERM) // Wait up to 15secs for it to stop for i := time.Duration(0); i < containerdShutdownTimeout; i += time.Second { if !utils.IsProcessAlive(r.daemonPid) { break } time.Sleep(time.Second) } if utils.IsProcessAlive(r.daemonPid) { logrus.Warnf("libcontainerd: containerd (%d) didn't stop within 15 secs, killing it\n", r.daemonPid) syscall.Kill(r.daemonPid, syscall.SIGKILL) } // cleanup some files os.Remove(filepath.Join(r.stateDir, containerdPidFilename)) os.Remove(filepath.Join(r.stateDir, containerdSockFilename)) }
// Called on running checks, to determine if they have finished // running. // // If the Check has not finished executing, returns false. // // If the Check has been running for longer than its Timeout, // a SIGTERM (and failing that a SIGKILL) is issued to forcibly // terminate the rogue Check process. In either case, this returns // as if the check has not yet finished, and Reap() will need to be // called again to fully reap the Check // // If the Check has finished execution (on its own, or via forced // termination), it will return true. // // Once complete, some additional meta-stats for the check execution // are appended to the check output, to be submit up to bolo func (self *Check) Reap() bool { pid := self.process.Process.Pid var ws syscall.WaitStatus status, err := syscall.Wait4(pid, &ws, syscall.WNOHANG, nil) if err != nil { log.Error("Error waiting on check %s[%d]: %s", self.Name, pid, err.Error()) return false } if status == 0 { // self to see if we need to sigkill due to failed sigterm if time.Now().After(self.started_at.Add(time.Duration(self.Timeout+2) * time.Second)) { log.Warn("Check %s[%d] has been running too long, sending SIGKILL", self.Name, pid) if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { log.Error("Error sending SIGKILL to check %s[%d]: %s", self.Name, pid, err.Error()) } self.sig_kill = true } // self to see if we need to sigterm due to self timeout expiry if !self.sig_kill && time.Now().After(self.started_at.Add(time.Duration(self.Timeout)*time.Second)) { log.Warn("Check %s[%d] has been running too long, sending SIGTERM", self.Name, pid) if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { log.Error("Error sending SIGTERM to check %s[%d]: %s", self.Name, pid, err.Error()) } self.sig_term = true } return false } self.ended_at = time.Now() self.running = false self.duration = time.Since(self.started_at) self.latency = self.started_at.Sub(self.next_run) self.output = string(self.stdout.Bytes()) self.err_msg = string(self.stderr.Bytes()) if ws.Exited() { self.rc = ws.ExitStatus() } else { log.Debug("Check %s[%d] exited abnormally (signaled/stopped). Setting rc to UNKNOWN", self.Name, pid) self.rc = UNKNOWN } if self.rc > UNKNOWN { log.Debug("Check %s[%d] returned with an invalid exit code. Setting rc to UNKOWN", self.Name, pid) self.rc = UNKNOWN } self.reschedule() if self.ended_at.After(self.next_run) { timeout_triggered := "not reached" if self.sig_term || self.sig_kill { timeout_triggered = "reached" } log.Warn("Check %s[%d] took %0.3f seconds to run, at interval %d (timeout of %d was %s)", self.Name, pid, self.duration.Seconds(), self.Every, self.Timeout, timeout_triggered) } return true }
func (m *Module) Stop() os.Error { // 0x02, or SIGINT. syscall.Kill(m.MainProcess.Pid, 0x02) syscall.Kill(m.SyncProcess.Pid, 0x02) // TODO: Check for syscall errors modules[m.Name] = nil, false return nil }
func Test_Handle_With2_SIGHUP_ExecutesFnTwice(t *testing.T) { done := make(chan bool, 1) signal.Handle(func() { done <- true }) syscall.Kill(syscall.Getpid(), syscall.SIGHUP) receiveOnce(t, done) syscall.Kill(syscall.Getpid(), syscall.SIGHUP) receiveOnce(t, done) }
func redirFromWs(stdinPipe io.Writer, ws *websocket.Conn, pid int) { defer func() { if r := recover(); r != nil { fmt.Fprintf(os.Stderr, "Error occured: %s\n", r) syscall.Kill(pid, syscall.SIGHUP) runtime.Goexit() } }() var buf [2048]byte for { /* communication protocol: 1 byte cmd if cmd = i // input 8 byte length (ascii) length bytes the actual input if cmd = w // window size changed 8 byte cols (ascii) 8 byte rows (ascii) */ readFull(ws, buf[0:1]) switch buf[0] { case 'i': length := readInt(ws) switch nr, er := io.ReadFull(ws, buf[0:length]); { case nr < 0: fmt.Fprintf(os.Stderr, "error reading from websocket with code %s\n", er) return case nr == 0: // EOF fmt.Fprintf(os.Stderr, "connection closed, sending SIGHUP to %d\n") syscall.Kill(pid, syscall.SIGHUP) return case nr > 0: _, err := stdinPipe.Write(buf[0:nr]) if err != nil { fmt.Fprintf(os.Stderr, "error writing to stdinPipe: %s\n", err.Error()) return } } case 'w': // sadly, we can no longer change window size as easily :( // cols, rows := readInt(ws), readInt(ws) // setColsRows(winsz, cols, rows) // C.goChangeWinsz(C.int(fd), winsz) default: panic("Unknown command " + string(buf[0])) } } }
func testCancel(t *testing.T, ignore bool) { // Send SIGWINCH. By default this signal should be ignored. syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) time.Sleep(100 * time.Millisecond) // Ask to be notified on c1 when a SIGWINCH is received. c1 := make(chan os.Signal, 1) Notify(c1, syscall.SIGWINCH) defer Stop(c1) // Ask to be notified on c2 when a SIGHUP is received. c2 := make(chan os.Signal, 1) Notify(c2, syscall.SIGHUP) defer Stop(c2) // Send this process a SIGWINCH and wait for notification on c1. syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) waitSig(t, c1, syscall.SIGWINCH) // Send this process a SIGHUP and wait for notification on c2. syscall.Kill(syscall.Getpid(), syscall.SIGHUP) waitSig(t, c2, syscall.SIGHUP) // Ignore, or reset the signal handlers for, SIGWINCH and SIGHUP. if ignore { Ignore(syscall.SIGWINCH, syscall.SIGHUP) } else { Reset(syscall.SIGWINCH, syscall.SIGHUP) } // Send this process a SIGWINCH. It should be ignored. syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) // If ignoring, Send this process a SIGHUP. It should be ignored. if ignore { syscall.Kill(syscall.Getpid(), syscall.SIGHUP) } select { case s := <-c1: t.Fatalf("unexpected signal %v", s) case <-time.After(100 * time.Millisecond): // nothing to read - good } select { case s := <-c2: t.Fatalf("unexpected signal %v", s) case <-time.After(100 * time.Millisecond): // nothing to read - good } // Reset the signal handlers for all signals. Reset() }
func HandleSignals(c int) { pid := syscall.Getpid() cur := Cursor{os.Stdout} switch c { case keyCtrlC: cur.Show() syscall.Kill(pid, syscall.SIGINT) case keyCtrlZ: cur.Show() syscall.Kill(pid, syscall.SIGTSTP) } }
func main() { lines_t := os.Getenv("lines_t") cols_t := os.Getenv("cols_t") lines64, err := strconv.ParseUint(lines_t, 10, 0) if err != nil { panic(err) } cols64, err := strconv.ParseUint(cols_t, 10, 0) if err != nil { panic(err) } lines := uint(lines64) cols := uint(cols64) fmt.Print("\0337\033[?47h\033[40m\033[97m\033[2J") fmt.Print("\033[?25l") ready := make(chan bool) geni := getNextInt(cols) running(geni, lines) for i := cols; i > 0; i-- { go printEraseReady(i, lines, true, ready) time.Sleep(fastEraseTime * time.Millisecond) } for i := cols; i > 0; i-- { _ = <-ready } fmt.Print("\033[?25h") fmt.Print("\033[?47l\0338") fmt.Printf("\033[%d;%dH", lines, 1) fmt.Print("\033[39m\033[49m") fmt.Printf("Number of lines %3d\n", lines) fmt.Printf("Number of cols %3d\n", cols) ppid := os.Getppid() fmt.Printf("get_ppid %d\n", ppid) if ppid < 2 { ppid_t := os.Getenv("ppid_t") ppid, err := strconv.Atoi(ppid_t) if err != nil { panic(err) } fmt.Printf("env_ppid %d\n", ppid) err = syscall.Kill(ppid, 2) if err != nil { panic(err) } } else { fmt.Printf("realppid %d\n", ppid) err = syscall.Kill(ppid, 2) if err != nil { panic(err) } } }
func (cmd *Cmd) Kill() error { switch cmd.State { case Running: cmd.State = Terminated lg.Debugf("Cmd:\tKilling %v\n", cmd.JobID) pgid, err := syscall.Getpgid(cmd.Cmd.Process.Pid) if err != nil { // Fall-back on error. Kill the main process only. cmd.Cmd.Process.Kill() break } // Kill the whole process group. syscall.Kill(-pgid, 15) case Finished: lg.Debug("Cmd:\tKilling pgroup %v\n", cmd.JobID) pgid, err := syscall.Getpgid(cmd.Cmd.Process.Pid) if err != nil { break } // Make sure to kill the whole process group, // so there are no subprocesses left. syscall.Kill(-pgid, 15) case Initialized: // This one is tricky, as the cmd's Start() might have // been called and is already in progress, but the cmd's // state is not Running yet. usCallingStartOnce := false cmd.StartOnce.Do(func() { cmd.WaitOnce.Do(func() { cmd.State = Invalidated cmd.StatusCode = -2 cmd.Err = errors.New("invalidated") lg.Debugf("Cmd: Invalidating %v\n", cmd.JobID) close(cmd.Finished) }) close(cmd.Started) usCallingStartOnce = true }) if !usCallingStartOnce { // It was cmd.Start() that called StartOnce.Do(), not us, // thus we need to wait for Started and try to Kill again: <-cmd.Started cmd.Kill() } } return cmd.Err }
func TestDeath(t *testing.T) { defer log.Flush() Convey("Validate death happens cleanly", t, func() { death := NewDeath(syscall.SIGTERM) syscall.Kill(os.Getpid(), syscall.SIGTERM) death.WaitForDeath() }) Convey("Validate death happens with other signals", t, func() { death := NewDeath(syscall.SIGHUP) closeMe := &CloseMe{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(closeMe) So(closeMe.Closed, ShouldEqual, 1) }) Convey("Validate death gives up after timeout", t, func() { death := NewDeath(syscall.SIGHUP) death.setTimeout(10 * time.Millisecond) neverClose := &neverClose{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(neverClose) }) Convey("Validate death uses new logger", t, func() { death := NewDeath(syscall.SIGHUP) closeMe := &CloseMe{} logger := &MockLogger{} death.setLogger(logger) syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(closeMe) So(closeMe.Closed, ShouldEqual, 1) So(logger.Logs, ShouldNotBeEmpty) }) Convey("Close multiple things with one that fails the timer", t, func() { death := NewDeath(syscall.SIGHUP) death.setTimeout(10 * time.Millisecond) neverClose := &neverClose{} closeMe := &CloseMe{} syscall.Kill(os.Getpid(), syscall.SIGHUP) death.WaitForDeath(neverClose, closeMe) So(closeMe.Closed, ShouldEqual, 1) }) }
func (api *Api) HandleRequest(writer http.ResponseWriter, response *http.Request) { for _, pid := range api.Options.Pids { for _, signal := range api.Options.ConvertedSignals() { if err := syscall.Kill(pid, signal); err == nil { fmt.Printf("Process %v %v\n", pid, signal) break } } } io.WriteString(writer, "Bundy has killed again!\n") if api.Options.Suicide { go syscall.Kill(syscall.Getpid(), syscall.SIGTERM) } }
//Called by backup //Kills the parent of the backup func killParent(ppid int) { if ppid != os.Getppid() { log.Println("Main dead. Backup now belongs to pid:", os.Getppid()) } else { log.Println("Missing signals, shutting down main for restart") syscall.Kill(ppid, syscall.SIGINT) <-time.After(300 * time.Millisecond) if ppid == os.Getppid() { syscall.Kill(ppid, syscall.SIGKILL) } } log.Println("Backup going down") return }
// Test that Stop cancels the channel's registrations. func TestStop(t *testing.T) { sigs := []syscall.Signal{ syscall.SIGWINCH, syscall.SIGHUP, syscall.SIGUSR1, } for _, sig := range sigs { // Send the signal. // If it's SIGWINCH, we should not see it. // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. if sig == syscall.SIGWINCH || (sig == syscall.SIGHUP && *sendUncaughtSighup == 1) { syscall.Kill(syscall.Getpid(), sig) } time.Sleep(100 * time.Millisecond) // Ask for signal c := make(chan os.Signal, 1) Notify(c, sig) defer Stop(c) // Send this process that signal syscall.Kill(syscall.Getpid(), sig) waitSig(t, c, sig) Stop(c) select { case s := <-c: t.Fatalf("unexpected signal %v", s) case <-time.After(100 * time.Millisecond): // nothing to read - good } // Send the signal. // If it's SIGWINCH, we should not see it. // If it's SIGHUP, maybe we'll die. Let the flag tell us what to do. if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 { syscall.Kill(syscall.Getpid(), sig) } select { case s := <-c: t.Fatalf("unexpected signal %v", s) case <-time.After(100 * time.Millisecond): // nothing to read - good } } }
func TestWatchExit(t *testing.T) { if skipTest(t) { return } tw := newTestWatcher(t) cmd := startSleepCommand(t) childPid := cmd.Process.Pid // watch for exit event of our child process if err := tw.watcher.Watch(childPid, PROC_EVENT_EXIT); err != nil { t.Error(err) } // kill our child process, triggers exit event syscall.Kill(childPid, syscall.SIGTERM) cmd.Wait() tw.close() expectEvents(t, 0, "forks", tw.events.forks) expectEvents(t, 0, "execs", tw.events.execs) if expectEvents(t, 1, "exits", tw.events.exits) { expectEventPid(t, "exit", childPid, tw.events.exits[0]) } }
// CloseParent starts the close process in the parent. This does not wait for // the parent to close and simply sends it the TERM signal. func (p *Process) CloseParent() error { ppid := os.Getppid() if ppid == 1 { // init provided sockets, for example systemd return nil } return syscall.Kill(ppid, syscall.SIGTERM) }
func TestReload_sighup(t *testing.T) { template := test.CreateTempfile([]byte("initial value"), t) defer test.DeleteTempfile(template, t) out := test.CreateTempfile(nil, t) defer test.DeleteTempfile(out, t) outStream := gatedio.NewByteBuffer() cli := NewCLI(outStream, outStream) command := fmt.Sprintf("consul-template -template %s:%s", template.Name(), out.Name()) args := strings.Split(command, " ") go func(args []string) { if exit := cli.Run(args); exit != 0 { t.Fatalf("bad exit code: %d", exit) } }(args) defer cli.stop() // Ensure we have run at least once test.WaitForFileContents(out.Name(), []byte("initial value"), t) newValue := []byte("new value") ioutil.WriteFile(template.Name(), newValue, 0644) syscall.Kill(syscall.Getpid(), syscall.SIGHUP) test.WaitForFileContents(out.Name(), []byte("new value"), t) }
func (container *Container) Kill() error { if !container.IsRunning() { return nil } // 1. Send SIGKILL if err := container.killPossiblyDeadProcess(9); err != nil { return err } // 2. Wait for the process to die, in last resort, try to kill the process directly if _, err := container.WaitStop(10 * time.Second); err != nil { // Ensure that we don't kill ourselves if pid := container.GetPid(); pid != 0 { log.Infof("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", common.TruncateID(container.ID)) if err := syscall.Kill(pid, 9); err != nil { if err != syscall.ESRCH { return err } log.Debugf("Cannot kill process (pid=%d) with signal 9: no such process.", pid) } } } container.WaitStop(-1 * time.Second) return nil }
func (p *setnsProcess) signal(sig os.Signal) error { s, ok := sig.(syscall.Signal) if !ok { return errors.New("os: unsupported signal type") } return syscall.Kill(p.pid(), s) }
// Test that SIGCONT works (issue 8953). func TestSIGCONT(t *testing.T) { c := make(chan os.Signal, 1) Notify(c, syscall.SIGCONT) defer Stop(c) syscall.Kill(syscall.Getpid(), syscall.SIGCONT) waitSig(t, c, syscall.SIGCONT) }
// CloseParentService Send TERM signal to old service processor. func (gs *GraceServer) CloseParentServer() error { parentPID := os.Getppid() if parentPID == 1 { return nil } return syscall.Kill(parentPID, syscall.SIGQUIT) }
/* Kill a process group */ func killProcessGroup(pid int) { if DEBUG { log.Printf("Debug: killProcessGroup( %d )\n", pid) } syscall.Kill(-pid, syscall.SIGHUP) }