I have a program that is similar to a basic bash shell. I can run programs in the /bin
directory from the shell. I have a builtin command checkEnv that uses a pager to display system variables exactly like printenv | sort | less
but when less
has completed, the program exits. I want to program to return to the shell. Can you tell my how I can do it? The way I create the pipeline is
我有一个类似于基本bash shell的程序。我可以从shell运行/ bin目录中的程序。我有一个内置命令checkEnv,它使用寻呼机来显示与printenv |完全相同的系统变量排序|较少但是当完成较少时,程序退出。我想编程返回shell。你能告诉我怎么做吗?我创建管道的方式是
cmd[0].argv= printenv;
cmd[1].argv= sort;
cmd[2].argv= pager_cmd;
fork_pipes(3, cmd);
where cmd
is declared:
声明cmd的位置:
struct command
{
char * const *argv;
};
struct command cmd[3];
I have helper functions to fork:
我有辅助函数来fork:
/* 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;
}
My problem is that the program exits when using the builtin command checkEnv
. I want the program to return to the main loop that is the command prompt for my shell:
我的问题是程序在使用内置命令checkEnv时退出。我希望程序返回主循环,这是我的shell的命令提示符:
while(1) {
printf("miniShell>> ");
memset(line, 0, sizeof line); /*Reset*/
if(!fgets(line, BUFFER_LEN, stdin)) {
break;
}
Can you help me?
你可以帮我吗?
2 个解决方案
#1
1
My guess is that you forgot to call fork
for the third process. You use just exec
for it which means your main process (the miniShell) is substituted by pager_cmd. You should write something like that:
我的猜测是你忘了为第三个进程调用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
}
}
#2
1
If you use exec (or any exec function type) every line defined under exec will not be executed because exec is like executing another program inside this program.
如果使用exec(或任何exec函数类型),exec下定义的每一行都不会被执行,因为exec就像执行该程序中的另一个程序一样。
#1
1
My guess is that you forgot to call fork
for the third process. You use just exec
for it which means your main process (the miniShell) is substituted by pager_cmd. You should write something like that:
我的猜测是你忘了为第三个进程调用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
}
}
#2
1
If you use exec (or any exec function type) every line defined under exec will not be executed because exec is like executing another program inside this program.
如果使用exec(或任何exec函数类型),exec下定义的每一行都不会被执行,因为exec就像执行该程序中的另一个程序一样。