From 457c0066aeb073638a7ec42107a69e5406703b9b Mon Sep 17 00:00:00 2001 From: dreid Date: Thu, 20 Feb 2020 20:41:59 -0800 Subject: [PATCH] Simplify subprocess IO management. The previous version used two goroutines calling `io.Copy`. Unfortunately it did not check the return value of `io.Copy` and in production we saw some hangs which looked like they might be caused if one or both `io.Copy`s failed but `cmd.Wait` didn't return. This version is much simpler and just hooks up the parent's Stdout/Stderr to the child's Stdout/Stderr directly. --- cmd_cmd.go | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/cmd_cmd.go b/cmd_cmd.go index 240aa42..2b0f195 100644 --- a/cmd_cmd.go +++ b/cmd_cmd.go @@ -3,7 +3,6 @@ package main import ( "crypto/rand" "fmt" - "io" "os" "os/exec" "strings" @@ -91,26 +90,8 @@ func runCommand(subcmd string) error { fmt.Println("running /bin/bash -c", subcmd) cmd := exec.Command("/bin/bash", "-c", subcmd) - outReader, err := cmd.StdoutPipe() - if err != nil { - return err - } - errReader, err := cmd.StderrPipe() - if err != nil { - return err - } - - err = cmd.Start() - if err != nil { - return err - } - - go func() { - io.Copy(os.Stdout, outReader) - }() - go func() { - io.Copy(os.Stderr, errReader) - }() + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr - return cmd.Wait() + return cmd.Run() }