From ff85932af903df83d21e6394ab408863ccf4a845 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 25 Feb 2019 16:00:14 -0700 Subject: [PATCH 1/2] cli: fix ignoring std{out,err} sync errors on windows Apparently, windows returns "invalid file handle" and golang doesn't translate this to EINVAL. fixes ipfs/go-ipfs#6021 --- cli/error.go | 13 +++++++++++++ cli/error_posix.go | 15 +++++++++++++++ cli/error_windows.go | 17 +++++++++++++++++ cli/responseemitter.go | 18 ++++-------------- 4 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 cli/error.go create mode 100644 cli/error_posix.go create mode 100644 cli/error_windows.go diff --git a/cli/error.go b/cli/error.go new file mode 100644 index 00000000..92fe7278 --- /dev/null +++ b/cli/error.go @@ -0,0 +1,13 @@ +package cli + +import ( + "os" +) + +func isSyncNotSupportedErr(err error) bool { + perr, ok := err.(*os.PathError) + if !ok { + return false + } + return perr.Op == "sync" && isErrnoNotSupported(perr.Err) +} diff --git a/cli/error_posix.go b/cli/error_posix.go new file mode 100644 index 00000000..f9d52a3a --- /dev/null +++ b/cli/error_posix.go @@ -0,0 +1,15 @@ +//+build !windows + +package cli + +import ( + "syscall" +) + +func isErrnoNotSupported(err error) bool { + switch err { + case syscall.EINVAL, syscall.ENOTSUP: + return true + } + return false +} diff --git a/cli/error_windows.go b/cli/error_windows.go new file mode 100644 index 00000000..0c882846 --- /dev/null +++ b/cli/error_windows.go @@ -0,0 +1,17 @@ +//+build windows + +package cli + +import ( + "syscall" +) + +const invalid_file_handle syscall.Errno = 0x6 + +func isErrnoNotSupported(err error) bool { + switch err { + case syscall.EINVAL, syscall.ENOTSUP, invalid_file_handle: + return true + } + return false +} diff --git a/cli/responseemitter.go b/cli/responseemitter.go index 6b882f04..86c98f09 100644 --- a/cli/responseemitter.go +++ b/cli/responseemitter.go @@ -6,7 +6,6 @@ import ( "io" "os" "sync" - "syscall" "github.com/ipfs/go-ipfs-cmds" ) @@ -101,17 +100,6 @@ func (re *responseEmitter) CloseWithError(err error) error { re.stderr = nil }() - // ignore error if the operating system doesn't support syncing std{out,err} - ignoreError := func(err error) bool { - if perr, ok := err.(*os.PathError); ok && - perr.Op == "sync" && (perr.Err == syscall.EINVAL || - perr.Err == syscall.ENOTSUP) { - return true - } - - return false - } - var errStderr, errStdout error if f, ok := re.stderr.(*os.File); ok { errStderr = f.Sync() @@ -119,10 +107,12 @@ func (re *responseEmitter) CloseWithError(err error) error { if f, ok := re.stdout.(*os.File); ok { errStdout = f.Sync() } - if errStderr != nil && !ignoreError(errStderr) { + + // ignore error if the operating system doesn't support syncing std{out,err} + if errStderr != nil && !isSyncNotSupportedErr(errStderr) { return errStderr } - if errStdout != nil && !ignoreError(errStdout) { + if errStdout != nil && !isSyncNotSupportedErr(errStdout) { return errStdout } return nil From 9d994fb30ce9a3a3c0d192613a967f38395840a2 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 25 Feb 2019 16:03:21 -0700 Subject: [PATCH 2/2] docs: document cli.NewResponseEmitter --- cli/responseemitter.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli/responseemitter.go b/cli/responseemitter.go index 86c98f09..db46a907 100644 --- a/cli/responseemitter.go +++ b/cli/responseemitter.go @@ -12,6 +12,8 @@ import ( var _ ResponseEmitter = &responseEmitter{} +// NewResponseEmitter constructs a new response emitter that writes results to +// the console. func NewResponseEmitter(stdout, stderr io.Writer, req *cmds.Request) (ResponseEmitter, error) { encType, enc, err := cmds.GetEncoder(req, stdout, cmds.TextNewline)