Creating a Child Process using posix_spawn in C in Linux
Posted on In Linux, ProgrammingThe posix_spawn()
and posix_spawnp()
functions create a new child process from the specified process image constructed from a regular executable file. It can be used to replace the relative complex “fork-exec-wait” methods with fork()
and exec()
. However, compared to fork()
and exec()
, posix_spawn()
is less introduced if you search on the Web. The posix_spawn()
manual provides details. However, it is still not sufficient especially for beginners. Here, I give an example of C program using posix_spawn()
to create child processes.
The program is to run the command by /bin/sh -c
that you pass as the first argument to the program. The run.c source code is as follows.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
void run_cmd(char *cmd)
{
pid_t pid;
char *argv[] = {"sh", "-c", cmd, NULL};
int status;
printf("Run command: %s\n", cmd);
status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
if (status == 0) {
printf("Child pid: %i\n", pid);
do {
if (waitpid(pid, &status, 0) != -1) {
printf("Child status %d\n", WEXITSTATUS(status));
} else {
perror("waitpid");
exit(1);
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}
void main(int argc, char* argv[])
{
run_cmd(argv[1]);
return;
}
From the example, you can find the posix_spawn()
has its advantages and flexibility over other similar ones although it is a little tedious with 6 arguments.
- Different from
system()
andexec()
, it returns the new child process’ pid which you can wait bywaitpid()
. Of course,system()
is something you should forget that you have learned it in most situations. - Difference from
fork()
/vfork()
, the logic you implement is within the same process and you do not need to think about which piece of code is executed by the child process and which is executed by the parent process. It also avoid problems fromvfork()
.
Thanks for the example. Can you please let me know how to use the other NULL values that are used in the example?
Then I will refer you to the man page: https://www.systutorials.com/docs/linux/man/3p-posix_spawn/ . The man page is a bad source for getting started to use posix_spawn which is the purpose of this post. But the man page is a good source for references of the specific options and meanings of each parameters.
Thanks for this clear and useful example.
Hi
What is environ variable here.
And can you further explain how to let the child notinherit the parents FD.
Is it possible that my child doesnt inherit any fd of parent.
Well, Iam trying to run this using socket connection and the client fd is in CLOSED_WAIT state.
As i am running a code with infite loop in it .
This is making my socket to be in CLOSED_WAIT
ex : run_cmd(/bin/infi_loop);
Hi Tejas,
You can find many details not covered in this post in the posix_spawn manual: https://www.systutorials.com/docs/linux/man/3p-posix_spawn/ :
For your purpose to let the child not inherit parents FDs, you may have at least 2 choices.
1. Add the FD_CLOEXEC flag to the the socket FD by fcntl https://www.systutorials.com/docs/linux/man/3p-fcntl/ .
2. Specify a file_actions for the posix_spawn to close the FDs.
“Of course, system() is something you should forget that you have learned it in most situations”
what you mean about should forget? why?
For one quick reference, please check https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177 .
I believe you should use WIFEXITED and WEXITSTATUS when managing the child’s return status.
How can you open a console to view the output of the process ?
Like the CREATE_NEW_CONSOLE in CreateProcess
Good point. The example code is updated with changes as follows to make it more accurate.
For “a console” I guess you mean a terminal emulator like
xterm
? You may execute command likewhich will start an
xterm
and execute the/path/to/cmd
. An X server should be ready forxterm
to start.