简体   繁体   English

用于Shell的C程序:Execvp打印输出,然后在执行后台进程时发生分段错误

[英]C Program for shell: Execvp prints output and then segmentation fault occurs when executing a background process

I am writing a simple C program to create my own shell. 我正在编写一个简单的C程序来创建自己的shell。 It takes in input as commands and executes them. 它接受输入作为命令并执行它们。 But when I try to execute a process in background( ie I fork a process from parent. The parent won't wait for the child process to finish, it just goes on to take more input commands while the child process runs in the background.) The execvp does execute the command but then gives a segmentation fault immediately. 但是,当我尝试在后台执行进程时(即,我从父进程派生了一个进程。父进程不会等待子进程完成,它会继续执行更多输入命令,而子进程则在后台运行。 )execvp确实执行了命令,但是立即给出了分段错误。 Can you help me? 你能帮助我吗? I'll post my part of the code which I think is relevant. 我将发布我认为相关的部分代码。 Let me know if you need to know anything more, i'll edit my question accordingly. 让我知道是否需要更多信息,我将相应地编辑我的问题。

while(1){

pid = fork();
        if(pid == 0)
            executeCommand(info);
        else
            {
                if(info->boolBackground ==1)
                    {
                        waitpid(pid , status , WNOHANG);
                    }
                else
                    wait(NULL);                     
            }

} //Info contains the command to be executed and it's arguments.

Here is me executeCommand function: 这是我的executeCommand函数:

void executeCommand(parseInfo * info)
{
    FILE *infile, *outfile;
    struct commandType * com;
    char * cmd;
    int i , status;
    cmd = (char*)malloc(1024);
    strcpy(cmd , info->CommArray[0].command);
    if(info->boolOutfile == 1)
        {
            outfile = fopen(info->outFile, "w");
            dup2(fileno(outfile), 1);
        }
    if(info->boolInfile == 1)
        {
            infile = fopen(info->inFile, "r");
            dup2(fileno(infile), 0);
        }
    status = execvp(cmd , info->CommArray[0].VarList); //VarList contains the arguments
    if(status == -1){
        printf("%s\n",strerror(errno));}

    exit(0);
}

When I give an input command: ls & (& means that ls should be executed in background.) It forks a child process which executes ls and prints the list of files/directories in the directory and then gives segmentation fault. 当我给出输入命令时:ls&(&表示ls应该在后台执行。)它派生一个子进程,该子进程执行ls并打印目录中的文件/目录列表,然后给出分段错误。 Can you spot the error? 您能发现错误吗? I tried running execvp in background with simply ls command. 我尝试使用ls命令在后台运行execvp。 It also lead to a segmentation fault. 这也会导致分段错误。

Yes, as Mark Plotnick pointed out in a comment, you'll need probably need &status. 是的,正如Mark Plotnick在评论中指出的那样,您可能需要&status。 I'd use &info->status. 我会使用&info-> status。 Also, if you do detached jobs, you need to maintain a list of their info objects and do a waitpid loop on them: 另外,如果您执行分离的作业,则需要维护其信息对象的列表,并对它们执行waitpid循环:

forall (info in detached_detach_job_list) {
    pid = waitpid(info->pid,&info->status,WNOHANG);
    if (pid > 0) {
        report_status(info);
        remove_job_from_list(info);
    }
}

Hopefully, the code frag you gave for your outer loop does something like this. 希望您为外部循环提供的代码片段可以执行以下操作。

Also, I might not do "wait(NULL)" for a foreground. 另外,我可能不会对前台执行“ wait(NULL)”。 I'd treat it similarly to a detached job. 我会像对待独立工作一样对待它。 Consider a case where a user does: 考虑用户这样做的情况:

det1 &
det2 &
...
det9000 &
run_long_30_minute_job

Because your shell is doing a hard wait on the foreground, it can't reap the detached jobs as they finish and you'll end up with zombie processes. 由于您的外壳程序在前台进行了艰苦的等待,因此无法完成分离的作业,因为它们完成后,您将面临僵尸进程。 Do the list/loop approach, just don't give user a prompt until the foreground completes (eg it's in the list, it's just the one with the background flag cleared). 使用列表/循环方法,只是在前景完成之前不给用户提示(例如,它在列表中,只是清除了背景标志的那个)。 In other words, call the list something like child_list to denote all child processes, not just background. 换句话说,将列表称为child_list之类的名称来表示所有子进程,而不仅仅是背景。 Put a sleep in the outer loop. 在外循环中入睡。 Or, attach to SIGCHLD and do a single long sleep 或者,附加到SIGCHLD并进行一次长时间睡眠

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM