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

📄 shell.cpp

📁 这是一个linux下的Shell.有命令历史和命令提示
💻 CPP
📖 第 1 页 / 共 3 页
字号:
							{								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 + -