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

lanterna assumes that Cygwin is installed in the root directory #421

Open
buko opened this issue Jun 6, 2019 · 15 comments
Open

lanterna assumes that Cygwin is installed in the root directory #421

buko opened this issue Jun 6, 2019 · 15 comments

Comments

@buko
Copy link

buko commented Jun 6, 2019

Running a lanterna program using the Cygwin terminal results in the well-known issue:

Exception in thread "main" java.io.IOException: Cannot run program "/bin/stty": CreateProcess error=2, The system cannot find the file specifie

The program /bin/stty.exe exists but it won't be there unless Cygwin was installed in the root directory.

Workaround

You can work around this problem by putting stty.exe where Lanterna expects it. Create the directory C:\bin\ and copy stty.exe to C:\bin\stty.exe.

Once the fie has been copied over the lanterna program will work.

Proposed Solution

lanterna should check the environment variable CYGWIN_HOME. If this environment variable is set then lanterna should (1) Automatically use the Cygwin Terminal and (2) Change all paths to be relative to this base directory.

@avl42
Copy link
Contributor

avl42 commented Jun 6, 2019

The topic of cygwin and /bin/stty has been raised a couple of times in the past.

The problem is, that so far, about all who reported a problem with "/bin/stty and Cygwin" turned out not to have anything to do with cygwin, and just accidentally stumbled into the error, because they started the lanterna app from command line with java.exe (rather than for plain windows correctly with javaw.exe).

If you happen to be the first one who really has cygwin installed, and intends to run a lanterna app in cygwin's terminal, please let us know! And also let us know if accessing stty that way will really result in a working cygwin-terminal application.

What I also have gathered from different sources is, that it wouldn't even help calling the right stty.exe from within a java application, as the stty.exe would not have access to the terminal running the java application. My expectation is, that to run Lanterna under cygwin will really require a shell-script that calls stty.exe, then the Lanterna-app, and finally restore the tty to original settings.

Lanterna's CygwinTerminal is in desperate search for someone working with Cygwin and knowing what needs to be done there to let lanterna read single keystrokes in "raw" mode.

@buko
Copy link
Author

buko commented Jun 6, 2019

Well I have cygwin installed and I'm hoping to use lanterna and the workaround does fix the problem. I think it would be a good idea for lanterna to use CYGWIN_HOME to locate stty.

And also let us know if accessing stty that way will really result in a working cygwin-terminal application.

I've noticed other oddities under cygwin, especially when using the GUI components.

Lanterna's CygwinTerminal is in desperate search for someone working with Cygwin and knowing what needs to be done there to let lanterna read single keystrokes in "raw" mode.

This is what I've deduced too. Lanterna doesn't really work under cygwin. Unfortunately I'm no cygwin expert so I don't think I can be of much use here. What I can say is that lanterna's telnet Terminal seems to work fine. So if you install telnet under cygwin (apt-cyg install inetutils) and then run the lanterna app with TelnetTerminal... everything works great.

This isn't ideal but it's good enough for show business.

I would perhaps make it clearer in the docs that cygwin is indeed not really supported. It might save people some time.

@avl42
Copy link
Contributor

avl42 commented Jun 7, 2019

I've noticed other oddities under cygwin, especially when using the GUI components.

This really makes it look like the call to stty.exe is just effectless.
Please try to run a (textgui-based) lanterna application from a script, which calls "stty.exe raw" before starting java-lanterna-app.

I don't even have Windows on my machines, so can't test Cygwin.

Unfortunately I'm no cygwin expert so I don't think I can be of much use here.

If you can try out some things (like running stty in a script before java), then you'd be of great use here.

@buko
Copy link
Author

buko commented Jun 7, 2019 via email

@avl42
Copy link
Contributor

avl42 commented Jun 7, 2019

Yes, like:
$ stty.exe raw; java.exe ...

write it all in one line, or the shell might reset the terminal inbetween.
(Or, as I previously suggested: write a shell-script that has
stty raw
java ...
stty sane
in it, and run the script)

@avl42
Copy link
Contributor

avl42 commented Jun 7, 2019

