Open a process from file, in C++ on Linux - c++

I'm coding my application in C++ on Linux. C++ has a function called 'system' to execute a programme.
I try to open the gnome-system-monitor from C++ like this:
system("gnome-system-monitor");
However, the thread of my application blocks when I call this 'system' function until I close the window of gnome-system-monitor.
Any other ways to open a process from file without blocking the caller process?

The classic way, which works on any Linux or otherwise POSIX-based system, is
if (0 == fork()) {
execlp("gnome-system-monitor", "gnome-system-monitor", (char *)NULL);
}
(with error handling omitted from this example.) This (a) creates a new process, (b) in that new process, runs "gnome-system-monitor" after searching the PATH environment variable to find such a command, (c) passes it the name "gnome-system-monitor" as argv[0] and no other arguments. In the parent, once the new process is created it barrels on ahead without waiting for any result.
See the man pages for fork and execlp for more details.

fork/exec or posix_spawn. glib also has GSpawn if you are using that.

Gnome is built above GTk (which contains Glib), and you probably want the Glib Spawning Processes functions.
Of course, on Linux and Unix, processes are forked. Read a good book like
advanced unix programming and advanced linux programming to learn more about syscalls related to processes, notably fork(2), execve(2), pipe(2). Read also about the proc(5) filesystem.

Yes. Call System function on a separte thread.

Related

Windows Parent and Child Process creation

I want to create 5 child process in Windows using C++. But I am confused that CreateProcess asks for lpApplicationName and not like fork in which I can figure out whether I am child or parent. how to do this in Windows
Unfortunately the CreateProcess function can only be used to load a program and start a new process for that program.
You can however use CreateProcess to simulate the fork functionality, by asking it to load the program you are already running, and then ask it to jump to the correct position. This is what is (or was, at least) done by Cygwin, as referenced by this old answer.
It is usually preferable in Windows to use threading rather than multiple processes, because processes are much heavier objects in Windows than in UNIX.
However, you can do what you're asking by passing the name and path of your application to CreateProcess (using GetModuleFileName if you don't already know it) and including a command-line argument to tell your application that it is being launched as a child process.
Keep in mind that the child processes will be started from scratch, they will not have a copy of the parent's memory as they would if you were using fork.

launch an exe/process with stdin stdout and stderr?

With C++ how do i launch an exe/process with stdin stdout and stderr? I know how to do this in .NET and i remember using popen in the past but popen seems to allow stdin OR stdout not both and not all 3.
I need this for windows but a linux solution is welcome as i'll need it for the same project in the future.
You shoud use CreateProcess from WinApi. It takes as argument an object of struct STARTUP_INFO type. You can set hStdin, hStdout, and hStderr fields of the object to redirect those streams of child process to file handles you want (file, pipe, socket...)
A portable solution would be boost.process
(Note: this has been proposed as a Boost library, and released under the same license terms, but not officially accepted. See also Where is Boost.Process?)
I had troubles with spawning processes and reading or writing to their stream, but then I discovered a great C++ library which is very very convenient.
This open-source project is called tiny-process-library and was created by eidheim (a big thanks to him).
A small platform independent library making it simple to create and
stop new processes in C++, as well as writing to stdin and reading
from stdout and stderr of a new process.
Features
No external dependencies
Simple to use
Platform independent
Read separately from stout and stderr using anonymous functions
Write to stdin
Kill a running process (SIGTERM is supported on Unix-like systems)
Correctly closes file descriptors/handles
I am sharing this here because I first come to this thread before finding the library several hours later, so I hope it can save some time for further readers.

Communication with a script from a C++ program

I have a c++ program (very complicated, and lengthy both in code and execution time).
Once in a while this program stops and calls a user-specified shell script.
Before calling the script, my program creates a .out file with current data. I call the script via system() command. The script then reads the .out file, and creates its own script.out file and exits.
Then the system() function call ends, and my program reads and parses the script.out file.
Question: is there a better way to execute communication between my c++ program and a random shell script?
My intent is to have full communication between the two. Script could virtually "ask" the program "What data do you have right now?" and the program would reply with some strict convention. Then the script could say "Add this data...", or "delete all your previous data" etc.etc.
The reason I need this is because the shell script tells the program to modify its data. The exact data that was put in the original .out file. So after the modification is done -- the actual data held by the program does not correspond to the data written in the .out file.
Thanks!
P.S.
I swear I've searched around, but everyone suggests an intermediate file.
There are certainly ways to do that without intermediate files. The most common approach is to use command line arguments for input, and pipes for standard output; others also use pipes for input. The most straight-forward alternative to system then is to use popen.
On a unix-like system? Perhaps pipe (2) will work for you?
From the man page (Mac OS X 10.5 version):
SYNOPSIS
#include <unistd.h>
int pipe(int fildes[2]);
DESCRIPTION
The pipe() function creates a pipe (an object that allows unidirectional
data flow) and allocates a pair of file descriptors. The first descrip-
tor connects to the read end of the pipe; the second connects to the
write end.
You will, of course, have to follow the creation of the pipes with a fork and exec pair. Probably this has already been answered in detail, and now you know what to search on...
It's been a while since I did this, but:
In the main process, before forking the sub-process you call pipe twice. Now you have two pipes and control both ends of both of them.
You fork.
The main process will read from one pipe and write from the other. It doesn't matter which is which, but you need to be clear about this.
The child process will call one of the exec family of function to replace it's image with that of the shell you want to run but first you will use dup2 to replace it's standard input and output with the ends of the two pipes (again, this is where you need to be clear about which pipe is which).
At his point you have two processes, the main process can send things into one pipe ad they will be received on the standard input of the script, and anything the script writes to it's standard output will be sent up the other pipe to the controlling process. So they take turns, just like interacting with the shell.
You can use pipes or (maybe more convenient) sockets - for example frontends to gdb, or expect do that. It would require changes to your shell scripts, and switching from system() to more low-level fork() and exec().
It's rather complicated so please, be more specific about your environment and what you need to clarify.
You are asking the question on Interprocess Communication (IPC).
There are a lot of ways to do that. You can do a simply search and Internet will return you most answers.
If I am not wrong, Google chrome uses a technique called Named Pipe.
Anyway, I think the most "portable way" is probably a file. But if you know you are working on which operating system, you can definitely use most of the IPC techniques.

