c - 即使子进程已死,waitpid 也会挂起
问题描述
我有以下功能:
int run_func(command history[MAX_INPUT_SIZE], char** args, int capacity) {
int need_to_wait = 1;
int i = 0;
char* arg = args[0];
int status;
while (arg != NULL) {
if (strcmp(arg, "&") == 0) {
need_to_wait = 0;
break;
}
arg = args[i++];
}
pid_t wait_pid;
pid_t pid = fork();
int res;
if (pid == 0) {
res = execvp(args[0], args);
if (res == -1) {
printf("exec failed\n");
fflush(stdout);
return 0;
}
} else if (pid < 0) {
printf("fork failed\n");
fflush(stdout);
return 0;
} else {
if (need_to_wait){
do {
wait_pid = waitpid(pid, &status, 0);
} while(!WIFEXITED(status) && !WIFSIGNALED(status));
}
history[capacity - 1].pid = pid;
}
return 1;
}
我遇到的问题是,当我从终端收到来自用户的无效命令(例如“hello”)时,底部的 while 循环会挂起并且不会停止,直到我再次按 Enter 键。这个函数是从另一个接收用户输入的函数调用的。
解决方案
将评论复制到答案中。
附带问题:
- 错误消息应该打印到
stderr
,而不是stdout
。 - 无需保存或测试返回值
execvp()
——如果返回,则失败;如果成功,则不会返回。
主要观察:
- 您几乎肯定应该在错误处理代码中使用
exit()
or_exit()
而不是. 当命令失败(?)时,您最终会运行两个进程 - 一个来自失败的进程,一个是父进程。这很容易混淆一切,因为您有两个进程试图同时读取终端。return 0;
execvp()
hello
execvp()
推荐阅读
- python - Optional NoReturn: TypeHint for a function which sometimes raises an exception
- python - 带有udf pyspark的fasttext
- java - 如何用 Java 编写一个程序来查找“00”来检查字符串中的每个字符?
- javascript - 禁用右键单击时如何删除弹出消息?
- python - 如何计算图像数据集中 RGB 值的 3x3 协方差矩阵?
- angular - 量角器:无法在测试中创建新的浏览器实例
- c# - C# + unity中的元胞自动机邻居检查问题
- html - 我对移动设备中的导航栏有疑问
- python-3.x - 如何参数化限制?
- vue.js - VueJS:从复选框中列出选定对象的状态中的项目防止复选框被取消选中