支持输入输出重定向,管道等功能的shell

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>
int flag;
int mark;
void do_parse(char *buf,char* argv[]) {
      if(buf==NULL)
      {
              return;
                  
      }
          if(argv==NULL)
          {
                    return;
                        
          }
              int i;
              int argc=0;
              int status=0;
           for(i=0;buf[i];i++)
            {
             if(!isspace(buf[i]) &&status==0 )
               {
               argv[argc++]=buf+i;
                 status=1;                                         
                }else if( isspace(buf[i]))
                 {
                      status=0;
                      buf[i]='\0';                                     
                 }
                                       
            }
           argv[argc]=NULL;
                            
}

int has_pipe(char* argv[])
{
     int i=1;
       //Start form 1 because before '|' should have command.
              while(argv[i]!=NULL)
                    {
                          
                      if(strcmp(argv[i],"|")==0)
                        {
                         argv[i]=NULL;
                          return i+1;
                          
                        }
                       if(strcmp(argv[i],">") == 0)
                       {
                         argv[i] = NULL;
                        flag =1;
                        return i+1;
                       }
                       if(strcmp(argv[i],"<") == 0)
                       {
                         argv[i] = NULL;
                         mark = 1;
                        
                         return i+1;
                       }
                          i++;           
                        return 0;
                    }     
}
int main()
{
char* argv[16];
  char buf[1024]={0};
   char* tmp1[8];
char* tmp2[8];
int fd[2];
int ret;
int fd1;
do

  flag = 0;
  mark = 0;
  printf("[myshell~]");
  fflush(stdout);
 // read(1,buf,1024);  
  scanf("%[^\n]%*c",buf);
  do_parse(buf,argv);                                                              
  ret=has_pipe(argv);
  // 管道实现
  // 要想实现管道,必须调用两个exec函数,所以要有子进程和孙子进程
  // 把命令分出来,让子进程调用pipe函数
  if(ret && !flag && !mark)
  {   
    int i=0;
    int j=ret;
    while(argv[i]!=NULL)
    {
      tmp1[i]=argv[i];
      i++;                                              
    }
    tmp1[i]=NULL;
    i=0;       
    while(argv[j]!=NULL)
    {
      tmp2[i++]=argv[j++];                                                                           
    }       
    tmp2[i]=NULL;
    pid_t pid_p=fork(); 
    if(pid_p==-1)
    {
      perror("pid_p");
      exit(EXIT_FAILURE);

    }
    else if(pid_p==0)
    {
      if(pipe(fd)==-1)
      {        
        perror("pipe");
        exit(EXIT_FAILURE);
      }
      pid_t pid_s=fork();        
      if(pid_s==-1)
      {
        perror("pid_s");
        exit(EXIT_FAILURE);

      }
      else if(pid_s==0)
      {
        close(fd[0]);         
        dup2(fd[1],1);   
        execvp(tmp1[0],tmp1); 
      }
      else                        
      { 
        close(fd[1]);       
        dup2(fd[0],0);               
        execvp(tmp2[0],tmp2);                    
        
      }
    }
      else{        
      
        wait(NULL);           
        
      }
      
      
    }
          else {  
            pid_t pid=fork();
            if(pid==-1)
          
            {
              perror("pid");
              exit(EXIT_FAILURE);

            }
            else if(pid==0)
            {
              //输出重定向
                   if(flag)
                   {
                     fd1 = open(argv[ret],O_WRONLY|O_CREAT,0664);
                       close(1); 
                     dup2(fd1,1);
                   }
               //输入重定向   
                    if(mark)
                   {
                    // close(0);
                     fd1 =open(argv[ret],O_RDWR|O_CREAT,0644);
                     //close(0);
                     dup2(fd1,0);
                   }
            int a =  execvp(argv[0],argv);
            if(a == -1)
            {
              perror("ececvp");
            }
              if(flag||mark)
              {
                 close(fd1);
              }
              

            }else{
              wait(NULL);                                               
            }            
          }
          memset(buf,0,1024);
}while(buf[0] != 'q');
}
 

猜你喜欢

转载自blog.csdn.net/congjichukaishi/article/details/83187468
今日推荐