diff --git a/cmd_signal.go b/cmd_signal.go new file mode 100644 index 0000000..3b258c8 --- /dev/null +++ b/cmd_signal.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/DarthSim/overmind/v2/utils" + "github.com/urfave/cli" +) + +type cmdSignalHandler struct{ dialer } + +func (h *cmdSignalHandler) Run(c *cli.Context) error { + if len(c.Args()) < 1 { + utils.Fatal("Signal name is required") + } + + conn, err := h.Dial() + utils.FatalOnErr(err) + + fmt.Fprintf(conn, "signal %v\n", strings.Join(c.Args(), " ")) + + return nil +} diff --git a/main.go b/main.go index 8ad8f56..beaafc8 100644 --- a/main.go +++ b/main.go @@ -125,6 +125,18 @@ func setupQuitCmd() cli.Command { } } +func setupSignalCmd() cli.Command { + c := cmdSignalHandler{} + + return cli.Command{ + Name: "signal", + Usage: "Send a signal to specified processes (or all if none specified)", + Action: c.Run, + ArgsUsage: " [process name...]", + Flags: socketFlags(&c.SocketPath, &c.Network), + } +} + func setupKillCmd() cli.Command { c := cmdKillHandler{} @@ -192,6 +204,7 @@ func main() { setupStartCmd(), setupRestartCmd(), setupStopCmd(), + setupSignalCmd(), setupConnectCmd(), setupQuitCmd(), setupKillCmd(), diff --git a/start/command_center.go b/start/command_center.go index b0ff77f..f3b011c 100644 --- a/start/command_center.go +++ b/start/command_center.go @@ -84,6 +84,8 @@ func (c *commandCenter) handleConnection(conn net.Conn) { c.processRestart(args) case "stop": c.processStop(args) + case "signal": + c.processSignal(args) case "quit": c.processQuit() case "kill": @@ -132,6 +134,33 @@ func (c *commandCenter) processStop(args []string) { } } +func (c *commandCenter) processSignal(args []string) { + if len(args) == 0 { + return + } + + sig, ok := signalMap[args[0]] + if !ok { + return + } + + processes := args[1:] + + for _, p := range c.cmd.processes { + if len(processes) == 0 { + p.Signal(sig) + continue + } + + for _, pattern := range processes { + if utils.WildcardMatch(pattern, p.Name) { + p.Signal(sig) + break + } + } + } +} + func (c *commandCenter) processKill() { for _, p := range c.cmd.processes { p.Kill(false) diff --git a/start/handler.go b/start/handler.go index 4244519..4f44837 100644 --- a/start/handler.go +++ b/start/handler.go @@ -16,6 +16,7 @@ import ( var signalMap = map[string]syscall.Signal{ "ABRT": syscall.SIGABRT, + "HUP": syscall.SIGHUP, "INT": syscall.SIGINT, "KILL": syscall.SIGKILL, "QUIT": syscall.SIGQUIT, diff --git a/start/process.go b/start/process.go index b18c8bd..8b5e1b9 100644 --- a/start/process.go +++ b/start/process.go @@ -130,6 +130,15 @@ func (p *process) Kill(keepAlive bool) { } } +func (p *process) Signal(sig syscall.Signal) { + if p.Running() { + p.output.WriteBoldLinef(p, "Sending signal %v...", sig) + if err := p.groupSignal(sig); err != nil { + p.output.WriteErr(p, fmt.Errorf("Can't send signal: %s", err)) + } + } +} + func (p *process) Info() { p.groupSignal(SIGINFO) }