我正在用C创建一个简单的Linux命令外壳。我无法理解我的代码在哪里出现问题。 “命令”是我想作为一个父级的子级进程并发执行的Linux命令字符串的列表。当所有执行完成后,我希望父项退出该函数。但是,当我调用exit(0)时,for循环将继续并再次解析当前命令,从而导致args在execvp中再次执行。我在这里正确使用fork()和wait()吗?我也尝试过使用waitpid(),但是没有运气。
void executeShell(char** commands){
char **arr = commands;
char *c;
pid_t pid, wpid;
int status = 0;
for (c = *arr; c; c=*++arr){
// printf("%d-\n", strcmp(command, "exit"));
if (strcmp(c, "exit") == 0){
EXIT = 1;
return;
}
printf("Running command \'%s\'...\n", c);
char** args = parseStringToTokenArray(c, " ");
free(args);
/* fork and execute the command */
pid = fork();
if(pid < 0){
perror("fork() error\n");
return;
}
/* child process executes command */
else if (pid == 0){
/* 'cd' is not a part of /bin library so handle it manually */
if (strcmp(args[0], "cd") == 0){
changeDirectory(args[1]);
}
else if (strcmp(args[0], "sdir") == 0){
searchDirectory(args[1]);
}else{
/* parse commands with arguments */
execvp(args[0], args);//execute the command
}
exit(0);// <-----command is finished, so why no exit?
}
}
/* wait for children to complete */
while((wpid = wait(&status)) > 0);
}
答案 0 :(得分:1)
如果execvp成功,则整个子进程地址空间将由execvp()
调用的程序替换。这意味着exit(0)
仅在以下两种特殊情况下调用,即cd
和sdir
。就您的代码而言,execvp()
永远不会返回,除非出现错误。
另一个问题是,您在分配args
后立即释放了它,然后继续在子进程中使用它。这是不确定的行为。
我在您的wait
代码中看到的唯一问题是,如果任何子级阻止等待用户输入,则父级将阻止等待退出。
cd
代码对除其执行子级之外的任何进程均无效。父级的当前目录不受影响。如您在评论中所述,可以通过在父级中处理cd
而不分叉来解决此问题。