0

我正在尝试实现一个支持流水线的基本 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);

我相当肯定该错误与管道或循环中子进程的分叉有关。

4

0 回答 0