From 4c5ebfee96b4c6a82ca06c0004bb554a9465be34 Mon Sep 17 00:00:00 2001 From: Cody Roseborough Date: Mon, 19 Feb 2018 22:29:31 +0000 Subject: [PATCH] Fix panics in cio/io_unix.go Add nil checks before closing fifos to avoid panic when fifo was never opened. Signed-off-by: Cody Roseborough --- cio/io_unix.go | 13 ++++++++++--- cio/io_unix_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 cio/io_unix_test.go diff --git a/cio/io_unix.go b/cio/io_unix.go index 1eadcd50a..0f53cbbd8 100644 --- a/cio/io_unix.go +++ b/cio/io_unix.go @@ -98,17 +98,24 @@ func openFifos(ctx context.Context, fifos *FIFOSet) (pipes, error) { if f.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return f, errors.Wrapf(err, "failed to open stdin fifo") } + defer func() { + if err != nil && f.Stdin != nil { + f.Stdin.Close() + } + }() } if fifos.Stdout != "" { if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() return f, errors.Wrapf(err, "failed to open stdout fifo") } + defer func() { + if err != nil && f.Stdout != nil { + f.Stdout.Close() + } + }() } if fifos.Stderr != "" { if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() - f.Stdout.Close() return f, errors.Wrapf(err, "failed to open stderr fifo") } } diff --git a/cio/io_unix_test.go b/cio/io_unix_test.go new file mode 100644 index 000000000..081dca910 --- /dev/null +++ b/cio/io_unix_test.go @@ -0,0 +1,41 @@ +// +build !windows + +package cio + +import ( + "context" + "path/filepath" + "testing" + + "github.com/gotestyourself/gotestyourself/assert" +) + +func TestOpenFifos(t *testing.T) { + scenarios := []*FIFOSet{ + { + Config: Config{ + Stdin: "", + Stdout: filepath.Join("This/does/not/exist", "test-stdout"), + Stderr: filepath.Join("This/does/not/exist", "test-stderr"), + }, + }, + { + Config: Config{ + Stdin: filepath.Join("This/does/not/exist", "test-stdin"), + Stdout: "", + Stderr: filepath.Join("This/does/not/exist", "test-stderr"), + }, + }, + { + Config: Config{ + Stdin: "", + Stdout: "", + Stderr: filepath.Join("This/does/not/exist", "test-stderr"), + }, + }, + } + for _, scenario := range scenarios { + _, err := openFifos(context.Background(), scenario) + assert.Assert(t, err != nil, scenario) + } +}