(that CygwinTerminal class also calls stty doesn't matter here)

@buko
Copy link
Author

buko commented Jun 10, 2019

Well, I tried what you said. I ran:

$ stty.exe raw ; java ...

The result was a blank screen that was totally unresponsive. I couldn't even Ctrl-C out. I had to switch to another window and kill the process.

Maybe @adammurdoch can weigh in?

His https://github.com/adammurdoch/native-platform project looks very interesting. It seems to provide a facility for detecting the presence of a CygwinTerminal? If so, this could simplify things quite a bit. Though the user would still need to specify exactly where CYGWIN is installed by setting CYGWIN_HOME (environment variable) or cygwin.home (System property).

What's interesting is that as I've mentioned before Lanterna works great in Cygwin if I use the telnet terminal. cygwin+mintty are clearly capable of rendering the Lanterna output. The problem seems to lie in what lanterna thinks the Cygwin terminal can do and how itinitialized it.

@adammurdoch
Copy link

native-platform does detect the Cygwin terminal, but at this stage it does not support setting the Cygwin terminal input to raw mode, which I'm guessing might be a problem. It does support detection and raw mode input for other platforms and plus the Windows console. At some point I'd like to figure out how to make this work with the Cygwin terminal too.

@buko
Copy link
Author

buko commented Jun 27, 2019

Did some more research into this. After much testing it was possible to get lanterna mostly working under Cygwin and mintty. I had thought winpty might help but it only made things worse. After some more poking about @avl42's suggestion to run stty and launch the java program in a single shell command basically worked but it was necessary to pass some additional parameters to stty. This basically does the trick:

$ stty raw -echo isig ; ~/data/applications/Java/jdk-12.0.1/bin/java --module-path target/console-cowboy-app-0.0.1-SNAPSHOT-application-distribution/lib --module com.bubblegumproject.cowboy.console_app 

The -echo is to disable local input. Without this if the user presses enter the lanterna gui will scroll off the screen. isig parameter will allow your program to continue receiving system signals like Ctrl-C. This is very useful if you're just running test programs.

With these two options lanterna+cygwin+mintty seem to work but much more testing is necessary.

I should mention that if you do this and then Ctrl-C out of the program your terminal will be in a bad state. Therefore it is necessary to run the reset program to restore your terminal to a good state:

 $ reset

Not sure why this happens and it would be nice if it didn't. Maybe this is a matter of closing lanterna properly.

As mentioned above @adammurdoch 's native-platform project contains code for detecting if you're dealing with a Terminal. I think it may also have a method to query if the terminal is specifically Cygwin? Though it's not clear what the API is we could in theory use such a lib to detect if cygwin is the terminal and then look for a CYGWIN_HOME variable and this might be enough to automatically select the CygwinTerminal. We would also need to modify
(CygwinTerminal.java)[https://github.com/mabe02/lanterna/blob/master/src/main/java/com/googlecode/lanterna/terminal/ansi/CygwinTerminal.java] to change the parameters it passes to STTY.

@mabe02
Copy link
Owner

mabe02 commented Aug 20, 2019

Very interesting, this is probably the furtherst anyone has ever got with Cygwin! I'd be ok to make use of adammurdoch/native-platform if it could help us with controlling the terminal.

But let's say we detect Cygwin by looking for CYGWIN_HOME, should we then assume that the user has put the terminal in raw -echo isig mode? We could document it and let the end user deal with initialization if they really want to support Cygwin; it's not great but it's much better than what we have now.

@buko
Copy link
Author

buko commented Jan 26, 2020

But let's say we detect Cygwin by looking for CYGWIN_HOME, should we then assume that the user has put the terminal in raw -echo isig mode?

This would indeed be a step in the right direction.

I don't think there's any reason why you couldn't call stty raw -echo isig automatically like we do for other operating systems. The only problem is how do you determine that the user is running inside mintty and not the normal Windows console?

The solution we settled on was to require the user set two environment variables:

  1. CYGWIN_HOME must be set.
  2. TERM_EMULATOR must be set to 'https://mintty.github.io/'

If both these variables are set we assume the user is running Cygwin inside mintty. It's not perfect but it's a step in the right direction.

@mabe02
Copy link
Owner

mabe02 commented Feb 1, 2020

I'll try this out and let's see if I can get it working

mabe02 added a commit that referenced this issue Feb 1, 2020
…again

Also use CYGWIN_HOME to find where the binaries are
@mabe02
Copy link
Owner

mabe02 commented Feb 1, 2020

Alright, with the latest commit, I got it working somewhat. Enter key is still not working, but most of the other keys do.

@buko
Copy link
Author

buko commented Feb 1, 2020 via email

@mabe02
Copy link
Owner

mabe02 commented Feb 16, 2020

Unfortunately not, you'll have to clone and compile from source...

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

No branches or pull requests

4 participants