c - 在while循环中使用execvp和fork时的无限循环
问题描述
我正在尝试编写一个小型 shell 程序,我希望它在调用另一个程序(通过execvp()
)后保持活动状态。我希望fork
系统调用“复制”进程,创建发行(父)进程的几乎相同的副本(子)。因此,当父母因excevp()
通话而终止时,孩子们仍然活着。
在我附在下面的代码中,我读取了一个用户输入(程序和要执行的参数),然后我希望父 fork 将执行程序,而子 fork 将等待用户的下一个输入,但在第一次之后我插入输入(要执行的程序及其参数),程序陷入无限循环。当子叉子获得控制权时,它会执行前一个程序并且不等待新的输入(似乎在第一次之后fgets()
它不再等待用户输入)。
这是代码的有问题的部分:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "LineParser.h"
#include <limits.h>
#include <unistd.h>
char buf[PATH_MAX];
char buf_user[2048];
int pid;
void execute(cmdLine* pCmdLine) {
int pid = fork();
if(pid != 0) {
printf("I'm the parent.\n");
if(execvp(pCmdLine->arguments[0], pCmdLine->arguments) == -1) {
perror("execute failed");
_exit(1);
}
} else {
freeCmdLines(pCmdLine);
}
}
int main(int argc, char *argv[])
{
while(1) {
getcwd(buf, PATH_MAX);
printf("%s> ", buf);
fgets(buf_user, 2048, stdin);
fflush(stdin);
if(strcmp(buf_user, "quit\n") == 0) {
exit(0);
}
cmdLine* parsedCmd = parseCmdLines(buf_user);
execute(parsedCmd);
}
return 0;
}
cmdLine
结构体:
#define MAX_ARGUMENTS 256
typedef struct cmdLine
{
char *const arguments[MAX_ARGUMENTS]; /* command line arguments (arg 0 is the command) */
int argCount; /* number of arguments */
char const *inputRedirect; /* input redirection path. NULL if no input redirection */
char const *outputRedirect; /* output redirection path. NULL if no output redirection */
char blocking; /* boolean indicating blocking/non-blocking */
int idx; /* index of current command in the chain of cmdLines (0 for the first) */
struct cmdLine *next; /* next cmdLine in chain */
} cmdLine;
/* Parses a given string to arguments and other indicators */
/* Returns NULL when there's nothing to parse */
/* When successful, returns a pointer to cmdLine (in case of a pipe, this will be the head of a linked list) */
cmdLine *parseCmdLines(const char *strLine); /* Parse string line */
/* Releases all allocated memory for the chain (linked list) */
void freeCmdLines(cmdLine *pCmdLine); /* Free parsed line */
/* Replaces arguments[num] with newString */
/* Returns 0 if num is out-of-range, otherwise - returns 1 */
int replaceCmdArg(cmdLine *pCmdLine, int num, const char *newString);
解决方案
您不应该在父级中执行 vp,而应在子级中执行。
您的终端等待父母完成。完成父进程而不等待它的子进程结束会导致僵尸进程。
修改您的代码以便在子进程中执行命令并等待它在父进程中完成,当我测试它时解决了您的问题。
我建议你阅读man 3 等等 !
推荐阅读
- eclipse - 片段包未激活
- c# - 数据库备份不成功
- php - SQL Query 在没有 WHERE 的情况下工作,但是一旦我添加 WHERE 语句,它就无法正常运行
- c - 使用 const 复合文字的元素初始化静态变量
- vue-storefront - 向 vue-storefront 提交新模块有什么要求?
- sql-server - 有没有办法知道dts花了多长时间?
- spring-cloud-config - Spring Cloud Server 为同一个应用程序提供多个属性文件
- amazon-web-services - 如何在 AWS Route53 服务中使用 terraform 创建多值 SRV DNS 记录?
- java - 在另一个类的访问器中从不同的类调用方法(作业)
- linux - 执行脚本时出现“不明确的重定向”错误