Ncurses limited output size - c++

I'm learning how to use ncurses and I'm in a weird situation.
It seems my output can't go over 24 lines.
Moreover, whenever I run my software, and the execution finishes his job, my terminal stops working as before, and I have 2 different situations:
if I've launched my run from a line behind line 24 I can use the terminal, but if I keep scrolling when at the last line of the window, nothing more happens: all input and output keep happening in the last line, without any new line appearing at enter pressure.
if I've launched the run above line 24 the terminal will only become 24-lines high.
Both situations require me to reset the terminal, then everything works again.
I'm on MAC OSX machine.

There is a problem with the screen-size:
The easiest one to see is if you has LINES environment variable set to 24. The use_env manpage gives some clues about that.
The reason why it sounds like a problem with screen-size is that the description of the problem suggests that the program is setting the scrolling region to 24 lines.
If there is no problem with LINES, then a place to check is by running stty -a to see what the operating system supposes the screen-size to be. That is reported on the first line of stty's output as "rows".
In some cases (for instance in remote network connections), it is possible to have a session where the remote host cannot obtain the screen-size. As a workaround, you could run the resize program (an xterm utility) to update the operating system's notion of the screen-size.
By the way, your other question NCurses not restoring terminal behavior appears to be a duplicate of this. You should consolidate your questions into a single one which provides enough information for someone to offer useful information about the problem.

Related

Was GDB listing the code as I stepped through, or was I only dreaming?

Years ago, when I last had call to use GDB to debug a Linux server, I seem to remember seeing a listing of the code that was being executed. Perhaps it was just the current line +/- five lines or so. I think i also remember it redrawing the entire console, every time I executed a command, so that the code listing was always at the top of the screen.
Now that I am once again in need of GDB's assistance, is my memory playing cruel tricks on me? Or does such a mode actually exist?
The documentation I'm finding online just points me at the 'l' command to list code. That looks like it has some potential, but there doesn't seem to be a way to get it to dynamically update as I step/next my way through the code.
If it's significant, I'm running Ubuntu on a dedicated Linux machine, and (since the program uses OpenGL) the actual debugging is going on inside a Weston Compositor terminal window.

Clearing Screen in C++/XCode

