On 2020-07-29 22:03, Rabbe Fogelholm wrote:
On 2020-07-29 01:30, Thomas Wolff wrote:
Am 28.07.2020 um 21:51 schrieb Rabbe Fogelholm:
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.
Can you please provide a full test case, as it worked for you in
cygwin 3.0.7, i.e. the Java program and the wrapping commands, for
some experiments.
Thomas
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.
--
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
Hi Thomas, this small program can be used for experiments:
--- ReadKeystrokes.java ------------
import java.io.IOException;
public final class ReadKeystrokes {
/**
* Read keystrokes and write codes to standard output. The
* intention is that writing should occur immediately.
* @param args
* @throws InterruptedException
* @throws IOException
*/
public static void main(String[] args) throws IOException,
InterruptedException {
System.out.println("Press any keys; to exit press 'q'");
for (; true;) {
if (System.in.available() > 0) {
final int c = System.in.read();
System.out.println(String.format("key was pressed,
code: %d", c));
if (c == 'q') {
break;
}
}
else {
Thread.sleep(100);
}
}
}
}
------------------------------------
After compiling, assuming ReadKeystrokes.class is in the current
directory, launch it with:
java -classpath ./ ReadKeystrokes
I suppose the behavior of the above test program may depend on the Java
runtime being used. I am using Oracle Java SE 1.8, version 202.
--
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