package main import ( "context" "fmt" "os" "os/exec" "strconv" "syscall" "time" ) func main() { if len(os.Args) < 3 { fmt.Fprintf(os.Stderr, "Usage: %s \n", os.Args[0]) os.Exit(1) } timeout, err := strconv.ParseUint(os.Args[1], 10, 32) if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) defer cancel() cmd := exec.CommandContext(ctx, os.Args[2], os.Args[3:]...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Start() if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) } err = cmd.Wait() if err != nil { if ctx.Err() != nil { os.Exit(124) } else { exitErr, ok := err.(*exec.ExitError) if !ok { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(255) } waits, ok := exitErr.Sys().(syscall.WaitStatus) if !ok { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(255) } os.Exit(waits.ExitStatus()) } } else { os.Exit(0) } }