How to interface with an executable in C++

I have an executable that I need to run some tests on in C++ - and the testing is going to take place on all of Windows, Linux and Mac OSes.
I was hoping for input on:
How would I interface with the previously built executable from my code? Is there some kind of command functionality that I can use? Also, since I think the commands change between OSes, I'd need some guidance in figuring out how I could structure for all three OSes.
EDIT - Interface = I need to be able to run the executable with a command line argument from my C++ code.
The executable when called from the commandline also ouputs some text onto a console - how would I be able to grab that ouput stream (I'd need to record those outputted values as part of my tests).
Feel free to ask me follow up questios.
Cheers!
If you use qt to develop your code, you'll find QProcess will allow you to spawn a command line program in a platform-agnostic way.
Essentially:
QObject *parent;
QString program = "yourcommandlineprogram";
QStringList arguments;
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
You can then read from the process with various function calls such as readAllStandardOutput (), and write to the input of the process with QProcess::write(QString).
Alternatively, if you prefer Boost to Qt, Boost.Process will also let you launch processes. I confess I don't like the syntax as much...
boost::process::command_line cl("yourcommandlineprogram");
cl.argument("someargument");
boost::process::launcher l;
l.set_stdout_behavior(bp::redirect_stream);
l.set_merge_out_err(true);
l.set_work_directory(dir);
boost::process::child c = l.start(cl);
You can then work with your subprocess 'c' by using stream operators << and >> to read and write.
All those OSes support some form of "subprocess" calling technique, where your tester creates a new child process and executes the code under test there. You get to not only pass a command line, but also have the opportunity to attach pipes to the child process' standard input and output streams.
Unfortunately, there is no standard C++ API to create child processes. You'll have to find the appropriate API for each OS. For example, in Windows you could use the CreateProcess function: MSDN: Creating Processes (Windows).
See also Stackoverflow: How do you spawn another process in C?
As I understand, you want to:
Spawn a new process with arguments not known at runtime.
Retrieve the information printed to stdout by the new process.
Libraries such as QProcess can spawn processes, however, I would recommend doing it by hand for both Windows and MacOS/Linux as using QProcess for this case is probably overkill.
For MacOS/Linux, here's what I would do:
Set up a pipe in the parent process. Set the read end of the pipe to a new file descriptor in the parent.
fork.
In newly created child process, set stdout (file descriptor #1) to the write end of the pipe.
execvp in the newly created child process and pass the target executable along with what arguments you want to give it.
From the parent process, wait for the child (optional).
From the parent process, read from the file descriptor you indicated in Step 1.
First of all, is it possible that you simply need to want to make your original code reusable? In that case you can build it as library and link it in your new application.
If you really want to communicate with another executable then you can need start it as a subprocess of the main application. I would recommend the Process class of the Poco C++ libraries.
Looks like a job for popen(), available on Linux, Windows, and OS X
Sounds like you are only planning to do functional testing at the executable level. That is not enough. If you plane to do thorough testing, you should also write unit tests. For that there is some excellent frameworks. My prefered one (by far) for C++ is BOOST::Testing.
If you control source code there is also common tricks for functional testing beside launching exe from an external process : embed functional tests. You just add an option to your program that execute tests. This is cool because tests are embedded in code and autocheck can easily be launched in any execution environment.
That means that in the test environment, as you call your program with some test dedicated arguments, nothing keeps you from going the full way and redirect the content of stdout and even check the tests results from within the program. It will make the whole testing much easier than calling from an external launcher, then analysing the results from than launcher.

Where can I learn how to make a C++ program interact with the Operating System (Linux)

I am a C++ beginner.
I'd like to create small programs that interact with the operating system (using Kubuntu Linux). So far, I have not been able to locate any tutorial or handbook to get C++ to interface with the OS.
In PHP, I can use the command exec() or the backtick operator to launch commands typically executed in a console.
How can I do similar things in C++?
How can I get my C++ program to execute any other command?
How can I get the output of such commands?
Thanks.
You can use system() to execute arbitrary commands but, if you want to easily control the input and output with the program, you should look into popen().
For even more control, you can look into doing exactly what a shell might do, creating some extra file descriptors, forking to start another process, setting up file descriptors 0, 1 and 2 (input, output and error) in that process to connect them to your original process file descriptors then exec'ing the program you want to control. This isn't for the faint of heart :-)
You can use the system() command in stdlib to execute system commands:
#include <stdlib.h>
int main() {
system("ls -l");
}
system() returns an int as its return value, but the value of the int is system-dependent. If you try and use a command that doesn't exist, you'll get the standard "no such command" output back, and usually a non-zero return value. (For example, running system("ls -l"); on my Windows XP machine here returns a value of 1.
You can use system() as instructed previously or you can use libraries which provide access to standard POSIX API. unistd.h and The GNU C Library include many functions for OS interaction. The possibilities with these libraries are endless as you can implement the functionalities yourself. A simple example: scan a directory for text files with scandir() and print the contents of the files.