- 论坛徽章:
- 0
|
下面的程序是一个简单的shell,可以处理管道命令,比如:ls -l | cat | wc -l,这个程序是用递归算法实现管道的,感兴趣的不妨把它改成用for循环迭代连接管道中的命令。
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #define MAX_ARGC 16
- #define MAX_CMDC 16
- struct cmd_t {
- int argc;
- char *argv[MAX_ARGC];
- void exec()
- {
- execvp(argv[0], argv);
- perror("exec");
- exit(0);
- }
- };
- int cmdc;
- cmd_t *cmdv[MAX_CMDC];
- void split_cmd(char *line)
- {
- cmd_t * cmd = new cmd_t();
- cmdv[cmdc++] = cmd;
- cmd->argc = 0;
- char *save;
- char *arg = strtok_r(line, " \t", &save);
- while (arg) {
- cmd->argv[cmd->argc++] = arg;
- arg = strtok_r(NULL, " \t", &save);
- }
- cmd->argv[cmd->argc] = NULL;
- }
- void split_pipe(char *line)
- {
- char *save;
- char * cmd = strtok_r(line, "|", &save);
- while (cmd) {
- split_cmd(cmd);
- cmd = strtok_r(NULL, "|", &save);
- }
- }
- void do_pipe(int index)
- {
- if (index == cmdc - 1)
- cmdv[index]->exec();
- int fd[2];
- pipe(fd);
- if (fork() == 0) {
- dup2(fd[1], 1);
- close(fd[0]);
- close(fd[1]);
- cmdv[index]->exec();
- }
- dup2(fd[0], 0);
- close(fd[0]);
- close(fd[1]);
- do_pipe(index + 1);
- }
- void prompt()
- {
- char line[80];
- printf("%% ");
- gets(line);
- split_pipe(line);
- do_pipe(0);
- }
- int main()
- {
- for (;;) {
- int pid = fork();
- if (pid == 0) {
- prompt();
- exit(0);
- }
- waitpid(pid, NULL, 0);
- }
- return 0;
- }
复制代码 |
|