![](/img/trans.png)
[英]Can a child process wait for the parent process to terminate in Linux programming in C?
[英]Created child process with `clone()`. Why does `wait()` not wait for it to terminate?
我正在尝试在单独的 UTS 名称空间内运行一些代码,并且我一直在尝试在 C 中执行此操作。
我有一个父 function,代码如下:
void run (char **args, int arglen) {
printf("[*] Starting PID: %d\n", getpid());
int i=1;
cmd = concat_args(args, arglen);
pid_t child_pid = clone(child_container, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWPID, NULL);
int status;
wait(&status);
printf("[*] Exit code: %d", status);
return;
}
它创建了一个新进程并且应该等待它完成它的执行。
孩子有以下代码:
void child_container () {
printf("This is the container!\n");
printf("[*] Child PID: %d\n", getpid());
system(cmd);
printf("test\n");
}
我想在父母闭嘴之前运行任何命令。
问题是一些命令(例如/bin/ls
)设法执行,其他(较慢的)命令(例如/bin/sh
)在父级结束时关闭。
由于我使用了 wait function,我不明白为什么执行停止了。
我尝试在克隆之后在父级中使用睡眠,它延迟了程序的结束。 这应该意味着问题是父母没有等待它的孩子。
wait 和 waitpid 都试过了,进程还是结束了。
问题可能是新进程 ( /bin/sh
) 的产物吗? 我该如何解决?
编辑:
这应该是一个可重现的例子
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 0x3ff
#define STACK_SIZE 8192
static char child_stack[STACK_SIZE];
char *cmd;
char *concat_args(char **args, int arglen);
void child_container ();
void parse_command(char *cmd, char **args, int argc);
void run (char **args, int arglen);
char *concat_args(char **args, int arglen) {
char *cmd = (char *)malloc((BUF_SIZE+1)*sizeof(char));
memset(cmd, 0, BUF_SIZE+1);
strncat(cmd, args[0], BUF_SIZE);
for (int i=1; i<arglen; i++) {
strncat(cmd, " ", BUF_SIZE);
strncat(cmd, args[i], BUF_SIZE);
}
return cmd;
}
void run (char **args, int arglen) {
printf("[*] Starting PID: %d\n", getpid());
int i=1;
cmd = concat_args(args, arglen);
pid_t child_pid = clone(child_container, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWPID, NULL);
sleep(1);
int status, e_code;
e_code = wait(&status);
if (e_code == -1) {
perror("wait");
}
printf("[*] Exit code: %d\n[*] Status: %d\n", e_code, status);
return;
}
void child_container () {
printf("This is the container!\n");
printf("[*] Child PID: %d\n", getpid());
system(cmd);
printf("test\n");
}
void parse_command(char *cmd, char **args, int argc) {
if (!strcmp(cmd, "run")) {
run(args, argc-2);
} else {
error("No such command!");
}
}
int main(int argc, char **argv) {
const char *format = "./container run [cmd] [args]";
if (argc < 3) {
error("Wrong format!\nThe commands must be formatted in the following way:\t./container run [cmd] [args]");
return 0;
}
char *cmd = argv[1];
char **args = &argv[2];
parse_command(cmd, args, argc);
return 0;
}
从克隆的手册页中提取
孩子终止信号
当子进程终止时,可以向父进程发送信号。 终止信号在标志的低字节 ( clone ()) 或 cl_args.exit_signal ( clone3 ()) 中指定。 如果此信号指定为SIGCHLD以外的任何信号,则父进程在使用wait (2) 等待子进程时必须指定 __WALL 或 __WCLONE 选项。 如果没有指定信号(即零),则当子进程终止时,父进程不会收到信号。
所以,答案很明确。 您没有指定信号,因此当您的孩子终止时您不会收到通知,因此 wait 无需等待。
pid_t child_pid = clone(child_container, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWPID | SIGCHLD, NULL);
应该解决问题(至少,没有它,你没有机会等待工作)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.