NCurses not restoring terminal behavior - c++

Hello dear Communauts,
I'm am creating a terminal animated status report for a parallel software I'm developing. I'm using NCurses.
I'm having an issue related to the restoring of the standard behavior of the terminal.
After running my software the terminal keeps having just 24 lines, no matter if I call endwin() or I don't.
Here the simplified code:
int size=10;
initscr();
refresh();
while(KeepAlive){
int j=1;
mvprintw(j,0,/*Blah blah header*/));
for(int i=0;i<size;i++){
j++;
mvprintw(j,0,/*Some blah blah*/);
}
refresh();
usleep(1000000);
}
endwin();
KeepAlive is a control variable changed by another thread (so the while is not infinite loop, but controlled loop).
After running this software my terminal has only 24 lines, echo works, but there's plenty of blank space.
Thanks a lot for your help, have fun
EDIT:
I would like to share with you some information I found while attempting to solve my issue:
curses (ncurses) is perfectly working under openMP, then you can imagine some threads doing your math calculations and one thread (only one, be aware) giving out some runtime infos.
curse (ncurses) is NOT compatible with MPI. Well, the right stating would be is "not completely" compatible with MPI. MPI is really sophisticated about stdin/stdout/stderr, since all outputs from all MPI-processes could be redirected to a display (which could be specified). Using any advanced terminal output overriding library will take to a fault of the code, or unexpected behaviors.
That's supported by the MPI faq:
Maybe. But probably not.
Open MPI provides fairly sophisticated stdin / stdout / stderr forwarding. >However, it does not work well with curses, ncurses, readline, or other >sophisticated I/O packages that generally require direct control of the terminal.
Every application and I/O library is different -- you should try to see if yours >is supported. But chances are that it won't work.
Sorry. :-(
found here (MPI reference).
What I've discovered is that even if you appoint only one MPI-process to manage all the curses output (just that process calls initscr() at the beginning and endwin() at the end of his part of code) there is no way to force curses to use the full terminal (only default UNIX 24x80 will be available).
Once MPI has been finalized your whole terminal will keep working in 24x80 mode until reset is called.
Thanks to all communauts that helped me,
Have fun
gf

One possible solution is to completely decouple your text GUI from the rest of the MPI code and make both parts talk to each other via the client/server mechanism of MPI-2. That means:
Run the GUI as singleton MPI program, i.e. one that calls MPI_Init{_thread} but is not started via mpiexec. It then should open a listening port by calling MPI_Open_port. The call returns a string port name that has to be supplied to the compute part of the application. The GUI part should then start listening for connections by calling the blocking MPI_Comm_accept.
The compute part is started as usual via mpiexec. It should connect to the GUI by calling MPI_Comm_connect given the port name from (1).
The combination of MPI_Comm_accept in the GUI and MPI_Comm_connect in the compute part establishes an intercommunicator that can be used for sending messages between the two parts. The compute part could e.g. send periodic status messages to the GUI. If necessary, the intercommunicator could be further "flattened" to an intracommunicator.
Once the computation is finished, the communication part should disconnect by calling MPI_Comm_disconnect.
The GUI should call MPI_Close_port and finish its own execution.
In that scenario, the GUI part could be a text mode curses application started locally or remotely via SSH, an X11 GUI application, or whatever else there.

It should work. The comment about "parallel" suggests multithreading, which can mean that your output is not flushed as one might expect.
Likely this is the same issue (Ncurses limited output size) for which more information was given. Neither question provides enough detail to offer more than generic advice.

Related

Invoking a console application from C++ program

I have an console application 'app.exe', which i want to invoke from a C++ program and then communicate with it as if it was a command line. Essentially I want to make a C++ wrapper around another console application so that I could pass input to it at will and receive output.
In pseudo-code something like:
std:string input("...some parameters..."), output;
Process app("app.exe");
app.InputOutput(input, output);
std::cout<<output;
This must have been answered already, but I seem to lack proper terminology to look it up.
In case it matters, I am running Eclipse CDT on Windows 10 with GCC 5.3.0
EDIT: I need to be able to repeatedly send some values to 'app.exe' and repeatedly receive response, rather than just invoke it with parameters. This is needed for a small personal project so I do not care about it being platform-specific.
I used this code as a starting point, in an MFC dialog, to display output from a called process. It was rather painless as this is well documented. He tells you why he is doing what. It should be suitable as you are working with the Windows platform. But as Alf points out, cross platform is something else.
You can use the system function to invoke a shell (command line) command.
That command can be to execute a program with the arguments you want.
system returns the process exit code, but for other results there is no direct support. One easy way to access the output, for a program that just does a job and ends, is to redirect the program's output to a file.
Otherwise you'll have to use communication mechanisms such as pipes or Windows mailslots, that are not supported by the C++ standard library, i.e. you're then into platform-specific code.

How can I determine whether the current process has a UI open?

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.

Get trigger from console in C++

I am writing an application for a robot.
The required UI for the application is described in the pseudo-code below:
while(true){
if (spacebar is not pressed){
//do something
}
else{
sleep(1); //wait for a second
}
}
If I use cin or some other console input reading function then it will wait for user to press something. How do I ensure that it does not wait to get any input?
I am using Ubuntu. But I do not want it to be OS-specific.
Answers here seem to be OS specific.
Terminal Level input
What you are asking for is fairly close to the hardware (key-press / key-release) compared to the "standard input/output" stream concepts. So your implementation would have to be OS specific. Having said that the library to use is curses[1] which has been around for a long time and is standard on a lot of Un*x platforms. The GNU ncurses flavor compiles for pretty much all of them, it is a standard install in almost all Linux environments, and where it isn't installed by default you can find it. It also works well in Windows (cygwin), os/2 and a bunch of embedded systems etc. so you should be able to write a fairly portable software using curses that does what you want.
It's not too clear what you're asking for. In the if, is the
condition based on whether a space character has been entered,
or whether the user is currently holding down the space bar? In
the first case, you need something like curses (a portable
library which does gets each character as it was entered,
without echo). In the second, I don't think that there is
a portable solution. Even non-portably, you might not be able
to get it if your program is reading from a terminal window
(e.g. xterm); this sort of information is typically only present
as window events, when you created the window in your program.

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.)

Clear console using C++ with Xcode?

I'm trying to make a C++ console application using Xcode 4.1, but I can't find the command for cleaning the screen while the program is executing...
Any ideas? Thanks!
OSX doesn't have "consoles" the way Windows does. It has pseudoterminals, which act like an old-fashioned glass terminal to the program running "inside" them, and like a bidirectional pipe to the program that set them up. That outer program can do whatever it likes with the inner program's input and output. Notable examples of such programs are Terminal.app, which emulates the venerable VT-100, and ssh, which forwards the I/O over a secure channel to its own controlling terminal (which is probably itself a pseudoterminal). This is all by way of saying that there isn't a method that's guaranteed to work, because maybe the program on the outside of the pseudoterminal doesn't have a "screen" that you can meaningfully "clear." (Expect is a good example of a program like that.)
Having said that, though, if there is a screen, these days you can pretty much count on it to respect the VT-100 control codes. So this should do what you want:
std::cout << "\033[2J" << std::flush;
If you find that you need even one more control code, though, it's time to hook your program up to ncurses, which presents a nice friendly API to all the tricks that modern terminal windows are capable of, and will also have your back in the increasingly unlikely event that your program is attached to a terminal (or a program emulating a terminal) that is not a VT-100 nor one of its descendants.