56 lines
920 B
Go
56 lines
920 B
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"os/signal"
|
|
"syscall"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) <= 1 {
|
|
exitErr("Usage: parent <command> [<args>...]")
|
|
}
|
|
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c)
|
|
|
|
cmd := exec.Command(os.Args[1], os.Args[2:]...)
|
|
cmd.Stdin = os.Stdin
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Env = os.Environ()
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
exitErr(err)
|
|
}
|
|
|
|
go func() {
|
|
for sig := range c {
|
|
cmd.Process.Signal(sig)
|
|
}
|
|
}()
|
|
|
|
if err := cmd.Wait(); err != nil {
|
|
var e *exec.ExitError
|
|
if errors.As(err, &e) {
|
|
if e.ProcessState.Exited() {
|
|
os.Exit(e.ProcessState.ExitCode())
|
|
} else {
|
|
status, ok := e.ProcessState.Sys().(syscall.WaitStatus)
|
|
if ok && status.Signaled() {
|
|
os.Exit(128 + int(status.Signal()))
|
|
}
|
|
}
|
|
}
|
|
exitErr(err)
|
|
}
|
|
}
|
|
|
|
func exitErr(errs ...interface{}) {
|
|
fmt.Fprintln(os.Stderr, errs...)
|
|
os.Exit(1)
|
|
}
|