在循环结束时我做错了什么?

时间:2014-02-22 23:27:16

标签: c loops flags do-while

我正在使用“int flag = [0或1]”来确定我的循环是否应该返回到do {}。 继承我的代码

void shell() 
{
    int flag = 1;
    do
    {
        // Retrieve PID of the parent process. 
        pid_t shell_pid = getpid();

        // Print shell prompt. 
        printf("{%i}$ ", shell_pid);

        // Retrieve input from stdin.
        char* input = NULL;
        size_t input_size = 0;
        getline(&input, &input_size, stdin);
        char delim = ' ';
        char **argvp;
        int argc = makeargv(input, &delim, &argvp);

        // Remove \n from last arg
        char* lastarg = argvp[argc - 1];
        while(*lastarg && *lastarg != '\n')
            lastarg++;
        *lastarg = '\0';

        // Create a child process to handle user input. 
        pid_t pid = fork();

        // Parent process.  
        if (pid != 0) 
        {
            wait(NULL);
        } 
        else // Child process
        {
            int i;
            // Handle user input here!

            //got some debugging tools here
            printf("========DEBUG==========\n");
            printf("There are %i args\n", argc);
            for(i = 0; i < argc; i++)
            {
                printf("arg %i: \"%s\"\n", i, *(argvp + i));
            }
            printf("=====END DEBUG==========\n\n");
            printf("********OUTPUT*********\n");
            //handle "echo" here
            if((i = strcmp(argvp[0],"echo")) == 0)
            {
                echo(argc, argvp);
            }

            //handle "exit" or "quit" here
            if((i = strcmp(argvp[0],"exit")) == 0 || (i = strcmp(argvp[0],"quit")) == 0)
            {
                printf("got in the exit\n");
                flag = 0;
            }

        }
        printf("****END OUTPUT*********\n");
        // Free memory allocated by getline(). 
        free(input);
    }while(flag == 1);    
}

我的输入/输出如下所示:[输入前面是$]

$ ./shelltest
{13158}$ try first string
========DEBUG==========
There are 3 args
arg 0: "try"
arg 1: "first"
arg 2: "string"
=====END DEBUG==========

********OUTPUT*********
****END OUTPUT*********
{13159}$ echo try another
========DEBUG==========
There are 3 args
arg 0: "echo"
arg 1: "try"
arg 2: "another"
=====END DEBUG==========

********OUTPUT*********
try another 
****END OUTPUT*********
{13160}$ quit 
========DEBUG==========
There are 1 args
arg 0: "quit"
=====END DEBUG==========

********OUTPUT*********
got in the exit
****END OUTPUT*********
****END OUTPUT*********
{13160}$

由于输出中显示“get in the exit”,因此flag立即设置为0。 循环如何继续?

3 个答案:

答案 0 :(得分:4)

您正在使用fork(),父进程正在等待子进程退出,该行:

printf("****END OUTPUT*********\n");

由父进程和子进程执行,因此您看到它两次。

答案 1 :(得分:1)

您的进程正在退出循环,但您的父级继续运行。

shell的正常范例是父级读取和评估输入,只有在需要子进程时才进行分叉。

使用该方法,父级将检测exit并完成而不创建子级。

答案 2 :(得分:1)

打印时

  

{13160} $ quit

实际上,13160是由fork创建的进程的父进程的pid来处理quit命令(要查看此操作,请在fork之后打印子进程的pid)。这个将通过将标志设置为0来解析退出并退出。然后,您将看到****END OUTPUT*********两次。

你必须记住,当你分叉时,内存不与父共享(在Linux中它是,但它是写入时的副本。这是我上次读它时)所以当孩子写flag = 0时,父将没有看到这个值,所以它会再次循环。因此,为什么它再次要求输入。

您处理关系的另一件事看起来像{13158}->{13159}->{13160}->...由于根进程是13158,我认为您想要做的是在每次输入后从root生成一个子进程。所以你可能想检查一下。