diff --git a/integration/execin_test.go b/integration/execin_test.go index 3a1c5387..92a1ae0f 100644 --- a/integration/execin_test.go +++ b/integration/execin_test.go @@ -122,3 +122,54 @@ func TestExecInRlimit(t *testing.T) { t.Fatalf("expected rlimit to be 1024, got %s", limit) } } + +func TestExecInError(t *testing.T) { + if testing.Short() { + return + } + rootfs, err := newRootfs() + if err != nil { + t.Fatal(err) + } + defer remove(rootfs) + config := newTemplateConfig(rootfs) + container, err := newContainer(config) + if err != nil { + t.Fatal(err) + } + defer container.Destroy() + + // Execute a first process in the container + stdinR, stdinW, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + process := &libcontainer.Process{ + Args: []string{"cat"}, + Env: standardEnvironment, + Stdin: stdinR, + } + err = container.Start(process) + stdinR.Close() + defer func() { + stdinW.Close() + if _, err := process.Wait(); err != nil { + t.Log(err) + } + }() + if err != nil { + t.Fatal(err) + } + + unexistent := &libcontainer.Process{ + Args: []string{"unexistent"}, + Env: standardEnvironment, + } + err = container.Start(unexistent) + if err == nil { + t.Fatal("Should be an error") + } + if !strings.Contains(err.Error(), "executable file not found") { + t.Fatalf("Should be error about not found executable, got %s", err) + } +} diff --git a/process_linux.go b/process_linux.go index 5b6df152..5aab5a7f 100644 --- a/process_linux.go +++ b/process_linux.go @@ -61,6 +61,19 @@ func (p *setnsProcess) start() (err error) { if err := json.NewEncoder(p.parentPipe).Encode(p.config); err != nil { return newSystemError(err) } + if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil { + return newSystemError(err) + } + // wait for the child process to fully complete and receive an error message + // if one was encoutered + var ierr *genericError + if err := json.NewDecoder(p.parentPipe).Decode(&ierr); err != nil && err != io.EOF { + return newSystemError(err) + } + if ierr != nil { + return newSystemError(ierr) + } + return nil }