You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.0 KiB
103 lines
2.0 KiB
6 years ago
|
package main
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"syscall"
|
||
|
|
||
|
"github.com/alexflint/go-arg"
|
||
|
common "source.heropunch.io/tomo/go-coreutils"
|
||
|
)
|
||
|
|
||
|
var BadSignalName = errors.New("bad signal name")
|
||
|
|
||
|
func selectSignal(signame string) (syscall.Signal, error) {
|
||
|
switch signame {
|
||
|
case "TERM":
|
||
|
return syscall.SIGTERM, nil
|
||
|
case "KILL":
|
||
|
return syscall.SIGKILL, nil
|
||
|
case "PIPE":
|
||
|
return syscall.SIGPIPE, nil
|
||
|
case "INT":
|
||
|
return syscall.SIGINT, nil
|
||
|
case "QUIT":
|
||
|
return syscall.SIGQUIT, nil
|
||
|
case "SEGV":
|
||
|
return syscall.SIGSEGV, nil
|
||
|
case "STOP":
|
||
|
return syscall.SIGSTOP, nil
|
||
|
case "CONT":
|
||
|
return syscall.SIGCONT, nil
|
||
|
case "0":
|
||
|
return 0, nil
|
||
|
case "ABRT":
|
||
|
return syscall.SIGABRT, nil
|
||
|
case "ALRM":
|
||
|
return syscall.SIGALRM, nil
|
||
|
case "BUS":
|
||
|
return syscall.SIGBUS, nil
|
||
|
case "CHLD":
|
||
|
return syscall.SIGCHLD, nil
|
||
|
case "FPE":
|
||
|
return syscall.SIGFPE, nil
|
||
|
case "HUP":
|
||
|
return syscall.SIGHUP, nil
|
||
|
case "ILL":
|
||
|
return syscall.SIGILL, nil
|
||
|
case "TSTP":
|
||
|
return syscall.SIGTSTP, nil
|
||
|
case "TTIN":
|
||
|
return syscall.SIGTTIN, nil
|
||
|
case "TTOU":
|
||
|
return syscall.SIGTTOU, nil
|
||
|
case "USR1":
|
||
|
return syscall.SIGUSR1, nil
|
||
|
case "USR2":
|
||
|
return syscall.SIGUSR2, nil
|
||
|
case "URG":
|
||
|
return syscall.SIGURG, nil
|
||
|
default:
|
||
|
return -1, BadSignalName
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
var args struct {
|
||
|
SignalName string `arg:"-s"`
|
||
|
List int `arg:"-l"`
|
||
|
PIDs []int `arg:"positional"`
|
||
|
}
|
||
|
|
||
|
args.SignalName = "TERM"
|
||
|
args.List = -1
|
||
|
|
||
|
p := arg.MustParse(&args)
|
||
|
if len(os.Args) == 1 {
|
||
|
p.WriteUsage(os.Stderr)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
|
||
|
sig, err := selectSignal(args.SignalName)
|
||
|
common.ExitIfError(err)
|
||
|
|
||
|
exitCode := 0
|
||
|
if len(args.PIDs) > 0 {
|
||
|
for _, pid := range args.PIDs {
|
||
|
process, err := os.FindProcess(pid)
|
||
|
if err != nil {
|
||
|
common.PrintToStderr(fmt.Sprintf("error finding process %v: %v", pid, err))
|
||
|
exitCode = 1
|
||
|
continue
|
||
|
}
|
||
|
err = process.Signal(sig)
|
||
|
if err != nil {
|
||
|
common.PrintToStderr(fmt.Sprintf("kill %v: %v", pid, err))
|
||
|
exitCode = 1
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
os.Exit(exitCode)
|
||
|
}
|