C 捕获父级中的子级错误
我正在尝试编写以下C赋值:一个程序如果接受两个参数,将运行第一个参数,然后在成功时运行第二个参数。 以下是我的想法:C 捕获父级中的子级错误,c,exec,fork,C,Exec,Fork,我正在尝试编写以下C赋值:一个程序如果接受两个参数,将运行第一个参数,然后在成功时运行第二个参数。 以下是我的想法: #include <stdio.h> #include <unistd.h> #include <assert.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> char ** split(char * s) { char
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
char ** split(char * s) {
char ** words = malloc(sizeof(char *));
int i = 0;
char * word = strtok(strdup(s), " ");
while (word) {
words = realloc(words, sizeof(char *) * (i + 1));
words[i] = malloc(strlen(word) + 1);
strcpy(words[i++], word);
word = strtok(NULL, " ");
}
words[i] = NULL;
return words;
}
int main(int argc, char * argv[]) {
char ** argv1 = split(argv[1]);
char ** argv2 = split(argv[2]);
int t = fork();
if (t == -1)
exit(1);
else if (t == 0)
execvp(argv1[0], argv1);
else {
int status;
wait(&status);
if (WIFEXITED(status))
printf("exit status %d\n", WEXITSTATUS(status));
}
return 0;
}
我尝试了WSIGNALED,WSTOPPED,但我真的不知道如何捕捉错误。我的搜索方向是正确的,还是完全不同的,例如启动一个shell,然后执行我的命令,错误是shell固有的,而不是命令本身的?您应该检查wait是否真的返回了什么。如果返回值不是您的childpid,则无法解释状态
if(wait(&status) != child)
{
printf("Error in wait\n");
return -1;
}
我使用这段代码来解释各种状态。我认为通过我使用的日志注释,代码很容易理解
如果您的孩子崩溃了,它将被一个信号而不是退出,在这种情况下,您还必须检查相应的宏
if(WIFEXITED(status) == 0 && WIFSIGNALED(status) == 0)
{
LOGGER(MODULE_TAG, DEBUG2) << "Child: " << pid << " still running";
setRunning(true);
setTerminated(false);
setTerminationSignal(0);
setExitStatus(-1);
}
else if(WIFSTOPPED(status))
{
LOGGER(MODULE_TAG, DEBUG2) << "Child: " << pid << " stopped";
setRunning(false);
}
else if(WIFCONTINUED(status))
{
LOGGER(MODULE_TAG, DEBUG2) << "Child: " << pid << " continued";
setRunning(true);
}
else
{
setRunning(false);
setTerminated(true);
if(WIFEXITED(status))
{
LOGGER(MODULE_TAG, DEBUG2) << "Child: " << pid << " terminated normally";
setTerminationSignal(0);
setExitStatus(WEXITSTATUS(status)); // Exitcode from the child
}
else
{
LOGGER(MODULE_TAG, DEBUG2) << "Child: " << pid << " terminated by signal";
setTerminationSignal(WTERMSIG(status));
setExitStatus(-1);
}
}
将您的呼叫更改为execvp。尝试:
非常感谢大家的意见。我只需要返回execv的潜在返回,然后它就成为原始fork等待的WEXITSTATUS
else if (t == 0)
**return** execvp(argv1[0], argv1);
检查您的返回值。execvp成功了吗,还是返回了?并打开编译器警告。我使用gcc-Wall。我能做得更多吗?令人费解的是,无论我尝试像if-ls或if-toto-toto这样的东西,execvp都不会回来。如果你包括在内,你应该得到一个关于-Wall的警告。迷惑不同于调用未指定的行为。argv[1]是第二个参数的错误类型。我的错误是,程序实际上稍微复杂一些,我希望简化它以解决这个问题,但是execvp调用是正确的。我将更新问题以反映这一点。只有在无法启动execvp时才会返回。这就是你的意思吗?如果命令失败,返回一个错误?正如我明确指出的,这是一个作业,这意味着我是一个初学者。所以我并不假装理解,但现在程序工作了-例如:我的if ToToTo echo success和我的if ls fakestring echo success不响应成功,而:我的if ls-l echo success。不,你的程序不工作。execvp仅在出现错误时返回。你根本没有给外部程序打电话。我为我的粗鲁道歉,但它确实有效。评论中的三个例子正是它们应该做的。除了我在原始帖子中忘记更正的第二部分:ifWEXITSTATUSstatus==0 execvpargv2[0],argv2;返回execvp。。。是错误的,除非您的意图是在未成功执行外部程序时未能注意到。巧合的是,在这种情况下,您返回了一个错误,但应该发出一条错误消息。你是一个公认的初学者,所以试着听听我们中那些不是的人的意见。如果提交作业时返回execvp…,则表示您不了解execvp的工作原理。它不会返回外部程序的退出状态。
execvp( argv[1], argv + 1 );
else if (t == 0)
**return** execvp(argv1[0], argv1);