Certain control sequences have special effects in Linux, such as CTRL-C which sends SIGINT. I can handle signals easily enough, but it appears CTRL-S (XOFF) and CTRL-Q (XON) are special snowflakes. I know their effect (to pause input) can be disabled in the console with stty -ixon, and I could use some trickery to run that command, but that feels like a cheap workaround.
Is there a proper way to rid these sequences of their special effect and get their actual ASCII values (^S, ^Q) using system calls? I know it is doable because the text editor Nano does it, but for the life of me I can't find where it's being handled. I already tried searching the repo for "XOFF".
https://github.com/dtrebbien/nano/tree/master/src
Use the tcgetattr() and tcsetattr() system calls to turn off the IXON flag on standard input, as explained in this manual page.
Related
I am writing some library code which will rerun the current process as an administrator/root. The problem is (for linux at least) that if the calling code is a command line application the best way would be to call sudo whereas if it is a gui application, gksudo is appropriate. For completeness sake though, solutions (or pointers to solutions) for other os's are also welcome.
Also, this is useful so that for GUI apps, I can turn off printf statements.
I'd run gksu(do) if the environment variable DISPLAY is set. It doesn't really matter if the application has a GUI or not, if there's an X-server running, and we can use it, why shouldn't we?
Doesn't allow you to determine if you should disable stdout output. However, stderr output is generally captured in .xsession-errors, even if no terminal is connected, so you might not want to disable that output afterall.
We've been struggling for a while now to understand the keyboard scancode behavior in Linux.
When we open a normal bash shell, the arrow keys works as expected: UP shows the previous item in the history etc. However when you spawn a process, arrows does not work as expected anymore. For example, UP prints ^[[A instead of the previous command.
To demonstrate this, do something like:
bash$ ping www.google.com
Now, press UP or DOWN etc. and you will see the wrongly mapped key codes while the process is running. However, when you terminate the process the arrow keys will work again.
We've tested it on CentOs, Ubuntu, Mac and even in different shells (bash, sh, zsh) and the same happens everywhere. I've also tried different keyboard modes using kbd_mode where we tested with RAW and XLATE modes.
The closest thing I could see while searching for answers were IPython users have experienced the same behavior when IPython was not build against readline. However, this is not related to our case as far as I can see.
We are developing a C++ Tcl based console application which uses cin and cout to communicate with, and get input from the user. We are having issues with the arrow keys when we try to access the history of previously entered commands. This is a major issue for us as 99% of people expects the arrow characters to just work.
Any ideas on how we could overcome this would be much appreciated.
You must set the terminal into raw mode to get the scan codes and handle them (that is: disable ICANON, you want the non-canonical mode). You probably also want to disable ECHO (so that it doesn't print your input on the terminal).
That is what readline or linenoise are doing. See here for some code. Esp. see the function linenoiseEnableRawMode. Some other simple sample Python code is here where I have written a simple console media player which checks for the keypresses left ("\x1b[D") and right ("\x1b[C").
The relevant calls are to tcgetattr (to get the current terminal state and modify that state struct to get into raw mode and enable some other useful behavior stuff) and tcsetattr (to set the state).
readline, libedit or linenoise are some libraries which do all that work for you and provide you with history, autocompletion, etc.
At the end, you must restore back the old state, otherwise you get the behavior you are describing in your shell.
I want to make a version of cin that works in a graphics display window (it's SDL, but I don't think that matters here): that is, when you type, the characters echo into that window rather than the console window. The solution should be cross-platform.
I have this page to tell me how to get characters NOT to echo to the console window: Reading a password from std::cin
...but what I don't know how to do is to make the characters echo on the new graphics display window.
One thing I could do is intercept keyboard events, and if one happens, print the character. But this wouldn't perfectly echo the actual behavior of the istream buffer, because of repeating keys, backspace, enter, tab, and also the real behavior of cin in that if you are typing before C++ gets to the cin, it will put that stuff you typed on the screen at that point.
I think this echoing is done inside the call to _read (read in the Unix world), and that I'm not sure how to access.
TIA.
The behaviors you're talking about are not done by cin nor read() syscall; buffering and processing of special character is done by the terminal emulator and the shell.
You do need to intercept key events and implement these yourself. Alternatively, some terminal emulators (e.g. VTE widget in Gnome) were designed so they can be embedded into another program. You might want to look at that option.
Considering your application is running in a window you shouldn't read input from the console . It's probably possible but you'll have to switch to the terminal window from where you started the window each time you want to input text. If you take this route you need to disable tty echo: http://man7.org/tlpi/code/online/dist/tty/no_echo.c.html (for Linux). Check out http://www.cplusplus.com/forum/general/12256/ for some solutions for Windows too. I don't think there is a solution that works for both so you'll need to bury some #ifdef's in some utility functions.
Since you're using SDL you should probably use SDL's input functions.
Check out http://www.libsdl.org/docs/html/guideinputkeyboard.html
And, more specific to your needs: http://wiki.libsdl.org/moin.fcg/Tutorials/TextInput
First, a bit of background: I'm running the latest stable build of Crunchbang Linux inside a VirtualBox VM. I'm designing a custom text-based user interface to run on top of bash. This is being done with a combination of C++ and bash scripts.
I need to, at times, completely and totally remove the ability for the user to provide the system with any sort of standard keyboard input. This is because, when I run a part of the system, the user is forced to wait for certain amounts of time.
Unfortunately, the user can still type while this is going on, and whatever they type is put on the screen. This happens when I'm running a C++ program as well as a bash script. The reason this is a problem is that there is text on the screen which the user is to read, and if they can type, it displaces the text. There will be other uses for this later, as well, like making the system seem like it has frozen up.
So, the question - How do I
disable the keyboard, or
prevent anything pressed on the keyboard from showing up on the screen?
Turn off echo mode with stty -echo or the equivalent C code (which would use tcgetattr and tcsetattr). When you are ready to accept input again, turn it back on. You may also wish to discard the input that arrived while you weren't expecting it. That would be done with tcflush but be aware that some users (like me) would consider that an annoyance. Typeahead is a feature, not a bug!
To see how user input to a certain process or tty can be intercepted, the man page and source code of interceptty may be enlightening. (have no experience with it)
However, you can hardly (totally) prevent user input. The user is probably always able to switch to a different virtual terminal (if any) or at least to reboot the system with Alt+Print+B (Magic SysRq_key) if not disabled. It is two different things to ignore input on a given tty and disabling keyboard input altogether.
I have a GUI application, which creates a QProcess inside, catches its output and shows it on a form. I need to somehow catch key events from the form to pass them to QProcess (to make it fell as close as possible to real terminal window).
So, I suppose, I should process keyReleaseEvent() and somehow transform either event.text() (which is QString) or event.key() (which is int) to argument, suitable for process.write() (which takes char* or QByteArray). Is there some recommended way to do such a conversion (taking into account localization issues, ctrl/alt/shift modifiers and so on)? I do not really want to construct some sort of mapping from key() return values to char* strings; and text() drops modifiers.
Moreover, if I start process with command bash -c sudo something in QProcess, it exits instantly, complaining that "no tty present and no askpass program specified", so I may be doing something completely wrong...
The problem is more than just deciding what to write to the process.
You can't emulate a terminal just by reading/writing stdout/stdin of a process, it's more complicated than that. Think about the program less, or any pager, for example. How does it know how many lines to print at a time? It needs information about the terminal which isn't represented through stdin/stdout/stderr.
Emulating a terminal is beyond the scope of QProcess. If you're really sure you need to do this then use some existing Qt-based terminal emulator as a starting point (e.g. Konsole).