mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #50612 from thaJeztah/stdcopy_clean
apk/pkg/stdcopy: remove use of `iota`, improve docs, and add example
This commit is contained in:
@@ -14,16 +14,13 @@ import (
|
||||
type StdType byte
|
||||
|
||||
const (
|
||||
// Stdin represents standard input stream type.
|
||||
Stdin StdType = iota
|
||||
// Stdout represents standard output stream type.
|
||||
Stdout
|
||||
// Stderr represents standard error steam type.
|
||||
Stderr
|
||||
// Systemerr represents errors originating from the system that make it
|
||||
// into the multiplexed stream.
|
||||
Systemerr
|
||||
Stdin StdType = 0 // Stdin represents standard input stream. It is present for completeness and should NOT be used. When reading the stream with [StdCopy] it is output on [Stdout].
|
||||
Stdout StdType = 1 // Stdout represents standard output stream.
|
||||
Stderr StdType = 2 // Stderr represents standard error steam.
|
||||
Systemerr StdType = 3 // Systemerr represents errors originating from the system. When reading the stream with [StdCopy] it is returned as an error.
|
||||
)
|
||||
|
||||
const (
|
||||
stdWriterPrefixLen = 8
|
||||
stdWriterFdIndex = 0
|
||||
stdWriterSizeIndex = 4
|
||||
@@ -75,9 +72,20 @@ func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
// stream "w".
|
||||
//
|
||||
// Writers created through NewStdWriter allow for multiple write streams
|
||||
// (e.g. stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// single connection. "streamType" indicates the type of stream to encapsulate,
|
||||
// and can be [Stdin], [Stdout], pr [Stderr].
|
||||
// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to
|
||||
// include server-side errors in the stream. Information on this stream
|
||||
// is returned as an error by [StdCopy] and terminates processing the
|
||||
// stream.
|
||||
//
|
||||
// The [Stdin] stream is present for completeness and should generally
|
||||
// NOT be used. It is output on [Stdout] when reading the stream with
|
||||
// [StdCopy].
|
||||
//
|
||||
// All streams must share the same underlying [io.Writer] to ensure proper
|
||||
// multiplexing. Each call to NewStdWriter wraps that shared writer with
|
||||
// a header indicating the target stream.
|
||||
func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
return &stdWriter{
|
||||
Writer: w,
|
||||
@@ -94,11 +102,15 @@ func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
// [NewStdWriter].
|
||||
//
|
||||
// As it reads from "multiplexedSource", StdCopy writes [Stdout] messages
|
||||
// to "destOut", and [Stderr] message to "destErr].
|
||||
// to "destOut", and [Stderr] message to "destErr]. For backward-compatibility,
|
||||
// [Stdin] messages are output to "destOut". The [Systemerr] stream provides
|
||||
// errors produced by the daemon. It is returned as an error, and terminates
|
||||
// processing the stream.
|
||||
//
|
||||
// StdCopy it reads until it hits [io.EOF] on "multiplexedSource", after
|
||||
// which it returns a nil error. In other words: any error returned indicates
|
||||
// a real underlying error.
|
||||
// a real underlying error, which may be when an unknown [StdType] stream
|
||||
// is received.
|
||||
//
|
||||
// The "written" return holds the total number of bytes written to "destOut"
|
||||
// and "destErr" combined.
|
||||
@@ -129,8 +141,8 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
}
|
||||
}
|
||||
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
// Check the first byte to know where to write
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
switch stream {
|
||||
case Stdin:
|
||||
fallthrough
|
||||
@@ -146,7 +158,7 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
// to outstream if Systemerr is the stream
|
||||
out = nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unrecognized input header: %d", buf[stdWriterFdIndex])
|
||||
return 0, fmt.Errorf("unrecognized stream: %d", stream)
|
||||
}
|
||||
|
||||
// Retrieve the size of the frame
|
||||
|
||||
66
api/pkg/stdcopy/stdcopy_example_test.go
Normal file
66
api/pkg/stdcopy/stdcopy_example_test.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package stdcopy_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/moby/moby/api/pkg/stdcopy"
|
||||
)
|
||||
|
||||
func ExampleNewStdWriter() {
|
||||
muxReader, muxStream := io.Pipe()
|
||||
defer func() { _ = muxStream.Close() }()
|
||||
|
||||
// Start demuxing before the daemon starts writing.
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
// using os.Stdout for both, otherwise output doesn't show up in the example.
|
||||
osStdout := os.Stdout
|
||||
osStderr := os.Stdout
|
||||
_, err := stdcopy.StdCopy(osStdout, osStderr, muxReader)
|
||||
done <- err
|
||||
}()
|
||||
|
||||
// daemon writing to stdout, stderr, and systemErr.
|
||||
stdout := stdcopy.NewStdWriter(muxStream, stdcopy.Stdout)
|
||||
stderr := stdcopy.NewStdWriter(muxStream, stdcopy.Stderr)
|
||||
systemErr := stdcopy.NewStdWriter(muxStream, stdcopy.Systemerr)
|
||||
|
||||
for range 10 {
|
||||
_, _ = fmt.Fprintln(stdout, "hello from stdout")
|
||||
_, _ = fmt.Fprintln(stderr, "hello from stderr")
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
_, _ = fmt.Fprintln(systemErr, errors.New("something went wrong"))
|
||||
|
||||
// Wait for the demuxer to finish.
|
||||
if err := <-done; err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// hello from stdout
|
||||
// hello from stderr
|
||||
// error from daemon in stream: something went wrong
|
||||
}
|
||||
42
vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go
generated
vendored
42
vendor/github.com/moby/moby/api/pkg/stdcopy/stdcopy.go
generated
vendored
@@ -14,16 +14,13 @@ import (
|
||||
type StdType byte
|
||||
|
||||
const (
|
||||
// Stdin represents standard input stream type.
|
||||
Stdin StdType = iota
|
||||
// Stdout represents standard output stream type.
|
||||
Stdout
|
||||
// Stderr represents standard error steam type.
|
||||
Stderr
|
||||
// Systemerr represents errors originating from the system that make it
|
||||
// into the multiplexed stream.
|
||||
Systemerr
|
||||
Stdin StdType = 0 // Stdin represents standard input stream. It is present for completeness and should NOT be used. When reading the stream with [StdCopy] it is output on [Stdout].
|
||||
Stdout StdType = 1 // Stdout represents standard output stream.
|
||||
Stderr StdType = 2 // Stderr represents standard error steam.
|
||||
Systemerr StdType = 3 // Systemerr represents errors originating from the system. When reading the stream with [StdCopy] it is returned as an error.
|
||||
)
|
||||
|
||||
const (
|
||||
stdWriterPrefixLen = 8
|
||||
stdWriterFdIndex = 0
|
||||
stdWriterSizeIndex = 4
|
||||
@@ -75,9 +72,20 @@ func (w *stdWriter) Write(p []byte) (int, error) {
|
||||
// stream "w".
|
||||
//
|
||||
// Writers created through NewStdWriter allow for multiple write streams
|
||||
// (e.g. stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// (e.g., stdout ([Stdout]) and stderr ([Stderr]) to be multiplexed into a
|
||||
// single connection. "streamType" indicates the type of stream to encapsulate,
|
||||
// and can be [Stdin], [Stdout], pr [Stderr].
|
||||
// commonly, [Stdout] or [Stderr]. The [Systemerr] stream can be used to
|
||||
// include server-side errors in the stream. Information on this stream
|
||||
// is returned as an error by [StdCopy] and terminates processing the
|
||||
// stream.
|
||||
//
|
||||
// The [Stdin] stream is present for completeness and should generally
|
||||
// NOT be used. It is output on [Stdout] when reading the stream with
|
||||
// [StdCopy].
|
||||
//
|
||||
// All streams must share the same underlying [io.Writer] to ensure proper
|
||||
// multiplexing. Each call to NewStdWriter wraps that shared writer with
|
||||
// a header indicating the target stream.
|
||||
func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
return &stdWriter{
|
||||
Writer: w,
|
||||
@@ -94,11 +102,15 @@ func NewStdWriter(w io.Writer, streamType StdType) io.Writer {
|
||||
// [NewStdWriter].
|
||||
//
|
||||
// As it reads from "multiplexedSource", StdCopy writes [Stdout] messages
|
||||
// to "destOut", and [Stderr] message to "destErr].
|
||||
// to "destOut", and [Stderr] message to "destErr]. For backward-compatibility,
|
||||
// [Stdin] messages are output to "destOut". The [Systemerr] stream provides
|
||||
// errors produced by the daemon. It is returned as an error, and terminates
|
||||
// processing the stream.
|
||||
//
|
||||
// StdCopy it reads until it hits [io.EOF] on "multiplexedSource", after
|
||||
// which it returns a nil error. In other words: any error returned indicates
|
||||
// a real underlying error.
|
||||
// a real underlying error, which may be when an unknown [StdType] stream
|
||||
// is received.
|
||||
//
|
||||
// The "written" return holds the total number of bytes written to "destOut"
|
||||
// and "destErr" combined.
|
||||
@@ -129,8 +141,8 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
}
|
||||
}
|
||||
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
// Check the first byte to know where to write
|
||||
stream := StdType(buf[stdWriterFdIndex])
|
||||
switch stream {
|
||||
case Stdin:
|
||||
fallthrough
|
||||
@@ -146,7 +158,7 @@ func StdCopy(destOut, destErr io.Writer, multiplexedSource io.Reader) (written i
|
||||
// to outstream if Systemerr is the stream
|
||||
out = nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unrecognized input header: %d", buf[stdWriterFdIndex])
|
||||
return 0, fmt.Errorf("unrecognized stream: %d", stream)
|
||||
}
|
||||
|
||||
// Retrieve the size of the frame
|
||||
|
||||
Reference in New Issue
Block a user