On Tue, 28 Jul 2020 21:51:33 +0200 Rabbe Fogelholm wrote: > 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.
Another way to do this is: stty -cooked; cat | java ... However, this solution and yours need extra key input to quit program after java program quited. -- Takashi Yano <takashi.y...@nifty.ne.jp> -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple