我试图在一个单独的UTS命名空间内运行一些代码,我一直在尝试用c。
我有一个父函数,代码如下:
void run (char **args, int arglen) {
printf("[*] Starting PID: %dn", 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: %dn", getpid());
system(cmd);
printf("testn");
}
,我想在父程序关闭之前运行任何命令。
问题是一些命令(例如/bin/ls
)设法执行,其他(较慢的)命令(例如/bin/sh
)在parent结束时被关闭。
由于我使用了等待函数,我不明白为什么执行会停止。
我尝试在克隆后在父进程中使用sleep,它延迟了程序的结束。这应该意味着问题是父进程没有等待它的子进程。
我尝试了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: %dn", 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: %dn[*] Status: %dn", e_code, status);
return;
}
void child_container () {
printf("This is the container!n");
printf("[*] Child PID: %dn", getpid());
system(cmd);
printf("testn");
}
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;
}
从克隆的手册页中提取
子终止信号
子进程终止时,可能会向父进程发送一个信号。终止信号在low中指定(clone)())或在cl_args中。exit_signal (clone3())。如果这个信号被指定为SIGCHLD,那么父进程在使用wait等待子进程时必须指定__WALL或__WCLONE选项。(2).如果没有指定信号(即零),则在子进程终止时不向父进程发出信号。
所以,答案很清楚。您没有指定信号,所以当子进程终止时不会通知您,所以wait没有什么可等待的。
pid_t child_pid = clone(child_container, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWPID | SIGCHLD, NULL);
应该解决这个问题(至少,没有它,你就没有机会让等待工作)