There are three ways of executing a program in Go:
- syscallpackage with syscall.Exec, syscall.ForkExec, syscall.StartProcess
- ospackage with os.StartProcess
- os/execpackage with exec.Command
syscall.StartProcess is low level. It returns a uintptr as a handle.
os.StartProcess gives you a nice os.Process struct that you can call Signal on. os/exec gives you io.ReaderWriter to use on a pipe. Both use syscall internally.
Reading signals sent from a process other than your own seems a bit tricky. If it was possible, syscall would be able to do it. I don't see anything obvious in the higher level packages.
To receive a signal you can use signal.Notify like this:
sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
    syscall.SIGHUP,
    syscall.SIGINT,
    syscall.SIGTERM,
    syscall.SIGQUIT)
go func() {
    s := <-sigc
    // ... do something ...
}()
You just need to change the signals you're interested in listening to. If you don't specify a signal, it'll catch all the signals that can be captured.
You would use syscall.Kill or Process.Signal to map the signal. You can get the pid from Process.Pid or as a result from syscall.StartProcess.