📄 shell.cpp
字号:
{ subPath(work); delete work; } } } } } return 0; } else if(strcmp(command_block[0],"his") == 0) { if(num_block == 1) commandbuf.show(1, false); else commandbuf.setSize(atoi(command_block[1])); return 0; } else if(strcmp(command_block[0],"tip") == 0) { if(num_block == 1) puts("lover:no tip char"); else tipchar = command_block[1][0]; return 0; } else if(strcmp(command_block[0],"exit") == 0) return 2; //exit command return 1; //not lover command } return -1;//command_block not valid } //return value//0:command not found//2:comand found. OK//-1:command_block is no validint Shell::command_simple(char** command_block,int num_block,pro_info& pro) { if(num_block > 0) { pro.init(); char* work; work = findFirstExecFile(command_block[0]); if(!work) { cout<<"lover: "<<command_block[0]<<": command not found"<<endl; free__(command_block,num_block); pro.argv = 0; return 0; } else { List<char> argv_list; argv_list.inset(work); //the first arg is the full path of the execfile path delete work; int i=0; for(i = 1; i < num_block; i++) { if(strcmp(command_block[i],"&")==0) pro.background = true; else if(command_block[i][0] == '>') { int flag = -1; if(command_block[i][1] == 0) { flag = 0; work = findFirst(command_block[++i],NORMALFILE); } else if(command_block[i][1] == '>') { pro.output_over_tail = true; if(command_block[i][2] == 0) { flag = 1; work = findFirst(command_block[++i],NORMALFILE); } else { flag = 2; work = findFirst(&command_block[i][2],NORMALFILE); } } else work = findFirst(&command_block[i][1],NORMALFILE); //flag = -1 if(work) { pro.output_filepath = new char[strlen(work)+1]; strcpy(pro.output_filepath,work); delete work; } else { switch(flag) { case 0: case 1: pro.output_filepath = new char[strlen(command_block[i])+1]; strcpy(pro.output_filepath,command_block[i]); break; case 2: pro.output_filepath = new char[strlen(&command_block[i][2])+1]; strcpy(pro.output_filepath,&command_block[i][2]); break; case -1: pro.output_filepath = new char[strlen(&command_block[i][1])+1]; strcpy(pro.output_filepath,&command_block[i][1]); break; } if(ismatchin(pro.output_filepath) == true) { cout<<"Lover: "<<pro.output_filepath<<" :no valid parameter"<<endl; delete pro.output_filepath; pro.output_filepath = 0; return 0; } } } else if(command_block[i][0] == '<') { if(command_block[i][1]==0) work = findFirst(command_block[++i],NORMALFILE); else work = findFirst(&command_block[i][1],NORMALFILE); if(work) { pro.input_filepath = new char[strlen(work)+1]; strcpy(pro.input_filepath,work); delete work; } else pro.input_filepath = 0; } else if(command_block[i][0] == '-') argv_list.inset(command_block[i],-1); else { List<char>* temp = findAll(command_block[i],ALL, true); if(temp && !temp->isempty()) argv_list.inset(temp); else { char* temp = new char[strlen(command_block[i]) + 1]; strcpy(temp, command_block[i]); int i = 0; while(temp[i] != 0) { if(temp[i] == TRAN_ABLE) strcpy(&temp[i],&temp[i+1]); i++; } argv_list.inset(temp,-1); delete temp; } } }//for over pro.argv = argv_list.getbuf(); return 2; }//else ever } return -1;} void Shell::run(){ char** command_block; int num_block; pro_info pro; bool runFlag = true; //the flag of running the process list int i = 0; int start = i; char* work = 0; bool blockflag = (command[i] == '\'')?false:true; do { if(command[i] == 0 || (command[i] == '|' && command[i-1] != TRAN_ABLE && blockflag)) { work = new char[i-start + 1]; strncpy(work,command+start,i - start); work[i-start] = 0; blockchar(work,command_block,num_block); int result = command_lover(command_block,num_block); if(result == 0 ) { runFlag = false; free__(command_block,num_block); } else if(result == 1) { int result = command_simple(command_block,num_block,pro); if(result == 2) { free__(command_block,num_block); if(tail == 0) { tail = new process_node; tail->pro = pro; head = tail; } else { process_node* temp = new process_node; temp->pro = pro; tail->next = temp; tail = temp; } } } else if(result == 2) { free__(command_block,num_block); exit__(); exit(0); } if(command[i] == 0) break; else { i++; while(command[i] != 0 && (command[i] == ' ' || command[i] == '\t')){i++;}; start = i; } } if(command[i] == '\'' && (i == 0 || command[i-1] != TRAN_ABLE )) blockflag = !blockflag; i++; }while(command[i-1] != 0); //only one command. no the pipe problem if(head != 0 && tail == head) { int statloc; int pid; while(-1 == (pid = fork())); if(pid) { WAIT_CHILD(); pro.id = pid; TELL_CHILD(pid); if(!head->pro.background) waitpid(pid,&statloc,0); else cout<<"["<<++num_process_background<<"]"<<pid<<endl; } else { TELL_PARENT(getppid()); WAIT_PARENT(); execv__(head->pro); } } else if(runFlag) { process_node* cur = head; int pipe_work[2]; int i = 0; while(cur!=0) { if(cur == head) //the first process input over is promitted. { cur->readFlag = false; if(cur->pro.output_filepath) { runFlag = false; cout<<"lover: "<<cur->pro.argv[0]<<": output over and pipe conflict"<<endl; } else { pipe(pipe_work); cur->writeFlag = true; cur->pipe_write = pipe_work[WRITE]; cur->next->pipe_read = pipe_work[READ]; } } else if(cur->next == 0) //the last process the output over is permitted { cur->writeFlag = false; if(cur->pro.input_filepath) { runFlag = false; cout<<"lover: "<<cur->pro.argv[0]<<": input over and pipe conflict"<<endl; } else cur->readFlag = true; } else { if(cur->pro.output_filepath||cur->pro.input_filepath) { runFlag = false; if(cur->pro.output_filepath) cout<<"lover: "<<cur->pro.argv[0]<<": output over and pipe conflict"<<endl; if(cur->pro.input_filepath) cout<<"lover: "<<cur->pro.argv[0]<<": input over and pipe conflict"<<endl; } else { cur->readFlag = true; cur->writeFlag = true; pipe(pipe_work); cur->pipe_write = pipe_work[WRITE]; if(cur->next) cur->next->pipe_read = pipe_work[READ]; } } if(runFlag) { int pid; while(-1 == (pid = fork())); if(pid) { WAIT_CHILD(); cur->pro.id = pid; TELL_CHILD(pid); } else { TELL_PARENT(getppid()); WAIT_PARENT(); if(cur->pipe_read >= 0 && cur->readFlag) { close(0); dup(cur->pipe_read); } if(cur->pipe_write >= 0 && cur->writeFlag) { close(1); dup(cur->pipe_write); } execv__(cur->pro); } } if(cur->pipe_write >= 0) close(cur->pipe_write); if(cur->pipe_read) close(cur->pipe_read); cur = cur->next; i++; } } while(head) { usleep(1); }}void Shell::execv__(pro_info pro){ if(pro.input_filepath) { pro.input_fid = open(pro.input_filepath,O_RDONLY); if(pro.input_fid >= 0) { close(0); dup(pro.input_fid); } } if(pro.output_filepath) { if(pro.output_over_tail) pro.output_fid = open(pro.output_filepath,O_APPEND|O_WRONLY|O_CREAT); else pro.output_fid = open(pro.output_filepath,O_WRONLY|O_CREAT); chmod(pro.output_filepath, S_IRWXU); if(pro.output_fid >= 0) { close(1); dup(pro.output_fid); } } if(pro.background) { sigset_t* set = new sigset_t; sigprocmask(0,0,set);//get the old signal mask work sigaddset(set,SIGINT);//add the SIGINT mask sigprocmask(0,set,0);//reset the subprocess signal mask } recoverIOenv(); execv(pro.argv[0],pro.argv);}void Shell::execv__(char* filepath, List<char>* o, char* outputfile){ if(!filepath || !o || o->isempty()) return; o->inset(filepath); char** argv = o->getbuf(); if(outputfile) { int fid = open(outputfile, O_WRONLY | O_CREAT); if(fid >= 0) { close(1); dup(fid); } } execv(filepath, argv);}/*********************************************************************/char* Shell::findfirst(List<char>path,char* p,int type){ if(!p) return (char*)0; char* o; char* temp; path.reset(); while((temp = path.getCur()) != 0) { o = findfirst(temp,p,type); if(o) return o; } return 0;}/*********************************************************************///ok/*********************************************************************/char* Shell::findfirst(char* path,char* p,int type){ if(!p || !path) return 0; char* o = 0; DIR* drip = 0; struct dirent* dp = 0; drip = opendir(path); if(drip) { while ((dp = readdir (drip)) != 0) { if (fnmatch (p, dp->d_name, 0) == 0 && (dp->d_type == type || type == ALL) ) { if(dp->d_type == 4) o = new char[strlen(path) + strlen(dp->d_name) + 2]; else o = new char[strlen(path) + strlen(dp->d_name) + 1]; strcpy(o,path); strcat(o,dp->d_name); if(dp->d_type == 4) strcat(o,"/"); closedir(drip); dirproc(o); return o; } } } return 0;}/*********************************************************************/ /*********************************************************************/List<char>* Shell::findall(List<char> path,char* p,int type){ List<char>* o = 0; if(!p) return 0; o = new List<char>; DIR* drip = 0; struct dirent* dp = 0; char* temp = 0; char* str; path.reset(); while((temp = path.getCur()) != 0) { drip = opendir(temp); if(drip) { while ((dp = readdir (drip)) != 0) { if (fnmatch (p, dp->d_name, 0) == 0 &&( dp->d_type == type || type == ALL)) { str = new char[strlen(temp) + strlen(dp->d_name) + 1]; strcpy(str,temp); strcat(str,dp->d_name); dirproc(str); o->inset(str); delete str; } } closedir(drip); } } if(path.isempty()) { delete o; return 0; } return o;}/*********************************************************************/ //ok/*********************************************************************/List<char>* Shell::findall(char* path, char* p,int type){ if(!path || !p) return 0; List<char>* o = 0; o = new List<char>; DIR* drip = 0; struct dirent* dp = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -