Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os: FileMode Device flag not set for Windows character device #23123

Closed
zosmac opened this issue Dec 13, 2017 · 10 comments
Closed

os: FileMode Device flag not set for Windows character device #23123

zosmac opened this issue Dec 13, 2017 · 10 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@zosmac
Copy link

zosmac commented Dec 13, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.9.2 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

Build on Macos High Sierra
Run on Windows 2012 R2

What did you do?

Based on this definition and comment in the os.FileMode's file mode bits:

ModeCharDevice      // c: Unix character device, when ModeDevice is set

I use this test to determine if stderr points to a terminal:
info, _ := os.Stderr.Stat()
mode := info.Mode()
isTerminal := mode&os.ModeDevice == os.ModeDevice && mode&os.ModeCharDevice == os.ModeCharDevice

On windows, only ModeCharDevice is set. I propose either that

  1. for compatibility func (file *File)Stat() set ModeDevice when syscall.FILE_TYPE_CHAR is set

  2. the different behavior be documented, e.g.

    ModeCharDevice // c: Character device (on Unix, only when ModeDevice is set)

If possible, provide a recipe for reproducing the error.

info, _ := os.Stderr.Stat()
mode := info.Mode()
isTerminal := mode&os.ModeDevice == os.ModeDevice && mode&os.ModeCharDevice == os.ModeCharDevice

What did you expect to see?

That bool isTerminal is true

What did you see instead?

isTerminal is false

Is a workaround available?

info, _ := os.Stderr.Stat()
mode := info.Mode()
isTerminal := (mode&os.ModeDevice == os.ModeDevice || runtime.GOOS == "windows") &&
	mode&os.ModeCharDevice == os.ModeCharDevice
@bradfitz bradfitz changed the title os.FileMode Device flag not set for Windows character device os: FileMode Device flag not set for Windows character device Dec 13, 2017
@bradfitz bradfitz added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows labels Dec 13, 2017
@bradfitz bradfitz added this to the Go1.11 milestone Dec 13, 2017
@bradfitz
Copy link
Contributor

/cc @alexbrainman

@as
Copy link
Contributor

as commented Dec 15, 2017

How does that workaround affect Windows users that use Cygwin?

@alexbrainman
Copy link
Member

@zosmac I agree we should always set os.ModeDevice when os.ModeCharDevice is set. I will send a fix.

How does that workaround affect Windows users that use Cygwin?

I don't know, I don't use Cygwin myself. But if Cygwin creates real Windows console, it should affect it in a similar way it affects cmd.exe.

Alex

@gopherbot
Copy link

Change https://golang.org/cl/84435 mentions this issue: os: do not forget to set ModeDevice when using ModeCharDevice

@zosmac
Copy link
Author

zosmac commented Dec 19, 2017 via email

@alexbrainman
Copy link
Member

@zosmac

On Cygwin, the "terminal" device is identified as a pipe.

Thanks for explaining.

So for Cygwin, a test to determine if a file descriptor is associated with a terminal will need to be done differently.

Go does not support Cygwin as development environment. So I do not expect this test to work on Cygwin.

Can you, please, try https://golang.org/cl/84435 . Does it fixes you problem? Thank you.

Alex

@zosmac
Copy link
Author

zosmac commented Dec 20, 2017

I have rebuilt my go compiler with this fix, rebuilt my applications to use the new behavior of the Mode setting for a character device on Windows, and successfully tested them on Windows in the DOS and Powershell terminals. As noted above, this fix will not address behavior in the Cygwin bash terminal due to the way it spawns processes and propagates the descriptors. I am investigating the Windows Console API for handling the Cygwin case, but this would certainly be overkill to attempt to handle in the Go runtime for this issue.

Thank you!

@zosmac
Copy link
Author

zosmac commented Dec 20, 2017

Found this comment in a stackexchange thread:
"Cygwin terminal emulators do not emulate Windows consoles, so they are good for Cygwin programs and for stdio-only programs but not for Windows console programs."

@as
Copy link
Contributor

as commented Dec 20, 2017

As noted above, this fix will not address behavior in the Cygwin bash terminal due to the way it spawns processes and propagates the descriptors.

In Cygwin, file descriptors are windows named pipes. The pipelist.exe program from sysinternals will show you more than the cygwin environment itself.

@alexbrainman
Copy link
Member

I have rebuilt my go compiler with this fix, rebuilt my applications to use the new behavior of the Mode setting for a character device on Windows, and successfully tested them on Windows in the DOS and Powershell terminals.

Sounds good, thank you for checking. We will have to wait for the change to be approved and submitted.

Alex

@golang golang locked and limited conversation to collaborators Feb 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

5 participants