-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
arelo_unix.go
73 lines (65 loc) · 1.73 KB
/
arelo_unix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//go:build unix
package main
import (
"fmt"
"os"
"os/exec"
"os/signal"
"strings"
"syscall"
)
func parseSignalOption(str string) (os.Signal, string) {
switch strings.ToUpper(str) {
case "1", "HUP", "SIGHUP", "SIG_HUP":
return syscall.SIGHUP, "SIGHUP"
case "2", "INT", "SIGINT", "SIG_INT":
return syscall.SIGINT, "SIGINT"
case "3", "QUIT", "SIGQUIT", "SIG_QUIT":
return syscall.SIGQUIT, "SIGQUIT"
case "9", "KILL", "SIGKILL", "SIG_KILL":
return syscall.SIGKILL, "SIGKILL"
case "10", "USR1", "SIGUSR1", "SIG_USR1":
return syscall.SIGUSR1, "SIGUSR1"
case "12", "USR2", "SIGUSR2", "SIG_USR2":
return syscall.SIGUSR2, "SIGUSR2"
case "15", "TERM", "SIGTERM", "SIG_TERM", "":
return syscall.SIGTERM, "SIGTERM"
case "28", "WINCH", "SIGWINCH", "SIG_WINCH":
return syscall.SIGWINCH, "SIGWINCH"
}
return nil, fmt.Sprintf("unspported signal: %s", str)
}
// makeChildDoneChan returns a chan that notifies the child process has exited.
//
// On UNIX like OS, it is notified by SIGCHLD.
func makeChildDoneChan() <-chan struct{} {
c := make(chan struct{}, 1)
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGCHLD)
for {
<-sig
select {
case c <- struct{}{}:
default:
}
}
}()
return c
}
func prepareCommand(cmd []string) *exec.Cmd {
c := exec.Command(cmd[0], cmd[1:]...)
c.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
return c
}
func waitCmd(cmd *exec.Cmd) error {
return cmd.Wait()
}
func killChilds(c *exec.Cmd, sig syscall.Signal) error {
err := syscall.Kill(-c.Process.Pid, sig)
if err == nil && sig != syscall.SIGKILL && sig != syscall.SIGCONT {
// prosess can be stopped, so it must be start by SIGCONT.
err = syscall.Kill(-c.Process.Pid, syscall.SIGCONT)
}
return err
}