Chinaunix首页 | 论坛 | 博客
  • 博客访问: 201792
  • 博文数量: 63
  • 博客积分: 2764
  • 博客等级: 少校
  • 技术积分: 620
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-28 21:11
文章分类

全部博文(63)

文章存档

2011年(35)

2010年(28)

我的朋友

分类: LINUX

2010-08-09 23:27:29

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

#define MAXLINE 4096
#define MAXPIPE 16
#define MAXARG 8

struct {
    char *argv[MAXARG];
    char *in, *out;
} cmd[MAXPIPE+1];

int parse(char *buf, int cmdnum)
{
     int n = 0;
     char *p = buf;

     cmd[cmdnum].in = cmd[cmdnum].out = NULL;
     while (*p != '\0')
     {
          if (*p == ' ')
          {
               *p++ = '\0';
               continue;
          }
          if (*p == '<')
          {
               *p = '\0';
               while (*(++p) == ' ');
               cmd[cmdnum].in = p;
               if (*p++ == '\0')
                    return -1;
               continue;
          }
          if (*p == '>')
          {
               *p = '\0';
               while (*(++p) == ' ');
               cmd[cmdnum].out = p;
               if (*p++ == '\0')
                    return -1;
               continue;
          }
          if (*p != ' ' && ((p == buf) || *(p-1) == '\0'))
          {
               if (n < MAXARG - 1) {
                    cmd[cmdnum].argv[n++] = p++;
                    continue;
               } else
                    return -1;
          }
          p++;
     }
     if (n == 0)
          return -1;
     cmd[cmdnum].argv[n] = NULL;
     return 0;
}

int main()
{
    char buf[MAXLINE];
    pid_t pid;
    int fd, i, j, pfd[MAXPIPE][2], pipe_num, cmd_num;
    char* curcmd, *nextcmd;

    while (1) {
        printf("mysh%% ");
        if (!fgets(buf, MAXLINE, stdin))
            exit(0);
        if (buf[strlen(buf)-1]=='\n')
            buf[strlen(buf)-1]='\0';
        cmd_num = 0;
        nextcmd = buf;
        while ((curcmd = strsep(&nextcmd, "|"))) {
            if (parse(curcmd, cmd_num++)<0) {
                cmd_num--;
                break;
            }
            if (cmd_num == MAXPIPE + 1)
                break;
        }
        if (!cmd_num)
            continue;
                pipe_num = cmd_num - 1;

        for (i=0; i<pipe_num; i++)
            if (pipe(pfd[i])) {
                perror("pipe");
                exit(1);
            }
        printf("cmd_num=%d\n", cmd_num);
        for (i=0; i<cmd_num; i++)
        if ((pid=fork())==0)
            break;

        if (pid==0) {
            if (pipe_num)
            {
                if (i==0) {
                    dup2(pfd[0][1], STDOUT_FILENO);
                    close(pfd[0][0]);
                    for (j=1; j<pipe_num; j++) {
                        close(pfd[j][0]);
                        close(pfd[j][1]);
                    }
                } else if (i==pipe_num) {
                    dup2(pfd[i-1][0], STDIN_FILENO);
                    close(pfd[i-1][1]);
                    for (j=0; j<pipe_num-1; j++) {
                        close(pfd[j][0]);
                        close(pfd[j][1]);
                    }
                } else {
                    dup2(pfd[i-1][0], STDIN_FILENO);
                    close(pfd[i-1][1]);
                    dup2(pfd[i][1], STDOUT_FILENO);
                    close(pfd[i][0]);
                    for (j=0; j<pipe_num; j++)
                        if (j!=i || j!=i-1) {
                            close(pfd[j][0]);
                            close(pfd[j][1]);
                        }
                }
            }
            printf("in=%s\n",cmd[i].in);
            if (cmd[i].in) {
                fd = open(cmd[i].in, O_RDONLY);
                if (fd != -1)
                    dup2(fd, STDIN_FILENO);
            }
            printf("out=%s\n",cmd[i].out);
            if (cmd[i].out) {
                fd = open(cmd[i].out, O_WRONLY|O_CREAT|O_TRUNC, 0644);
                if (fd != -1)
                    dup2(fd, STDOUT_FILENO);
            }
            execvp(cmd[i].argv[0], cmd[i].argv);
            fprintf(stderr, "executing %s error.\n", cmd[i].argv[0]);
            exit(127);
        }

        /* parent */
        for (i=0; i<pipe_num; i++) {
            close(pfd[i][0]);
            close(pfd[i][1]);
        }
        for (i=0; i<cmd_num; i++)
            wait(NULL);
    }
}


阅读(833) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~