Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I execute external program within C code in linux with arguments?

Tags:

c

linux

I want to execute another program within C code. For example, I want to execute a command

./foo 1 2 3 

foo is the program which exists in the same folder, and 1 2 3 are arguments. foo program creates a file which will be used in my code.

How do I do this?

like image 960
js0823 Avatar asked Mar 08 '11 19:03

js0823


People also ask

Can you execute one program within another in Unix?

On Unix, one of the exec*( ) family of functions is used to replace the current program within a process with another program. Typically, when you're executing another program, the original program continues to run while the new program is executed, thus requiring two processes to achieve the desired effect.


2 Answers

For a simple way, use system():

#include <stdlib.h> ... int status = system("./foo 1 2 3"); 

system() will wait for foo to complete execution, then return a status variable which you can use to check e.g. exitcode (the command's exitcode gets multiplied by 256, so divide system()'s return value by that to get the actual exitcode: int exitcode = status / 256).

The manpage for wait() (in section 2, man 2 wait on your Linux system) lists the various macros you can use to examine the status, the most interesting ones would be WIFEXITED and WEXITSTATUS.

Alternatively, if you need to read foo's standard output, use popen(3), which returns a file pointer (FILE *); interacting with the command's standard input/output is then the same as reading from or writing to a file.

like image 164
Erik Avatar answered Sep 23 '22 20:09

Erik


The system function invokes a shell to run the command. While this is convenient, it has well known security implications. If you can fully specify the path to the program or script that you want to execute, and you can afford losing the platform independence that system provides, then you can use an execve wrapper as illustrated in the exec_prog function below to more securely execute your program.

Here's how you specify the arguments in the caller:

const char    *my_argv[64] = {"/foo/bar/baz" , "-foo" , "-bar" , NULL}; 

Then call the exec_prog function like this:

int rc = exec_prog(my_argv); 

Here's the exec_prog function:

static int exec_prog(const char **argv) {     pid_t   my_pid;     int     status, timeout /* unused ifdef WAIT_FOR_COMPLETION */;      if (0 == (my_pid = fork())) {             if (-1 == execve(argv[0], (char **)argv , NULL)) {                     perror("child process execve failed [%m]");                     return -1;             }     }  #ifdef WAIT_FOR_COMPLETION     timeout = 1000;      while (0 == waitpid(my_pid , &status , WNOHANG)) {             if ( --timeout < 0 ) {                     perror("timeout");                     return -1;             }             sleep(1);     }      printf("%s WEXITSTATUS %d WIFEXITED %d [status %d]\n",             argv[0], WEXITSTATUS(status), WIFEXITED(status), status);      if (1 != WIFEXITED(status) || 0 != WEXITSTATUS(status)) {             perror("%s failed, halt system");             return -1;     }  #endif     return 0; } 

Remember the includes:

#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> 

See related SE post for situations that require communication with the executed program via file descriptors such as stdin and stdout.

like image 22
Jonathan Ben-Avraham Avatar answered Sep 21 '22 20:09

Jonathan Ben-Avraham