Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cli/streams/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package streams
import (
"errors"
"io"
"os"

"github.com/moby/term"
)
Expand All @@ -14,7 +15,8 @@ type In struct {
cs commonStream
}

// NewIn returns a new [In] from an [io.ReadCloser].
// NewIn returns a new [In] from an [io.ReadCloser]. If in is an [*os.File],
// a reference is kept to the file, and accessible through [In.File].
func NewIn(in io.ReadCloser) *In {
return &In{
in: in,
Expand All @@ -27,6 +29,13 @@ func (i *In) FD() uintptr {
return i.cs.fd
}

// File returns the underlying *os.File if the stream was constructed from one.
// If the stream was created from a non-file (e.g., a pipe, buffer, or wrapper),
// the returned boolean will be false.
func (i *In) File() (*os.File, bool) {
return i.cs.file()
}

// Read implements the [io.Reader] interface.
func (i *In) Read(p []byte) (int, error) {
return i.in.Read(p)
Expand Down
11 changes: 10 additions & 1 deletion cli/streams/out.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package streams

import (
"io"
"os"

"github.com/moby/term"
)
Expand All @@ -14,7 +15,8 @@ type Out struct {
cs commonStream
}

// NewOut returns a new [Out] from an [io.Writer].
// NewOut returns a new [Out] from an [io.Writer]. If out is an [*os.File],
// a reference is kept to the file, and accessible through [Out.File].
func NewOut(out io.Writer) *Out {
return &Out{
out: out,
Expand All @@ -27,6 +29,13 @@ func (o *Out) FD() uintptr {
return o.cs.FD()
}

// File returns the underlying *os.File if the stream was constructed from one.
// If the stream was created from a non-file (e.g., a pipe, buffer, or wrapper),
// the returned boolean will be false.
func (o *Out) File() (*os.File, bool) {
return o.cs.file()
}

// Write writes to the output stream.
func (o *Out) Write(p []byte) (int, error) {
return o.out.Write(p)
Expand Down
10 changes: 10 additions & 0 deletions cli/streams/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@ import (
)

func newCommonStream(stream any) commonStream {
var f *os.File
if v, ok := stream.(*os.File); ok {
f = v
}

fd, tty := term.GetFdInfo(stream)
return commonStream{
f: f,
fd: fd,
tty: tty,
}
}

type commonStream struct {
f *os.File
fd uintptr
tty bool
state *term.State
Expand All @@ -27,6 +34,9 @@ type commonStream struct {
// FD returns the file descriptor number for this stream.
func (s *commonStream) FD() uintptr { return s.fd }

// file returns the underlying *os.File if the stream was constructed from one.
func (s *commonStream) file() (*os.File, bool) { return s.f, s.f != nil }

// isTerminal returns whether this stream is connected to a terminal.
func (s *commonStream) isTerminal() bool { return s.tty }

Expand Down
Loading