我试图在子进程中调用 exec(),并在父进程中等待。当我在父进程中使用 'wait()' 时它工作正常。但是我喜欢获取子进程的状态码,所以我使用了waitpid(),但它等待失败。不知道为什么,请帮忙,不胜感激!
int runcgi(int socket, char *uri, char *dir)
{
pid_t pid;
int status = 0;
char command[MAXPATHLEN];
snprintf(command, MAXPATHLEN, "%s%s", dir, strsep(&uri, "?"));
printf("%s\n", command);
if ((pid = fork()) < 0)
{
syslog(LOG_INFO, "Error forking");
return -1;
}
else if (pid == 0)
{
if (dup2(socket, STDOUT_FILENO) < 0)
{
syslog(LOG_ERR, "Error duping STDOUT_FILENO");
status = -1;
exit(EXIT_FAILURE);
}
if (dup2(socket, STDERR_FILENO) < 0)
{
syslog(LOG_ERR, "Error duping STDERR_FILENO");
status = -1;
exit(EXIT_FAILURE);
}
if (setenv("PATH", dir, 1) != 0)
{
syslog(LOG_ERR, "Failed to set PATH=%s", dir);
status = -1;
err(EXIT_FAILURE, "Failed to set PATH=%s", dir);
}
if (uri != NULL && strlen(uri) > 0)
{
char *var;
while ((var = strsep(&uri, "&")) != NULL)
{
if (putenv(var) == -1)
{
syslog(LOG_ERR, "Failed to set env %s", var);
status = -1;
err(EXIT_FAILURE, "Failed to set env %s", var);
}
}
}
execlp(command, basename(command), (char *)0);
status = -1;
}
if (waitpid(pid, &status, 0) == -1)
{
syslog(LOG_ERR, "waitpid failed");
err(EXIT_FAILURE, "waitpid failed");
}
if (WIFEXITED(status))
{
return WEXITSTATUS(status);
}
// (void)wait(NULL);
return status;
}
奇怪的是,当我检查 errno 时,我得到“没有这样的文件或目录”。
答案 0 :(得分:1)
将 status
传递给其父级的代码在哪里?孩子将 status
设置为 -1
但随后没有对它做任何事情!你想让孩子_exit(status);
吗?
你收到一个错误,因为孩子试图等待一个他没有的孩子
有。此处的错误“没有此类文件或目录”仅表示 PID 不对应于子进程中的任何进程,因为子进程从 fork
获得零返回。
这是孩子身上发生的事情:
else if (pid == 0)
{
... // lots of code here
execlp(command, basename(command), (char *)0);
status = -1;
}
if (waitpid(pid, &status, 0) == -1)
请注意,如果 execlp
失败,请将 status
设置为 -1
。但是你什么都不用做。然后您在子进程中调用 waitpid
,但是 pid
在这里为零!您错过了孩子对 _exit
的呼叫。