The function below illustrates how to do this:
This function takes the parameterspid_t
exec_redirect(
const char *path, char *const args[],
int new_in, int new_out, int new_err
)
{
pid_t child;
// Fork new process
child = fork();
if (child == 0) {
// Child process
// Redirect standard input
if (new_in >= 0) {
close(STDIN_FILENO);
dup2(new_in, STDIN_FILENO);
}
// Redirect standard output
if (new_out >= 0) {
close(STDOUT_FILENO);
dup2(new_out, STDOUT_FILENO);
}
// Redirect standard error
if (new_err >= 0) {
close(STDERR_FILENO);
dup2(new_err, STDERR_FILENO);
}
// Execute the command
execv(path, args);
}
// Parent process
return child;
}
path
and args
which is the same as what you would normally pass to execv(3)
. In addition, there are three parameters, new_in
, new_out
, and new_err
which are (optional) file descriptors where the new application's standard input, output, and error, respectively, will be redirected from/to. To make redirection optional, we specify that if the descriptor parameter is -1
, then no redirection will take place.So how do we use this? The code snippet below executes the command line
/bin/myapp -l -p
, with input redirected from in.txt
, output redirected to out.txt
, and error redirected to err.txt
:On a closing note, it's also probably a good idea to...
char *cmd = "/bin/myapp";
char *args[] = { "/bin/myapp", "-l", "-p", NULL };
in = open("in.txt", O_RDONLY);
out = open("out.txt", O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
err = open("err.txt", O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
exec_redirect(cmd, args, in, out, err);
...
close()
the file handles in the parent process, after exec_redirect()
, just to prevent "inadvertently" accessing them while the child process is also doing the same. Yes, the pun was intended ;-)[Update: fixed some typos]
2 comments:
Hi,
How do we Ensure that Parent waits for the child to Complete Execution ?
Do we need to call WaitPId with the childs Pid ?
@Pavan,
Yup, if you want to synchronize the parent with the child termination, call a waitpid() on the parent, with the child's pid (or -1 to wait for any child).
Alternatively, if you just want some notification that the child has terminated, you can also just register a SIGCHLD handler and read the exit status of the child from there (also via waitpid).
Post a Comment