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

Comments

@zosmac
Copy link

@zosmac 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 this to the Go1.11 milestone Dec 13, 2017
@bradfitz

This comment has been minimized.

Copy link
Contributor

@bradfitz bradfitz commented Dec 13, 2017

@as

This comment has been minimized.

Copy link
Contributor

@as as commented Dec 15, 2017

How does that workaround affect Windows users that use Cygwin?

@alexbrainman

This comment has been minimized.

Copy link
Member

@alexbrainman alexbrainman commented Dec 15, 2017

@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

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Dec 15, 2017

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

@zosmac

This comment has been minimized.

Copy link
Author

@zosmac zosmac commented Dec 19, 2017

@alexbrainman

This comment has been minimized.

Copy link
Member

@alexbrainman alexbrainman commented Dec 20, 2017

@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

This comment has been minimized.

Copy link
Author

@zosmac 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

This comment has been minimized.

Copy link
Author

@zosmac 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

This comment has been minimized.

Copy link
Contributor

@as 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

This comment has been minimized.

Copy link
Member

@alexbrainman alexbrainman 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.

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

Alex

@gopherbot gopherbot closed this in 9cae3aa Feb 26, 2018
@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.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.