如何在调用exec后让程序返回原始循环?

时间:2015-05-19 18:01:50

标签: c linux bash shell

我有一个类似于基本bash shell的程序。我可以从shell运行/bin目录中的程序。我有一个内置命令checkEnv,它使用寻呼机显示与printenv | sort | less完全相同的系统变量,但是当less完成后,程序退出。我想编程返回shell。你能告诉我怎么做吗?我创建管道的方式是

cmd[0].argv= printenv;
cmd[1].argv= sort;
cmd[2].argv= pager_cmd;
fork_pipes(3, cmd);

声明cmd

struct command
{
    char * const *argv;
};
struct command cmd[3];

我有辅助功能来分叉:

/* Helper function that forks pipes */
static void fork_pipes(int n, struct command *cmd)
{
    int i;
    int in = 0;
    int fd[2];
    int take_return;
    for (i = 0; i < n - 1; ++i)
    {
        take_return = pipe(fd);
        ++take_return; /* Please the -O4 switch to gcc */
        spawn_proc(in, fd[1], cmd + i);
        close(fd[1]);
        in = fd[0];
    }
    if (dup2(in, 0) < 0)    {
        err_syserr("dup2() failed on stdin for %s: ", cmd[i].argv[0]);
    }
    fprintf(stderr, "%d: executing %s\n", (int)getpid(), cmd[i].argv[0]);
    execvp(cmd[i].argv[0], cmd[i].argv);
    err_syserr("failed to execute %s: ", cmd[i].argv[0]);
}

/* Helper function that spawns processes */
static int spawn_proc(int in, int out, struct command *cmd)
{
    pid_t pid;
    if ((pid = fork()) == 0)
    {
        if (in != 0)
        {
            if (dup2(in, 0) < 0)
                err_syserr("dup2() failed on stdin for %s: ", cmd->argv[0]);
            close(in);
        }
        if (out != 1)
        {
            if (dup2(out, 1) < 0)
                err_syserr("dup2() failed on stdout for %s: ", cmd->argv[0]);
            close(out);
        }
        fprintf(stderr, "%d: executing %s\n", (int)getpid(), cmd->argv[0]);
        execvp(cmd->argv[0], cmd->argv);
        err_syserr("failed to execute %s: ", cmd->argv[0]);
    }
    else if (pid < 0)   {
        err_syserr("fork failed: ");
    }
    return pid;
}

我的问题是程序在使用内置命令checkEnv时退出。我希望程序返回到主循环,即我的shell的命令提示符:

 while(1) {

        printf("miniShell>> ");
        memset(line, 0, sizeof line); /*Reset*/
        if(!fgets(line, BUFFER_LEN, stdin)) {
            break;
        }

你能帮助我吗?

2 个答案:

答案 0 :(得分:1)

如果使用exec(或任何exec函数类型),exec下定义的每一行都不会被执行,因为exec就像在这个程序中执行另一个程序一样。

答案 1 :(得分:1)

我的猜测是你忘了给第三个进程打电话fork。您只使用exec表示您的主进程(miniShell)被pager_cmd替换。你应该写这样的东西:

static void fork_pipes(int n, struct command *cmd)
{
    ... //calling spawn_proc two times
    pid = fork();
    if(pid == 0) { //child process (pager_cmd)
        execvp(cmd[i].argv[0], cmd[i].argv);
        err_syserr("failed to execute %s: ", cmd[i].argv[0]);
    } else if(pid > 0) {
        //call wait() for three pids we obtained by forking
    } else {
        //error handling
    }
}