Skip to content

Commit

Permalink
podman cp: treat /dev/stdout correctly
Browse files Browse the repository at this point in the history
/dev/stdout should not be treated as "-" to remain compatible with
Docker and to have a more consistent and idiomatic interface.

Fixes: containers#9362
Signed-off-by: Valentin Rothberg <[email protected]>
  • Loading branch information
vrothberg committed Mar 10, 2021
1 parent c67172a commit 20f2160
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
19 changes: 18 additions & 1 deletion cmd/podman/containers/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ func copyFromContainer(container string, containerPath string, hostPath string)
return err
}

isStdout := false
if hostPath == "-" {
isStdout = true
hostPath = os.Stdout.Name()
}

Expand Down Expand Up @@ -152,10 +154,16 @@ func copyFromContainer(container string, containerPath string, hostPath string)
hostBaseName = filepath.Base(hostInfo.LinkTarget)
}

if !isStdout {
if err := validateFileInfo(hostInfo); err != nil {
return errors.Wrap(err, "invalid destination")
}
}

reader, writer := io.Pipe()
hostCopy := func() error {
defer reader.Close()
if hostInfo.LinkTarget == os.Stdout.Name() {
if isStdout {
_, err := io.Copy(os.Stdout, reader)
return err
}
Expand Down Expand Up @@ -363,3 +371,12 @@ func containerParentDir(container string, containerPath string) (string, error)
workDir = filepath.Join(workDir, containerPath)
return filepath.Dir(workDir), nil
}

// validateFileInfo returns an error if the specified FileInfo doesn't point to
// a directory or a regular file.
func validateFileInfo(info *copy.FileInfo) error {
if info.Mode.IsDir() || info.Mode.IsRegular() {
return nil
}
return errors.Errorf("%q must be a directory or a regular file", info.LinkTarget)
}
4 changes: 4 additions & 0 deletions test/system/065-cp.bats
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ load helpers
run_podman exec cpcontainer sh -c "echo '$rand_content' > /tmp/file.txt"
run_podman exec cpcontainer touch /tmp/empty.txt

# Make sure that only "-" gets special treatment. "/dev/stdout"
run_podman 125 cp cpcontainer:/tmp/file.txt /dev/stdout
is "$output" 'Error: invalid destination: "/dev/stdout" must be a directory or a regular file'

# Copying from stdout will always compress. So let's copy the previously
# created file from the container via stdout, untar the archive and make
# sure the file exists with the expected content.
Expand Down

0 comments on commit 20f2160

Please sign in to comment.