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

idf_monitor: make Ctrl-] work when running on WSL (v3) #1324

Closed
wants to merge 2 commits into from
Closed

idf_monitor: make Ctrl-] work when running on WSL (v3) #1324

wants to merge 2 commits into from

Conversation

enrikb
Copy link

@enrikb enrikb commented Nov 27, 2017

Because the TIOCSTI termios ioctl is not supported on WSL (bash on
windows) at this time, another way for avoiding (or unblocking) a
blocking read on stdin is needed. Also, setting a timeout using
termios.c_cc[VMIN] = 0 with termios.c_cc[VTIME] = 1 does not currently
work for WSL.

A first approach to mimic the Windows kludge based on kbhit() by using
ioctl(TIOCINQ) for peeking at the input queue before calling read()
basically worked but failed badly for fast multi character input like
escape sequences sent back by the terminal. This can be easily
reproduced using the console example (examples/system/console). The root
cause was identified to be the buffering involved reading and decoding
stdin in python.

The second approach used pthread_kill() via ctypes (python 2) to unblock
getkey() in ConsoleReader which seemed to be working well. However,
even in this case stdin must have been re-opened without buffering.
Otherwise, the read() may be restarted internally after seeing EINTR.
Additionally, the solution felt at least a bit unclean.

After having identified the importance of making stdin unbuffered, it
became clear that in this case select() (or other I/O completion
methods) should also work correctly. Therefore, the current solution was
implemented, which looks a lot cleaner. It should also work on other
POSIX systems (e.g., plain Linux), but this has not been tested, so far.

The change has been tested successfully on WSL with the console example,
escape sequences (UP, DOWN keys), Ctrl-] to leave the monitor and
Ctrl-T/Ctrl-A for re-flashing.

Because the TIOCSTI termios ioctl is not supported on WSL (bash on
windows) at this time, another way for avoiding (or unblocking) a
blocking read on stdin is needed. Also, setting a timeout using
termios.c_cc[VMIN] = 0 with termios.c_cc[VTIME] = 1 does not currently
work for WSL.

A first approach to mimic the Windows kludge based on kbhit() by using
ioctl(TIOCINQ) for peeking at the input queue before calling read()
basically worked but failed badly for fast multi character input like
escape sequences sent back by the terminal. This can be easily
reproduced using the console example (examples/system/console). The root
cause was identified to be the buffering involved reading and decoding
stdin in python.

The second approach used pthread_kill() via ctypes (python 2) to unblock
getkey() in ConsoleReader which seemed to be working well.  However,
even in this case stdin must have been re-opened without buffering.
Otherwise, the read() may be restarted internally after seeing EINTR.
Additionally, the solution felt at least a bit unclean.

After having identified the importance of making stdin unbuffered, it
became clear that in this case select() (or other I/O completion
methods) should also work correctly. Therefore, the current solution was
implemented, which looks a lot cleaner. It should also work on other
POSIX systems (e.g., plain Linux), but this has not been tested, so far.

The change has been tested successfully on WSL with the console example,
escape sequences (UP, DOWN keys), Ctrl-] to leave the monitor and
Ctrl-T/Ctrl-A for re-flashing.
@enrikb
Copy link
Author

enrikb commented Nov 27, 2017

Now this is the third try to work-around missing TIOCSTI with WSL, as promised.
It looks not only cleaner to me, but also much simpler than V2. Further, it should even work with other POSIX systems (not tested!).
The basic building blocks are:

  • unbuffered stdin
  • select before read
  • a 'cancel' pipe used for unblocking select, no timeout necessary
    Feedback welcome.

@enrikb
Copy link
Author

enrikb commented Nov 28, 2017

JFTR: this change has at least one potential issue with varying length or multibyte per character input (example: UTF-8). If you manage to enter an incomplete UTF-8 sequence, the getkey() might still block when low-level read()s will be called until the sequence will be complete. Not sure if this can really happen.
The issue could be avoided by not using serial.getkey() at all, but handle reading / decoding locally instead.
However, this might not be too relevant for practical use.

@enrikb
Copy link
Author

enrikb commented Nov 1, 2018

This pull request is obsolete. TIOCSTI has been implemented in Bash on Windows 10 v1809 (see https://docs.microsoft.com/en-us/windows/wsl/release-notes). Ctrl-] just works on recent Windows 10.

@enrikb enrikb closed this Nov 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant