⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 execute.c

📁 linux下的简单的shell解释器
💻 C
📖 第 1 页 / 共 2 页
字号:
    history.end = -1;    history.start = 0;        len = 0;
	//将路径文件内容依次读入到buf[]中    while(read(fd, &c, 1) != 0){         buf[len++] = c;    }    buf[len] = '\0';
    //将环境路径存入envPath[]    getEnvPath(len, buf);         //注册信号    struct sigaction action;    action.sa_sigaction = rmJob;    sigfillset(&action.sa_mask);    action.sa_flags = SA_SIGINFO;    sigaction(SIGCHLD, &action, NULL);    signal(SIGTSTP, ctrl_Z);}
/*******************************************************
                      命令解析
********************************************************/SimpleCmd* handleSimpleCmdStr(int begin, int end){    int i, j, k;    int fileFinished; //记录命令是否解析完毕    char c, buff[10][40], inputFile[30], outputFile[30], *temp = NULL;    SimpleCmd *cmd = (SimpleCmd*)malloc(sizeof(SimpleCmd));    
	//默认为非后台命令,输入输出重定向为null    cmd->isBack = 0;    cmd->input = cmd->output = NULL;        //初始化相应变量    for(i = begin; i<10; i++){        buff[i][0] = '\0';    }    inputFile[0] = '\0';    outputFile[0] = '\0';        i = begin;
	//跳过空格等无用信息    while(i < end && (inputBuff[i] == ' ' || inputBuff[i] == '\t')){        i++;    }        k = 0;    j = 0;    fileFinished = 0;    temp = buff[k]; //以下通过temp指针的移动实现对buff[i]的顺次赋值过程    while(i < end){
		/*根据命令字符的不同情况进行不同的处理*/        switch(inputBuff[i]){             case ' ':            case '\t': //命令名及参数的结束标志                temp[j] = '\0';                j = 0;                if(!fileFinished){                    k++;                    temp = buff[k];                }                break;
            case '<': //输入重定向标志
                if(j != 0){
                    temp[j] = '\0';
                    j = 0;
                    if(!fileFinished){
                        k++;
                        temp = buff[k];
                    }
                }
                temp = inputFile;
                fileFinished = 1;
                i++;
                break;                            case '>': //输出重定向标志                if(j != 0){                    temp[j] = '\0';                    j = 0;                    if(!fileFinished){                        k++;                        temp = buff[k];                    }                }                temp = outputFile;                fileFinished = 1;                i++;                break;                            case '&': //后台运行标志                if(j != 0){                    temp[j] = '\0';                    j = 0;                    if(!fileFinished){                        k++;                        temp = buff[k];                    }                }                cmd->isBack = 1;                fileFinished = 1;                i++;                break;                            default: //默认则读入到temp指定的空间                temp[j++] = inputBuff[i++];                continue;		}        
		//跳过空格等无用信息        while(i < end && (inputBuff[i] == ' ' || inputBuff[i] == '\t')){            i++;        }	}        if(inputBuff[end-1] != ' ' && inputBuff[end-1] != '\t' && inputBuff[end-1] != '&'){        temp[j] = '\0';        if(!fileFinished){            k++;        }    }    
	//依次为命令名及其各个参数赋值    cmd->args = (char**)malloc(sizeof(char*) * (k + 1));    cmd->args[k] = NULL;    for(i = 0; i<k; i++){        j = strlen(buff[i]);        cmd->args[i] = (char*)malloc(sizeof(char) * (j + 1));           strcpy(cmd->args[i], buff[i]);    }    
	//如果有输入重定向文件,则为命令的输入重定向变量赋值    if(strlen(inputFile) != 0){        j = strlen(inputFile);        cmd->input = (char*)malloc(sizeof(char) * (j + 1));        strcpy(cmd->input, inputFile);    }
    //如果有输出重定向文件,则为命令的输出重定向变量赋值    if(strlen(outputFile) != 0){        j = strlen(outputFile);        cmd->output = (char*)malloc(sizeof(char) * (j + 1));           strcpy(cmd->output, outputFile);    }        return cmd;}
/*******************************************************
                      命令执行
********************************************************/
/*执行外部命令*/void execOuterCmd(SimpleCmd *cmd){    pid_t pid;    int pipeIn, pipeOut;        if(exists(cmd->args[0])){ //命令存在
        if((pid = fork()) < 0){            perror("fork failed");            return;        }                if(pid == 0){ //子进程            if(cmd->input != NULL){ //存在输入重定向                if((pipeIn = open(cmd->input, O_RDONLY, S_IRUSR|S_IWUSR)) == -1){                    printf("不能打开文件 %s!\n", cmd->input);                    return;                }                if(dup2(pipeIn, 0) == -1){                    printf("重定向标准输入错误!\n");                    return;                }            }                        if(cmd->output != NULL){ //存在输出重定向
                if((pipeOut = open(cmd->output, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == -1){
                    printf("不能打开文件 %s!\n", cmd->output);
                    return ;
                }
                if(dup2(pipeOut, 1) == -1){
                    printf("重定向标准输出错误!\n");
                    return;
                }
            }                        if(cmd->isBack){ //若是后台运行命令,等待父进程增加作业                signal(SIGUSR1, setGoon); //收到信号,setGoon函数将goon置1,以跳出下面的循环                while(goon == 0) ; //等待父进程SIGUSR1信号,表示作业已加到链表中                goon = 0; //置0,为下一命令做准备                                printf("[%d]\t%s\t\t%s\n", getpid(), RUNNING, inputBuff);                kill(getppid(), SIGUSR1);            }                        justArgs(cmd->args[0]);            if(execv(cmdBuff, cmd->args) < 0){ //执行命令                printf("execv failed!\n");                return;            }        }
		else{ //父进程            if(cmd ->isBack){ //后台命令                             fgPid = 0; //pid置0,为下一命令做准备                addJob(pid); //增加新的作业                kill(pid, SIGUSR1); //子进程发信号,表示作业已加入                                //等待子进程输出                signal(SIGUSR1, setGoon);                while(goon == 0) ;                goon = 0;            }else{ //非后台命令                fgPid = pid;                waitpid(pid, NULL, 0);            }		}    }else{ //命令不存在        printf("找不到命令 15%s\n", inputBuff);    }}
/*执行命令*/void execSimpleCmd(SimpleCmd *cmd){    int i, pid;    char *temp;    Job *now = NULL;        if(strcmp(cmd->args[0], "exit") == 0) { //exit命令        exit(0);    } else if (strcmp(cmd->args[0], "history") == 0) { //history命令        if(history.end == -1){            printf("尚未执行任何命令\n");            return;        }        i = history.start;        do {            printf("%s\n", history.cmds[i]);            i = (i + 1)%HISTORY_LEN;        } while(i != (history.end + 1)%HISTORY_LEN);    } else if (strcmp(cmd->args[0], "jobs") == 0) { //jobs命令        if(head == NULL){            printf("尚无任何作业\n");        } else {            printf("index\tpid\tstate\t\tcommand\n");            for(i = 1, now = head; now != NULL; now = now->next, i++){                printf("%d\t%d\t%s\t\t%s\n", i, now->pid, now->state, now->cmd);            }        }    } else if (strcmp(cmd->args[0], "cd") == 0) { //cd命令        temp = cmd->args[1];        if(temp != NULL){            if(chdir(temp) < 0){                printf("cd; %s 错误的文件名或文件夹名!\n", temp);            }        }    } else if (strcmp(cmd->args[0], "fg") == 0) { //fg命令        temp = cmd->args[1];        if(temp != NULL && temp[0] == '%'){            pid = str2Pid(temp, 1, strlen(temp));            if(pid != -1){                fg_exec(pid);            }        }else{            printf("fg; 参数不合法,正确格式为:fg %<int>\n");        }    } else if (strcmp(cmd->args[0], "bg") == 0) { //bg命令        temp = cmd->args[1];        if(temp != NULL && temp[0] == '%'){            pid = str2Pid(temp, 1, strlen(temp));                        if(pid != -1){                bg_exec(pid);            }        }
		else{            printf("bg; 参数不合法,正确格式为:bg %<int>\n");        }    } else{ //外部命令        execOuterCmd(cmd);    }        //释放结构体空间    for(i = 0; cmd->args[i] != NULL; i++){        free(cmd->args[i]);        free(cmd->input);        free(cmd->output);    }}
/*******************************************************
                     命令执行接口
********************************************************/void execute(){    SimpleCmd *cmd = handleSimpleCmdStr(0, strlen(inputBuff));    execSimpleCmd(cmd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -