0

I am writing an application in C++. In many places in my code I use system() function to run some commands. I am not sure this is an elegant solution and I would like to replace using this function by another way to call child processes.

There are two important issues to consider.

  1. First, I want to wait for the end of execution of this child process and check its return code.
  2. Second, sometimes these commands prints some important information in a terminal. I want these pieces of information to be read and stored by rsyslog. I am logging some events in my application by using syslog(LOG_INFO, "%s", "Some event occured."). Is it possible to log outputs from child processes in the similar way?

2 Answers 2

2

In many places in my code I use system() function to run some commands.

Not a good sign! system is really something that you should be vary of using – it's not a C++ function, it's not a system call, it's a C library that opens a shell to execute the command (OK, it's wrapped in <cstdlib>, but still) – not only is this a lot of overhead in most cases, it's also a common way to introduce security vulnerabilities in your program. It can also behave pretty surprising - your environment might make the shell behave interestingly.

So, don't use system unless you really want to

  1. find the /bin/sh program
  2. run it ,
  3. setting its arguments (argv) to -c what you passed to system()

The 3. point only makes sense if what you're executing is not just some other executable, but shell commands, i.e. something that might be possible to logically incorporate into your program in the first place.

I am not sure this is an elegant solution and I would like to replace using this function by another way to call child processes.

There's certainly a few ways, what you really should be doing really depends on what you're calling and why, how often.

First, I want to wait for the end of execution of this child process and check its return code.

You can do that with system as well, by the way, using WEXITSTATUS. For more details, see man 2 waitpid. Anyway, as said above, I'd discourage use of system.

sometimes these commands prints some important information in a terminal. I want these pieces of information to be read and stored by rsyslog.

Not to state the obvious, but maybe these commands should do their logging themselves?

Anyway, if you want to capture the output of a process you spawned, use libc/posix popen.

Again, I still would strongly recommend you look into the question whether what you're doing by calling external commands could instead be done through an existing library, so that you don't have to do the slightly awkward detour through asking your operating system to run another process and communicate with it.

0

I cannot check this for C++, but @Marcus answer says that popen() is available. This will provide your application with a FILE * object where you can read the stdout of the invoked command.

There is also a stand-alone command logger which sends its stdin to syslog.

It happens popen runs a command-line by invoking /bin/sh, so you can invoke a redirection of the app's stderr to a pipe to logger. This might mean you need to wrap the command to use Bash process substitution. So your popen command could be something like (untested):

fp = popen ("bash -c 'myApp myArgs 2>( logger -opts )'", "r");

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .