Skip to content

Commit 94d4929

Browse files
committed
cli/streams: Out, In: preserve original os.File when available
Preserve the original *os.File, if available, and add a File() method to return it. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 2cc9fe1 commit 94d4929

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

cli/streams/in.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package streams
33
import (
44
"errors"
55
"io"
6+
"os"
67

78
"github.com/moby/term"
89
)
@@ -14,7 +15,8 @@ type In struct {
1415
cs commonStream
1516
}
1617

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

32+
// File returns the underlying *os.File if the stream was constructed from one.
33+
// If the stream was created from a non-file (e.g., a pipe, buffer, or wrapper),
34+
// the returned boolean will be false.
35+
func (i *In) File() (*os.File, bool) {
36+
return i.cs.file()
37+
}
38+
3039
// Read implements the [io.Reader] interface.
3140
func (i *In) Read(p []byte) (int, error) {
3241
return i.in.Read(p)

cli/streams/out.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package streams
22

33
import (
44
"io"
5+
"os"
56

67
"github.com/moby/term"
78
)
@@ -14,7 +15,8 @@ type Out struct {
1415
cs commonStream
1516
}
1617

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

32+
// File returns the underlying *os.File if the stream was constructed from one.
33+
// If the stream was created from a non-file (e.g., a pipe, buffer, or wrapper),
34+
// the returned boolean will be false.
35+
func (o *Out) File() (*os.File, bool) {
36+
return o.cs.file()
37+
}
38+
3039
// Write writes to the output stream.
3140
func (o *Out) Write(p []byte) (int, error) {
3241
return o.out.Write(p)

cli/streams/stream.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,21 @@ import (
1111
)
1212

1313
func newCommonStream(stream any) commonStream {
14+
var f *os.File
15+
if v, ok := stream.(*os.File); ok {
16+
f = v
17+
}
18+
1419
fd, tty := term.GetFdInfo(stream)
1520
return commonStream{
21+
f: f,
1622
fd: fd,
1723
tty: tty,
1824
}
1925
}
2026

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

37+
// file returns the underlying *os.File if the stream was constructed from one.
38+
func (s *commonStream) file() (*os.File, bool) { return s.f, s.f != nil }
39+
3040
// isTerminal returns whether this stream is connected to a terminal.
3141
func (s *commonStream) isTerminal() bool { return s.tty }
3242

0 commit comments

Comments
 (0)