Skip to content

Reimplement Unix.isatty on Windows#1321

Merged
mshinwell merged 5 commits intoocaml:trunkfrom
dra27:windows-isatty
Sep 15, 2017
Merged

Reimplement Unix.isatty on Windows#1321
mshinwell merged 5 commits intoocaml:trunkfrom
dra27:windows-isatty

Conversation

@dra27
Copy link
Copy Markdown
Member

@dra27 dra27 commented Sep 6, 2017

Presently:

C:\Users\DRA\Documents\ocaml> ocaml 2>nul
        OCaml version 4.06.0+dev1-2017-06-23

# #load "unix.cma";;
# Unix.isatty Unix.stderr;;
- : bool = true

With this version, it returns false (as it should).

The null device is a character device, but is not a console -
Unix.isatty would incorrect return true for standard handles redirected
to null.

The new implementation returns true if and only if the fd points to a
console handle.
CAMLprim value unix_isatty(value fd)
{
DWORD lpMode;
return (Val_bool(GetConsoleMode(Handle_val(fd), &lpMode)));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This relies on the fact that GetConsoleMode fails (i.e. returns 0) iff the handle is neither for an input or output buffer of a console. Are you confident that this always works? I cannot find on MSDN a description of error cases. (I could imagine e.g. that the function doesn't fail on some older versions of Windows even on non-console handles.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not explicit, I agree, but even for MSDN it would be very strange for a function to be documented as requiring a console handle and not to return ERROR_INVALID_HANDLE if it receives a handle to something else.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In these useful cuddly open-source Microsoft times, it turns out we can often check these things: https://github.com/dotnet/corefx/blob/master/src/System.Console/src/System/ConsolePal.Windows.cs#L164

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, it's interesting that .NET first of all checks that the handle represents a character device.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was introduced in dotnet/corefx@8cd8e78. Should we search advice from the author of this commit?

Copy link
Copy Markdown
Contributor

@xavierleroy xavierleroy Sep 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't go wrong by copying the logic of the .NET code...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think we can go wrong - I'm going to risk asserting that the .NET code is actually incorrect. It was added in dotnet/corefx@8cd8e78#diff-6f40ebab17283a57f687629b80f8beb7 and it treats the output of GetFileType as if it were a bitmask, which it is not. So the code they have will unnecessarily call GetConsoleMode for pipes as well.

I have pushed a commit which includes what I believe to a correct version of the test on GetFileType...

Unix.isatty Unix.stderr = %b"
(Unix.isatty Unix.stdin)
(Unix.isatty Unix.stdout)
(Unix.isatty Unix.stderr)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would feel better if at least one test of Unix.isatty would return true. For example, what about opening /dev/tty or CON (whichever succeeds) and test that?

@@ -0,0 +1,3 @@
Unix.isatty Unix.stdin = false
Unix.isatty Unix.stdout = false
Unix.isatty Unix.stderr = false No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please terminate this last line (and the corresponding printf) with a newline, it feels lonely without one.

@xavierleroy
Copy link
Copy Markdown
Contributor

The freeze for 4.06 is tomorrow Friday Sept 15th. This PR can go in provided the changes suggested by @alainfrisch and I are made by this time.

@mshinwell
Copy link
Copy Markdown
Contributor

I believe all the comments have been addressed, so merging.

@mshinwell mshinwell merged commit 6fb2960 into ocaml:trunk Sep 15, 2017
shindere added a commit to shindere/ocaml that referenced this pull request Sep 15, 2017
This reverts commit 6fb2960.

This is to be able to test ocamltest without this commit that breaks CI.

The branch should not be merged into trunk as long as this commit is here.
shindere added a commit to shindere/ocaml that referenced this pull request Sep 15, 2017
This reverts commit 6fb2960.

This is to be able to test ocamltest without this commit that breaks CI.

The branch should not be merged into trunk as long as this commit is here.
shindere added a commit to shindere/ocaml that referenced this pull request Sep 15, 2017
This reverts commit 6fb2960.

This is to be able to test ocamltest without this commit that breaks CI.

The branch should not be merged into trunk as long as this commit is here.
shindere added a commit to shindere/ocaml that referenced this pull request Sep 15, 2017
This reverts commit 6fb2960.

This is to be able to test ocamltest without this commit that breaks CI.

The branch should not be merged into trunk as long as this commit is here.
shindere added a commit to shindere/ocaml that referenced this pull request Sep 15, 2017
This reverts commit 6fb2960.

This is to be able to test ocamltest without this commit that breaks CI.

The branch should not be merged into trunk as long as this commit is here.
@dra27 dra27 deleted the windows-isatty branch July 6, 2021 14:05
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
Co-authored-by: Christine Rose <christinerose@users.noreply.github.com>
Co-authored-by: Sonja Heinze <sonjaleaheinze@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants