【断更一段时间】实现了I/O重定向的shell

实现了I/O重定向的shell

0x00 代码

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include "rio.h"
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
void handler(){
    int status;
    while(waitpid(-1,&status,0)>0){//回收所有终止子进程

    }
    return;
}
int try_to_exec(char*buf){
    char temp;
    int line_len=strlen(buf);
    int p=0;
    int cnt=0;
    int flag=0;//0代表之前的字符是 空格 1代表非空格
    for(p=0;p<=line_len;p++){
        temp=*(buf+p);
        if(temp=='\0'||temp==' '){
            if(flag==0){

            }else{
                cnt++;
                flag=0;
            }
        }else{
            if(flag==0){
                flag=1;
            }else{

            }
        }
    }//知道有多少个子段 
    int argc=cnt;
    char**argv=(char**)malloc(sizeof(char*)*(cnt+1));//cnt+1 最后一个为null
    cnt=0;
    int start=0;
    int child_len=0;
    for(p=0;p<=line_len;p++){
        temp=*(buf+p);
        if(temp=='\n'){
            if(flag==0){

            }else{
                char* temp1=(char*)malloc(sizeof(char)*(child_len+1));//child_len+1,结尾有'\0'
                memcpy(temp1,buf+start,child_len);
                temp1[child_len]='\0';
                argv[cnt]=temp1;
                cnt++;
                flag=0;
            }
            break;
        }
        if(temp=='\0'||temp==' '){
            if(flag==0){

            }else{
                char* temp1=(char*)malloc(sizeof(char)*(child_len+1));//child_len+1,结尾有'\0'
                memcpy(temp1,buf+start,child_len);
                temp1[child_len]='\0';
                argv[cnt]=temp1;
                cnt++;
                flag=0;
            }
        }else{
            if(flag==0){
                child_len=1;
                start=p;
                flag=1;
            }else{
                child_len++;
            }
        }
    }
    argv[argc]=NULL;//标识结尾
    pid_t p1=fork();
    int status;
    if(p1==0){//子进程
        
        int i;
        int fd;
        for(i=0;i<argc-1;i++){
            if(strcmp(argv[i],">")==0){
                fd=open(argv[i+1],O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
                if(fd<0){
                    printf("no such file!\n");
                    exit(1);
                }
                dup2(fd,STDOUT_FILENO);//重定向输出 将描述符表里fd文件条目对应的
                //内容复制到STDOUT条目里,实现了I/O
            }
        }
        if(strcmp(argv[argc-1],"&")==0){//关闭终端显示
            close(STDOUT_FILENO);
        }
        if(execve(argv[0],argv,__environ)<0){
            printf("executable file does not exits!\n");
            exit(1);
        }
    }
    if(strcmp(argv[argc-1],"&")==0){//后台运行

    }else{
        waitpid(-1,&status,0);
    }
    return argc;
}
int main(){
    signal(SIGCHLD,handler);
    rio_t std_int_rio;
    rio_init(STDIN_FILENO,&std_int_rio);
    char buf[MAX_RIO_BUF_SIZE];
    while(1){
        rio_readLineb(&std_int_rio,buf,MAX_RIO_BUF_SIZE);
        int a=try_to_exec(buf);
       
    }
}