程序因调用execvp编译错误程序而崩溃?
Program crashed for calling execvp to compile a program with error?
我用execvp编译程序出错。但是随后错误消息在我的终端屏幕上弹出,这不应该发生,因为如果 execvp 失败,它只会让子 return 具有退出状态。我不明白为什么我的终端会显示错误信息?
我的命令数组:{gcc, studentcode.c, ourtest3.c, -o, ourtest3.x, NULL} 在 ourtest3.c 中,我故意犯了几个错误。我的调用函数是这样的:
commands = {"gcc", "studentcode.c", "ourtest3.c", "-o", "ourtest3.x", NULL};
int compile_program(Char** commands) {
pid_t pid;
int status;
pid = safe_fork();
if (pid == 0) { /*Child*/
if (execvp(commands[0], commands) < 0) {
exit(0);
}
} else { /*Parent*/
if (wait(&status) == -1) {
return 0;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
return 1;
}
} else {
return 0;
}
}
return 1;
}
ourtest3.c是这样的:
#include <stdio.h>
#include <assert.h>
#include "studentcode.h"
int main(void) {
assert(product(2, 16) == 32
printf("The student code in public07.studentcode.c works on its ");
printf("third test!\n");
return 0;
}
我的程序本应以 return 值 0 正常结束,但在我的终端 window 上却显示
ourtest3.c: In function 'main':
ourtest3.c:19:0: error: unterminated argument list invoking macro "assert"
ourtest3.c:13:3: error: 'assert' undeclared (first use in this function)
ourtest3.c:13:3: note: each undeclared identifier is reported only once for each function it appears in
ourtest3.c:13:3: error: expected ';' at end of input
ourtest3.c:13:3: error: expected declaration or statement at end of input
如果您想更改进程的标准输入、标准输入和标准错误,您需要这样做。否则,它只是从其 parent 继承它们。在 fork
之后和 execvp
之前,您可能想要 open
/dev/null
和 dup
到文件描述符 0 和 1.
这是一些没有错误检查的难看代码:
if (pid == 0) { /*Child*/
/* Redirect stdin and stderr to /dev/null */
int fd = open ("/dev/null", O_RDONLY);
dup2(STDIN_FILENO, fd);
dup2(STDERR_FILENO, fd);
close(fd);
if (execvp(commands[0], commands) < 0) {
_exit(0);
}
如果您希望 parent 能够访问 child 的输出,您也可以将它们重定向到文件或管道。
注意对 _exit
的调用。不要养成在失败 children 时调用 exit
的习惯。这在过去导致了具有严重安全隐患的错误。想象一下,如果您的进程在 exit
s 时要执行某些操作(例如将缓冲区刷新到终端或网络连接)。通过在 child 中调用 exit
,您会执行 两次 。你可能认为你知道你没有这样的东西,但你不可能知道(通常)因为你不知道你的图书馆可能在内部做什么。
我用execvp编译程序出错。但是随后错误消息在我的终端屏幕上弹出,这不应该发生,因为如果 execvp 失败,它只会让子 return 具有退出状态。我不明白为什么我的终端会显示错误信息?
我的命令数组:{gcc, studentcode.c, ourtest3.c, -o, ourtest3.x, NULL} 在 ourtest3.c 中,我故意犯了几个错误。我的调用函数是这样的:
commands = {"gcc", "studentcode.c", "ourtest3.c", "-o", "ourtest3.x", NULL};
int compile_program(Char** commands) {
pid_t pid;
int status;
pid = safe_fork();
if (pid == 0) { /*Child*/
if (execvp(commands[0], commands) < 0) {
exit(0);
}
} else { /*Parent*/
if (wait(&status) == -1) {
return 0;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
return 1;
}
} else {
return 0;
}
}
return 1;
}
ourtest3.c是这样的:
#include <stdio.h>
#include <assert.h>
#include "studentcode.h"
int main(void) {
assert(product(2, 16) == 32
printf("The student code in public07.studentcode.c works on its ");
printf("third test!\n");
return 0;
}
我的程序本应以 return 值 0 正常结束,但在我的终端 window 上却显示
ourtest3.c: In function 'main':
ourtest3.c:19:0: error: unterminated argument list invoking macro "assert"
ourtest3.c:13:3: error: 'assert' undeclared (first use in this function)
ourtest3.c:13:3: note: each undeclared identifier is reported only once for each function it appears in
ourtest3.c:13:3: error: expected ';' at end of input
ourtest3.c:13:3: error: expected declaration or statement at end of input
如果您想更改进程的标准输入、标准输入和标准错误,您需要这样做。否则,它只是从其 parent 继承它们。在 fork
之后和 execvp
之前,您可能想要 open
/dev/null
和 dup
到文件描述符 0 和 1.
这是一些没有错误检查的难看代码:
if (pid == 0) { /*Child*/
/* Redirect stdin and stderr to /dev/null */
int fd = open ("/dev/null", O_RDONLY);
dup2(STDIN_FILENO, fd);
dup2(STDERR_FILENO, fd);
close(fd);
if (execvp(commands[0], commands) < 0) {
_exit(0);
}
如果您希望 parent 能够访问 child 的输出,您也可以将它们重定向到文件或管道。
注意对 _exit
的调用。不要养成在失败 children 时调用 exit
的习惯。这在过去导致了具有严重安全隐患的错误。想象一下,如果您的进程在 exit
s 时要执行某些操作(例如将缓冲区刷新到终端或网络连接)。通过在 child 中调用 exit
,您会执行 两次 。你可能认为你知道你没有这样的东西,但你不可能知道(通常)因为你不知道你的图书馆可能在内部做什么。