From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from pio-pvt-msa3.bahnhof.se (pio-pvt-msa3.bahnhof.se [79.136.2.42]) by sourceware.org (Postfix) with ESMTPS id 16FED385700D for ; Fri, 31 Jul 2020 06:52:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 16FED385700D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=bahnhof.se Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rabbe@bahnhof.se Received: from localhost (localhost [127.0.0.1]) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTP id A10F93F5DF for ; Fri, 31 Jul 2020 08:52:31 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at bahnhof.se X-Spam-Score: -2.711 X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00, BODY_8BITS, KAM_DMARC_STATUS, KAM_NUMSUBJECT, NICE_REPLY_A, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 Received: from pio-pvt-msa3.bahnhof.se ([127.0.0.1]) by localhost (pio-pvt-msa3.bahnhof.se [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BpLhfCdkkOlm for ; Fri, 31 Jul 2020 08:52:30 +0200 (CEST) Received: from [10.0.0.9] (h-47-10.A165.priv.bahnhof.se [46.59.47.10]) (Authenticated sender: mb748077) by pio-pvt-msa3.bahnhof.se (Postfix) with ESMTPA id A848C3F41A for ; Fri, 31 Jul 2020 08:52:30 +0200 (CEST) Subject: Re: Re: stty -cooked not usable since cygwin-3.1.1-1 To: cygwin@cygwin.com References: <20200113200152.5243a304d481677c61c12450@nifty.ne.jp> <12d7cb6e-b900-6780-1d1c-80ed84cc82d5@bahnhof.se> <1ea4e90c-7075-39e8-a518-40bc764a5237@bahnhof.se> <20200729013848.cf6d4d99464e92d92d346029@nifty.ne.jp> <22f2becd-1f2e-5ff8-4999-b34f2fb0bff3@bahnhof.se> From: Rabbe Fogelholm Message-ID: <57da53a4-db59-f7db-cfd7-62c39c67263c@bahnhof.se> Date: Fri, 31 Jul 2020 08:52:30 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: cygwin@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: General Cygwin discussions and problem reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Jul 2020 06:52:37 -0000 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 >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> >>>>> 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.