From ffcb7afbeee1cafdc6db0b72f7145442f922c51a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 2 Jun 2013 19:03:26 -0700 Subject: [PATCH] provisioner/shell: Properly handle closed channels in select --- provisioner/shell/provisioner.go | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 2795b1da9..864afca09 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -64,25 +64,38 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) { stderr := cmd.StderrChan() stdout := cmd.StdoutChan() +OutputLoop: for { select { - case output := <-stderr: - ui.Say(output) - case output := <-stdout: - ui.Say(output) + case output, ok := <-stderr: + if !ok { + stderr = nil + } else { + ui.Say(output) + } + case output, ok := <-stdout: + if !ok { + stdout = nil + } else { + ui.Say(output) + } case exitStatus := <-exit: log.Printf("shell provisioner exited with status %d", exitStatus) - break + break OutputLoop } } // Make sure we finish off stdout/stderr because we may have gotten // a message from the exit channel first. - for output := range stdout { - ui.Say(output) + if stdout != nil { + for output := range stdout { + ui.Say(output) + } } - for output := range stderr { - ui.Say(output) + if stderr != nil { + for output := range stderr { + ui.Say(output) + } } }