I am trying to write up a C++ program for a class using XCode. One of the things I wish to do, is to simply clear the screen. I've looked into how to do this, however the catch is that the code needs to run on both a Windows and Macintosh computer. I've looked at some other similar questions, but none of the answers help me. I know there is no "screen" but I want the system to clear the output window. I know that the command system("clear"); does what I want it to, but when XCode tests the program, instead of clearing the screen it prints TERM Variable not set
I've tried opening up the terminal and typing clear and it does in fact respond the way I want it to, so why doesn't the 'terminal' inside of XCode do the same? I just want to get the output window in XCode to respond to clear the same way that the terminal already does.
Here is something I have already tried;
I went to the terminal and ran echo $TERM, to which the terminal responded xterm-256color. I then went over to XCode and opened the "Scheme" settings, and found an Environment Variables setting under "Arguments". I added a variable (to the blank list) called TERM and gave it value xterm-256color. Upon running the program again, the output displays ¿[H¿[2J in the output window, positioned where the TERM Variable not set used to be printed.
Last thing, as a reminder, I cannot change the source code from the way it is now, or it could cause errors when the program is run on a Windows machine.
It does not work because you are "lying": The terminal in Xcode is not a xterm-256color, but it is dumb terminal. More precise, the display represents a NSTextStorage that collects stdout and/or (depending on target switch) stderr.
A dumb terminal is not able to clean the display. If you want to change this, you can write a plug-in similar to Xcode-Colors what adds the ability to understand ansi color codes.
However, if your requirement that the code simply run at Windows and OSX, you may stick with your solution system("clear"), since it works prefectly in the "normal" OSX terminal.

Linux keyboard scancode issues: For example, UP ARROW gives ^[[A

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.

Launch new program using exec in new terminal

I've got a program called pgm1 which create a new process using fork.
Then in this process, I launch a new program (pgm2) using the following command:
execv( exec_path_name, argv ).
But the thing is that with this method I've got both output in the same terminal.
I've been searching for a while ans the only solution i found was this one:
Open a new terminal with a system call
Attach my pgm2 to the new terminal using this soft http://blog.nelhage.com/2011/01/reptyr-attach-a-running-process-to-a-new-terminal/comment-page-1/#comment-27264
So my question is really simple, is there a more simple way to do that ?
Thanks in advance !
PS: Distro - Ubuntu 11.10 32bit
I can think of two possible solutions:
Do The Right Thing(TM) and send your output to a file: Each process can use a different file, providing both clear separation of the output and better record-keeping. As a bonus, you are also bound to see a performance improvement - terminal output is computationally expensive, even nowadays...
Execute a terminal emulator with the proper arguments: Most terminal emulators provide a way to execute a specific program in place of the shell. For example xterm:
$ xterm top
This will launch top in an xterm instance, without a shell. Quiting top also terminates the xterm window.
If your terminal emulator of choice supports this, you can use it simply by modifying the arguments passed to execv(). Of course, in this case you will be actually executing the terminal emulator instead of your program, which will then call your own process.
Keep in mind that, depending on the terminal emulator, any open file descriptors may not be passed correctly to your program - the terminal will at least mangle the standard file descriptors.

C++ - How to detect I am running without a terminal

In C/C++ how can my programs determine if there is a desktop (system or remote) or not?
My project has three separate programs running (now) in separate gnome-terminals. It is launched by the last line of .profile, so it starts whether I am at the system desktop (gnome) or remotely connecting by VPN/telnet or VPN/remote-desktop. My machine is 250 miles away at a test site, so I frequently login remotely to make changes and have to restart the program.
I'd like my program to be able to detect that it is launched from a desktop environment or from a telnet session. Preferably, I want them to continue running after the remote connection is broken.
Obviously, I need to make my programs into daemons so they will persist after I close the connection. But if I start them in a terminal on a desktop environment, where I can actually have three terminals open, I'd like to watch their progress messages. And if I disconnect the remote desktop, I'd like the daemons to detect this and turn off printing (to the now killed terms) but keep on running in normal (silent) daemon mode. Best of all, the programs could recheck for a desktop occasionally and resume printing by opening new terminals.
Is this possible? Any coding suggestions?
Thanks in advance.
You can use the isatty function. Detect if stdin is a terminal or pipe?
#include <stdio.h>
#include <io.h>
//...
if (isatty(fileno(stdin)))
printf( "stdin is a terminaln" );
else
printf( "stdin is a file or a pipen");
You can find more information at http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html
Some more code: http://pastebin.com/S3Lr9tik
The traditional solution for this problem is an option in the command
line. Such programs will typically demonize themselves unless given a
special debug option telling them not to.
Another solution would be to use a shell script to start the program as
a demon, via the nohup command (and redirecting standard input and
output to /dev/null).
As for determining whether your managing terminal is local or not, it
could be difficult; both X and telnet use virtual terminals, so if
you're running under X, you may not be able to distinguish between a
telnet session and a local xterm window. Still, it might be worth
trying... Under Linux, /proc/<procid>/fd/0 is a symbolic link to the
device connected to standard in (fd 0): using something like readlink,
you should be able to determine the actual name. Or fstat will give
you the major and minor numbers of the device. Given these, you might
be able to determine which is which. If your local terminal is not
under X, but a real terminal, it will definitely have a different minor
number than a pseudo-terminal. For xterms, it's possible that the minor
numbers of the pseudo-terminals fall in different ranges, or even that
there are distinct sets of pseudo-terminals for remote links and for X;
you'll probably have to experiment some, and there might be no working
solution. (For starters, to tty at each terminal, and see what it
says. I don't have local access to a Linux machine to check, but I seem
to remember that on Solaris, X terminals had names like /dev/ttyxx; my
remote terminals on Linux here are /dev/pts/xx. (Where xx is a
number in each case.)