stty -cooked not usable since cygwin-3.1.1-1
Rabbe Fogelholm
rabbe@bahnhof.se
Tue Jul 28 19:51:33 GMT 2020
On 2020-07-28 18:56, Thomas Wolff wrote:
>
>
> Am 28.07.2020 um 18:38 schrieb Takashi Yano via Cygwin:
>> On Tue, 28 Jul 2020 15:56:54 +0200
>> Rabbe Fogelholm wrote:
>>> Rabbe Fogelholm wrote:
>>>> Takashi Yano wrote:
>>>>> On Mon, 13 Jan 2020 11:52:43 +0100
>>>>> Rabbe Fogelholm wrote:
>>>>>> I am running a console Java program that is started from a
>>>>>> shellscript
>>>>>> wrapper. Before invoking Java the wrapper calls `stty -cooked'.
>>>>>> The Java
>>>>>> program polls the keyboard using System.in.available() and reads
>>>>>> characters immediately using System.in.read(), without waiting for
>>>>>> the
>>>>>> Enter key to be pressed.
>>>>>>
>>>>>> This way of combining `stty -cooked' and Java has stopped working
>>>>>> since
>>>>>> version 3.1.1-1 of the Cygwin package. The Java thread that reads the
>>>>>> keyboard hangs until Enter is pressed, which is not desirable.
>>>>>>
>>>>>> I had to downgrade to version 3.0.7-1 to resolve the problem.
>>>>>>
>>>>>> Versioning information:
>>>>>>
>>>>>> java version "1.8.0_202"
>>>>>> Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
>>>>>>
>>>>>> OS Name: Microsoft Windows 10 Pro
>>>>>> Version: 10.0.17763 Build 17763
>>>>>> System Type: x64-based PC
>>>>>>
>>>>>> See also the enclosed cygcheck.out.
>>>>>>
>>>>>> To demonstrate the issue I enclose a small Java program that
>>>>>> should be
>>>>>> able to read single keystrokes when `stty -cooked' is in effect.
>>>>> Does your java program work in command prompt? cygwin 3.1.x uses
>>>>> pseudo console, so the native (non cygwin) program works as if it
>>>>> is executed in command prompt.
>>>>>
>>>> With cygwin 3.1.x I can't find a way to make my program work.
>>>>
>>>> When running from within a Cygwin64 terminal the `stty -cooked' command
>>>> terminates with exit code 0, but the Java program behaves just as if
>>>> `stty -cooked' is not in effect: It does not handle single keystrokes
>>>> immediately.
>>>>
>>>> When running from a Windows command prompt I can execute the stty
>>>> program as \cygwin64\bin\stty. However, when given the '-cooked'
>>>> argument it complains:
>>>> /usr/bin/stty: 'standard input': unable to perform all requested
>>>> operations
>>>>
>>>> - and here as well the Java program behaves as if `stty -cooked' is not
>>>> in effect.
>>> Some time has passed; I am just curious if anyone may have found a
>>> solution to the "stty -cooked" issue. With cygwin-3.0.* it was possible
>>> to have a Java program act on single keystrokes, with cygwin-3.1 I don't
>>> know how to do it. Any ideas welcome!
>> Solution 1:
>> Redesign your java program using JNA with kbhit()/getch() instead of
>> System.in.available()/System.in.read().
>>
>> Solution 2:
>> Add SetConsoleMode() call with ENABLE_LINE_INPUT flag cleared using JNA.
> Couldn't cygwin clear this flag when it sets up ConPTY while the pty is
> in raw mode?
> Thomas
>
>>
>> Solution 3:
>> Use a wrappwer instead of stty such as:
>>
>> #include <stdio.h>
>> #include <unistd.h>
>> #include <termios.h>
>> #include <string.h>
>> #include <pthread.h>
>> #include <sys/wait.h>
>>
>> void *fwd(void *param)
>> {
>> FILE *f = (FILE *) param;
>> char buf[128];
>> int len;
>> while (1) {
>> if ((len = read(0, buf, sizeof(buf))) <= 0) break;
>> if (write(fileno(f), buf, len) < len) break;
>> }
>> return NULL;
>> }
>>
>> int main(int argc, char *argv[])
>> {
>> FILE *f;
>> int i;
>> pthread_t th;
>> struct termios t, t_orig;
>> char cmd[1024] = {0, };
>> if (argc < 2) return 0;
>> for (i = 1; i < argc && strlen(cmd)+strlen(argv[i]) <
>> sizeof(cmd)-2; i++) {
>> sprintf(cmd + strlen(cmd), (i>1)?" %s":"%s", argv[i]);
>> }
>> f = popen(cmd, "w");
>> tcgetattr(0, &t_orig);
>> t = t_orig;
>> cfmakeraw(&t);
>> tcsetattr(0, TCSANOW, &t);
>> pthread_create(&th, NULL, fwd, f);
>> wait(NULL);
>> tcsetattr(0, TCSANOW, &t_orig);
>> pclose(f);
>> return 0;
>> }
>>
>
>
Thanks Takashi for suggesting many ways to solve this! The C wrapper
solution looks quite powerful.
Meanwhile it has occurred to me that bash itself can provide a
workaround. Since I start the Java console application from a bash
wrapper already, I have now changed it so that it does something like
this:
(while true; do read -s -r -N 1 Key; echo "$Key"; done) | java ...
With these options to 'read' I get action on every keystroke, and the
Java program gets its input as terminated length-1 lines.
More information about the Cygwin
mailing list