我正在尝试实现一个支持流水线的基本 linux shell。但是,我的代码似乎挂起或只是不执行程序,我不知道为什么。
if (list_empty(&job_list))
job_index = 1;
bool dopipe = false;
if (list_size(&pipeline->commands) > 1)
dopipe = true;
esh_signal_sethandler(SIGCHLD, signal_handler);
esh_signal_block(SIGCHLD);
setpgid(0, 0);
pipeline->pgrp = getpgid(0);
pipeline->jid = job_index++;
list_push_back(&job_list, &pipeline->elem);
bool background = pipeline->bg_job;
pid_t pid;
if ( (pid = fork()) == 0)
{
//Child
if (pipeline->bg_job)
setpgid(0, 0);
int oldpipe[2];
int newpipe[2];
int count = 0;
int size = list_size(&pipeline->commands);
struct list_elem * current_job;
printf("SIZE: %zu\n", list_size(&pipeline->commands));
for (current_job = list_begin(&pipeline->commands); current_job != list_tail(&pipeline->commands); current_job = list_next(current_job))
{
if (count < size)
pipe(newpipe);
pid_t fpid = fork();
printf("fpid: %d\n", (int)fpid);
if (fpid == 0)
{
//Child
printf("Executing Child\n");
if (count > 0)
{
//prev command exists
dup2(oldpipe[0], 0);
close(oldpipe[0]);
close(oldpipe[1]);
}
if (count < size - 1)
{
//next command exists
close(newpipe[0]);
dup2(newpipe[1], 1);
close(newpipe[1]);
}
esh_command* cmd = list_entry(current_job, struct esh_command, elem);
printf("Running: %s %s\n", cmd->argv[0], cmd->argv[1]);
if (execvp(cmd->argv[0], cmd->argv) < 0)
esh_sys_fatal_error("Program Does Not Exist\n");
}
else
{
//Parent
//*
int status = 0;
if (waitpid(fpid, &status, 0) < 0)
esh_sys_fatal_error("Could not fork pipe\n");
//*/
printf("Parent\n");
if (count > 0)
{
//prev command exists
close(oldpipe[0]);
close(oldpipe[1]);
}
if (count < size - 1)
{
//next command exists
oldpipe[0] = newpipe[0];
oldpipe[1] = newpipe[1];
}
printf("End of Parent\n");
}
count++;
}
if (size > 1)
{
close(oldpipe[0]);
close(oldpipe[1]);
}
printf("Finished Pipeline\n");
exit(3);
}
else
{
//*
int status = 0;
commands->pid = pid;
//Parent
if (!background)
{
pipeline->status = FOREGROUND;
if (waitpid(pid, &status, 0) < 0)
printf("waitpid ERROR\n");
list_remove(&pipeline->elem);
}
else
pipeline->status = BACKGROUND;
//*/
}
esh_signal_unblock(SIGCHLD);
我相当肯定该错误与管道或循环中子进程的分叉有关。