I'm developing a chat server in C++. The programme is built and run from a terminal. As running in the terminal, I can write to this terminal normally using 'printf'. Some of the information written to this terminal are the alerts of new incoming connections, outgoing connections, etc.
Now I need to get the keyboard input so that admin can type commands to see the values of variables in the chat server. I intend to create a new thread and attach a new terminal to it. A suggestion is to call system("gnome-terminal"), but it requires a little delay with sleep(), doesn't seem to be a good choice because all the contents redirected to this gnome-terminal will be considered as bash commands. And I don't know how to attach the terminal opened by 'system'` command to the thread.
Any simple way to attach a terminal to created thread?
Maybe have a read of this on how to use pipes in Linux
http://linuxprograms.wordpress.com/tag/pipes/
As partially answered in this question: Avoid gnome-terminal close after script execution?
There is a good option like this:
(1) Use the main terminal for normal input/ouput.
(2) Create log file (log.file) before calling 'tail'
(3) Use 'tail' command for showing log contents (log files)
//c++ code
system("gnome-terminal -e \"bash -c 'tail -f log.file'\"");
(4) Append the content to 'log.file' to tell 'tail' to show it up.
Related
I have a python script that outputs to the console every 10 seconds or so.
I want to run that script from my c++ code, and keep it running to continue getting updates until I close my app. If I use popen, I can get the output line by line, without having to wait for the script to "finish", but I cannot kill it when I close my app now.
Is there a way to read the output of a script as it is spit out, keeping the script running until I close my qt app?
Thanks!
QProcess allows you to call a external process from code. The documentation includes information on how to close it within the program. Also you can use the read/write channels for communication.
There are some examples in the documentation and method descriptions, for getting started.
Does someone know how to open the terminal and execute several commands using a C program ?
I have a program in C and another sets of commands executed by the terminal. I need to combine them into one program in C.
I'm using Ubuntu 10.04.
Thanks!
Your question may be somewhat misleading.
Because you want to run all the terminal commands in the c-code, perhaps you actually have only textual input / output with these commands. If so, you probably do not need the terminal.
I use popen when the output of the (terminal) program is a text stream. It is probably the easiest to use. As an example:
...
const char* cmndStr = "ls -lsa";
FILE* pipe = popen(cmndStr, "r");
...
The popen instruction executes the command in the cmndStr, and any text written to the commands (ls -lsa) standard output, is redirected into the pipe, which is then available for your C program to read in.
popen opens a separate process (but without a terminal to work in, just the pipe)
'Fork' is another way to launch a separate process, with some control over the launched processes' std i/o, but again, I think not a terminal.
On the other hand, if your output is not a simple text stream, maybe you can get by with a output-only dedicated terminal screen to accommodate special output activity. For instance, when I work with ncurses:
I manually open a terminal in the conventional way, and in the terminal
issue the command "tty" to find out the device name, and
issue a "cd" to set the focus to the working dir.
dmoen#C5:~$ tty
/dev/pts/1
dmoen#C5:~$ cd work
dmoen#C5:~/work$
Then I start my program (in a different tty), and let the program know which device I want it to use for the special output (i.e. /dev/pts/1 ) ... I typically use command line parameters to tell my program which pts or extra terminals I want it to use, but environment variables, pipes, in/out redirection, and other choices exist.
I have not tried (lately) to launch a terminal (as suggested by smrt28), except in shell. I believe this will work, but I do not see how the output from the terminal command (ls in the example) would be delivered back to your program. popen trivially delivers a text stream.
A long time ago, I used a device called 'pty' which works like a terminal, but I don't remember how to connect it usefully.
There is a set of 'exec' commands ... see man exec. To connect them back to your program, you will probably work with files, or perhaps redirecting i/o. Too many choices to list here.
And also, maybe you can connect these commands with your c program using shell pipes.
Check "man xterm", parameter -e. Then, in C, you can:
system("xterm -e ls")
I have to write a program that intercepts data from terminal and i have to parse it. After processing when the data, i have to parse it before it goes to stdout.
I can't use tee or commands like prog > file 2>&1 as the program is going to be interactive.
For example :
If the user types ls in the terminal i have to parse it then it should go operating system and then when I get the result after processing I ll have to again parse it before it's displayed in the terminal.
I did my research and I think I can achieve it through pseudo terminal interfaces ( pty ).
Please let me know if there is a better way to achieve it.
I am using cpp and bash and the platform is *nix.
Update:
I can also use libexpect from expect.
I am not sure what do you mean here - you mean interactive program as "working in another terminal communicating with user" or even displaying GUI?
How does it specify the terminal? It is probably important what is program layout here (which program starts which).
If your application uses GUI to communicate with user, then I would simply do it this way:
start bash with sdtin and stdout attached to pipes,
your program reads & writes to it's end's of those pipes, parses data, and reads/writes on it's own stdin&stdout - so it appears on it's terminal.
If you mean controlling different terminal than your application's, it gets though since system generally does not expect program operating on multiple terminals. I don't think it's possible to filter communication between terminal and already working application attached to it. Starting another process spawning another terminal might be an option - to have basically two terminals working in sync. But then you will have to synchronize both processes by some other means (named pipes, network connection or some other IPC).
If you provide more detail on your program I might provide more directed help.
PS Don't tell me that you are writing some terminal keylogger ')
EDIT:
Your program is probably GUI based then - what i would recommend would be something similar to answer linked by banuj.
Best option will probably be to create three pipes, then fork, and in child process assign corresponding ends of pipes to stdin, stdout and stderr. Then child process should exec into shell - probably bash, although I am not sure if other shells would sound better if read out loud ;) Main process will be able to read/write other ends of mentioned pipes, parsing both inputs and outputs to bash and programs it runs.
You could also exec directly to commands user specifies, but that forces you to take over tedious job of a shell - managing current directory, environment variables, job control and so on.
Using above method might however cause some trouble - some programs (usually in security related contexts - eg. su(do) asking for password) will try to bypass stdin/stdout anyway and read directly from terminal device. I am not sure what can you do in such case - programing your own terminal emulator would be an option, but I don't know if you want to go this deep into system programming for this.
If you want some code snippet's, if you don't know how to do above, just ask ;)
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.
I have written a simple program that pings three sites and then reacts to whether they are reachable or not.
My question is: can I suppress system("ping ")'s output? I have written my code in C++ as I know that language the best. Currently the code opens the ping.exe running the system command. If I can prevent the output from showing up while it still pings that would be ideal.
I am eventually going to turn this program in a windows service that is why I would like to suppress both the command line console window as well as suppress the ping output. Thanks.
Try doing system("ping host > nul") (nul is windows equivalent of UNIX /dev/null).
Generally, if you're going to call another program but don't want it to act like std::system, you're going to need a platform-specific function like fork()/exec() on UNIX or CreateProcess() on Windows. These functions give you control over how the other program runs, for instance, that it not show output or not create a console window, etc.
You can use system command like below to suppress the output of ping command.
system("ping 100.100.100.100 > response.dat");
Above command pings IP address 100.100.100.100 and directs the output to a file called response.dat. In response.dat you can see the response of ping command.
Do system( "ping site.com >nul 2>nul" ); and check the value the shell returns.
if the ping succeeds, the shell will return 0, else it will return 1.
I would be more detailed, but Vis Studio is reinstalling itself. :)
There's also a way to hide the console window using the Win API to exec the command, but...
I do not remember the details.
Edit:
I'm still waiting for the MSVS install process, so... :)
Use CreateProcess with the DETACHED_PROCESS flag for the dwCreationFlags parameter to hide the console window.
After you call create process, you'll have to use WaitForSingleObject on the process handle to wait for the ping to complete. The last parameter to CreateProcess should have a pointer to process information that contains the process handle. (Assuming CreateProcess was successful) You have to wait for the command to complete. Once it's complete, you can use the process handle to get the return value, though I'm too time contstrained to tell you how to do that at this point.
When you get over to Windows and call CreateProcess(), be sure to set:
lpStartupInfo->wShowWindow = SW_HIDE;
This will ensure that any windows created by the new process are hidden.
Using the DETACHED_PROCESS flag will prevent the new process from inheriting your application's console, but that does not prevent the new process from creating a new console. Not sure what ping would do, but best to remove all doubt by using SW_HIDE.
You could also use this way, this will return the output in a file and doesn't show up a console windows and freezes the main application which is really usefull.
At first you need to include the Windows header using;
#include <Windows.h>
then send a ping command and write the output into a file like this;
WinExec("ping google.com > file.dat", SW_HIDE);
This will send a ping command to google.com and writes the output to the file 'file.dat' in the directory of your current running program. So you could change file.dat to any file or filepath you want and of course you could change the ping command. The > character means that the output of the command needs to be wrote in the file path behind it.
If you want to show the console window and freeze the application while running the ping command you need to use the following line of code instead of the WindExec() code;
system("ping google.com > file.dat");