我需要找到一种从execl命令获取状态的方法。我调用execl来获取需要作为守护进程(后台进程)运行的进程,该进程将由init进程继承。但是,即使execl调用本身没有失败,我尝试execl的进程也可能会退出。因此,execl成功运行并且不会返回到父代码,但是我尝试执行的进程可能会异常退出。我从主进程中分叉两次,在孙进程中运行execl,根据将由主进程捕获的孙子的状态退出子进程,并将成功或失败返回给调用者。
问题在于,在子进程(execl'ed进程的父进程)中我不能使用没有WNOHANG的waitpid,否则如果execl'ed进程没有退出,它会永远等待,另一方面我不能使用与WNOHANG一起,因为如果子进程在孙子(调用execl)之前被调度,它只会说孙子没有被退出(这是我的应用程序中的成功案例),即使孙子可能在execl执行后异常退出。
我试图使用管道,但我认为它不起作用。 (在管道写入之后的上下文切换,在execl或多核调度之前会再次破坏所有内容)我在这里附加代码段,这与我尝试使用的类似。可以请你帮我解决这个问题吗?感谢。
int pid;
pid = fork();
const char* command_cstr = "pwd"; // this is only a placeholder.
if ( pid < 0 ) {
return -1;
}
if ( pid == 0 ) { // CHILD CODE
int fd[2];
int val;
setsid();
pipe(fd);
pid = fork();
if ( pid < 0 ) {
exit(1);
}
if ( pid == 0 ) { // GRANDCHILD CODE
close(fd[0]);
val = 1;
write(fd[1], &val, sizeof(val));
close(fd[1]);
execl("/bin/bash", "bash", "-c", command_cstr, NULL);
exit(1); // exits only when execl returns on error
}
// CHILD CODE
// wait until grandchild process is executed
close(fd[1]);
read(fd[0], &val, sizeof(val)); // blocks until child writes
close(fd[0]);
int grandchild_status;
waitpid(pid, &grandchild_status, WNOHANG);
if (WIFEXITED(grandchild_status) == false) {
exit(0); // success case, execl alive
} else {
exit(1); // fail case, execl exitted
}
}
// PARENT CODE
// Reap the child, leaving the grandchild to be inherited by init
int child_status;
waitpid(pid, &child_status, 0);
// If the child exited with 0, it managed to fork and execl didn't exit
if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) {
// Child forked and exited successfully
return 0;
} else {
// If the child did not exit with 0
return -1;
}
}