execvp()不让我

时间:2014-12-15 04:55:31

标签: c shell exec

我正在尝试在C中实现一个基本的shell,但每当我的shell使用execvp()执行一个命令时,它就会跳出我希望它保留的循环。我怀疑这是因为我不是熟悉execvp。

相关代码:

int main()
{
    int nCmd = 1;                   // Command number
    char *line;                     // Initial command line
    token *list;                    // Linked list of tokens
    CMD *cmd;                       // Parsed command
    int process (CMD *);

    for ( ; ; ) {

    printf ("(%d)$ ", nCmd);                // Prompt for command
    fflush (stdout);
    if ((line = getLine (stdin)) == NULL)   // Read line
        break;                              //   Break on end of file

    list = lex (line);
    // Lex line into tokens
    free (line);
    if (list == NULL) {
        continue;
    } else if (getenv ("DUMP_LIST")) {      // Dump token list only if
        dumpList (list);                    //   environment variable set
        printf ("\n");
    }

    cmd = parse (list);                     // Parsed command?
    freeList (list);
    if (cmd == NULL) {
        continue;
    } else if (getenv ("DUMP_TREE")) {      // Dump command tree only if
        dumpTree (cmd, 0);                  //   environment variable set
        printf ("\n");
    }

    process (cmd);                          // Execute command

    freeCMD (cmd);                          // Free associated storage
    nCmd++;                                 // Adjust prompt

    }

    return EXIT_SUCCESS;
}

以下是“流程”的相关部分:

int process (CMD *cmdList)
{
    if ((cmdList->nLocal)>0)
    {
        for (int i = 0; i<cmdList->nLocal; i++)
        {
            setenv(cmdList->locVar[i], cmdList->locVal[i], 0);
        }
    }
    if (cmdList->type==SIMPLE)
    {
        execvp(cmdList->argv[0],cmdList->argv);
    }
    return 0;
}

正在发生的事情是我在main的for循环中完成了第一个过程。但是,执行命令后,程序才会结束,而不是像我想的那样读取命令行。如何让它保持在for循环中?

2 个答案:

答案 0 :(得分:2)

execvp将当前流程替换为您要求其运行的流程。

您需要使用fork创建子进程并从子进程运行execvp。这样,父母将仍然活着并且能够处理更多用户输入。

答案 1 :(得分:1)

exec*形式的函数族是唯一的,因为只要程序到达它们,整个过程存储器就被擦除并用新程序的过程存储器重写。你的代码没有跳出循环,循环不再存在。

如果要模仿shell的工作方式,则必须使用另一个系统调用来创建可以覆盖的单独进程:fork。查找更多信息。