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

📄 shell.cpp

📁 linux中的shell的实现 包括代码和题目
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************//*作者:王伟*//*班级:自42*//*学号:2004011443*//*程序功能:模拟linux下shell环境,实现shell功能*//*日期:2007.6.1*//*****************************************************************************/#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <unistd.h> #include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#define BUFFERSIZE 80int main(void) {	char *read_order(char *buffer);		//从键盘中读取命令	char **order_name(const char *input);	//返回每条命令	int pipel(char * input);	int pipe_number(const char *input);//统计管道数量	int redirect(char *input);//输入输出重定向	int order_number(const char *input);	//统计命令数量,以;相隔	char *path,*buffer;	char *all_order,**every_order;	int i,pipe,k,number;	if((buffer=(char *)malloc(BUFFERSIZE*(sizeof(char))))==0)	{		printf("error! can't malloc enough space for buffer\n");		return (0);	}	while(1)	{		path=getcwd(NULL,0);	//取得当前所在路径		printf("%s > $", path);		all_order=read_order(buffer);		//读取命令		if(all_order==NULL)			continue;		number=order_number(all_order);		if (number<0)			continue;		every_order=order_name(all_order);		i=0;		while (i<number)		{			if(strlen(every_order[i])!=0)			{				k=pipe_number(every_order[i]);	//是否有管道				if(k!=0)					pipel(every_order[i]);				else					redirect(every_order[i]);	//输入输出重定向或普通命令				//for debug				//printf("%s\n",every_order[i]);			}			i++;		}		//释放申请的空间		for(i=0;i<number;i++)			free(every_order[i]);		free(every_order);		free(all_order);		free(path);	}}char **order_name(const char *input)	//返回每条命令{	int order_number(const char *input);	//统计命令数量,以;相隔	int i,j,k,max_len;	char **order;		max_len=strlen(input);	k=order_number(input);	order=(char **)malloc(k*sizeof(char *));	for(i=0;i<k;i++)	{		order[i]=(char *)malloc((max_len+1)*sizeof(char));		order[i][0]='\0';	}	//分别取出被";"分割开的命令	k=0;	j=0;	for (i=0;i<=max_len;i++)	{		if (input[i]!=';')		{			order[k][j]=input[i];			j++;		}		else		{			order[k][j]='\0';			k++;			j=0;		}	}	//show the orders that are departed by ';'	/*for(i=0;i<k+1;i++)		printf("%s\n",order[i]);*/	return order;}int order_number(const char *input)	//统计命令数量,以;相隔{	int sum=0,i=0,len;	len=strlen(input);	while(i<len&&(input[i]==' '||input[i]=='	'))		i++;	if(input[i]==';')	//发生错误,出现;;	{		fprintf(stderr," syntax error near unexpected token: ;\n");		return -1;	}	if (i==len)		//命令参数中只有空格或tab		return -1;	for (i=0;i<len;i++)	if(input[i]==';')	{		while(i<strlen(input)&&(input[i+1]==' '||input[i+1]=='	'))			i++;		if(input[i+1]==';')	//发生错误,出现;;		{			fprintf(stderr," syntax error near unexpected token: ;;\n");			return -1;		}		else			sum++;	}	sum=sum+1;	return sum;}int pipel(char * input){	int redirect(char *input);	int is_back(char *order);	//分析是否为后台进程,并且将字符&去掉	int pipe_number(const char *input);	//统计管道数量				int status,i,j,k,**fd,back=0,len;	char **order;	int *child;		back=is_back(input);	len=strlen(input);	k=pipe_number(input);	order=(char **)malloc((k+1)*sizeof(char *));	for(i=0;i<k+1;i++)		order[i]=(char *)malloc((len+1)*sizeof(char));	child=(int *)malloc((k+1)*sizeof(char *));	fd=(int **)malloc(k*sizeof(int *));	for(i=0;i<k;i++)		fd[i]=(int *)malloc(2*sizeof(int));		//分别取出被管道分割开的命令	k=0;	j=0;	for (i=0;i<=len;i++)	{		if (input[i]!='|')		{			order[k][j]=input[i];			j++;		}		else		{			order[k][j]='\0';			k++;			j=0;		}	}	//test	/*for(i=0;i<k+1;i++)		printf("%s\n",order[i]);*/	/*分析完毕*/	//create the pipe	for(i=0;i<k;i++)		if(pipe(fd[i]) == -1) 		{			fprintf(stderr, "Open pipe error !\n");			//printf("Open pipe error !\n");			return 0;		}	//create the first child	i=0;	if((child[i]=fork())==0)	{		close(fd[i][0]);		if(fd[i][1] != STDOUT_FILENO) 		{			// 将标准的输出重定向到管道的写入端,这样该子进程的输出就写入了管道			if(dup2(fd[i][1], STDOUT_FILENO) == -1) 			{				fprintf(stderr, "Redirect Standard Out error !\n");				//printf("Redirect Standard Out error !\n");				return -1;			}			//关闭写入端			close(fd[i][1]);		}		redirect(order[i]);			exit(1);	//child1 exit	}	else	{		//wait for child		waitpid(child[i],&status,0);		close(fd[i][1]);	}	i++;	while(i<k)	{		if ((child[i]=fork())==0)		{			if(fd[i][0] != STDIN_FILENO) 			{				// 将标准的输入重定向到管道的读入端				if(dup2(fd[i-1][0], STDIN_FILENO) == -1) 								{					fprintf(stderr, "Redirect Standard In error !\n");					//printf("Redirect Standard In Error !\n");					return -1;				}				close(fd[i-1][0]);				// 将标准的输出重定向到管道的写入端,这样该子进程的输出就写入了管道				if(dup2(fd[i][1], STDOUT_FILENO) == -1) 								{					fprintf(stderr, "Redirect Standard Out error !\n");					//printf("Redirect Standard Out error !\n");					return -1;				}				close(fd[i][1]);			}			redirect(order[i]);			exit(1);		}		else		{			//wait for child			waitpid(child[i],&status,0);			close(fd[i][1]);			i++;		}	}	//create the last child	if((child[i] = fork()) == 0) 	{		close(fd[i-1][1]);		if(fd[i-1][0] != STDIN_FILENO) 		{			// 将标准的输入重定向到管道的读入端			if(dup2(fd[i-1][0], STDIN_FILENO) == -1) 			{				fprintf(stderr, "Redirect Standard In error !\n");				//printf("Redirect Standard In Error !\n");				return -1;			}			close(fd[i-1][0]);		}		redirect(order[i]);		exit(1);	}	else if(back==0)  	{		waitpid(child[i], NULL, 0);		close(fd[i-1][1]);	}	//释放申请的空间	for(i=0;i<k;i++)		free(fd[i]);	free(fd);	for(i=0;i<k+1;i++)		free(order[i]);	free(order);	free(child);	return 1;	/**************************************************/}int pipe_number(const char *input)//统计管道数量{	int sum=0,i;	for (i=0;i<strlen(input);i++)	if(input[i]=='|')		sum++;	return sum;}void do_cd(char *argv[])	//专门用于cd命令{ 	if(argv[1]!=NULL)	{ 		if(chdir(argv[1])<0) 			switch(errno)		{ 			case ENOENT: 				fprintf(stderr,"DIRECTORY NOT FOUND\n"); 				break; 			case ENOTDIR: 				fprintf(stderr,"NOT A DIRECTORY NAME\n"); 				break; 			case EACCES: 				fprintf(stderr,"YOU DO NOT HAVE RIGHT TO ACCESS\n"); 				break; 			default: 				fprintf(stderr,"SOME ERROR HAPPENED IN CHDIR\n"); 		} 	}} int redirect(char *input)	//重定向处理{	char **analize(const char *input);	//分析键入的命令,获取命令和参数并保存在arg中	char *is_file_exist(const char *order);		//判断命令是否存在	void do_cd(char *argv[]);	//专门用于cd命令	int number(const char *input);	//分析命令和参数数量,来划分相应字符串	int is_back(char *order);	//分析是否为后台进程,并且将字符&去掉	int pipe_number(const char *input);	//统计管道数量	char *order_path,*real_order;	char *out_filename,*in_filename;	char **analized_order;	int len,status,i,j,k,back=0,fd_out,fd_in,flag_out=0,flag_in=0;	pid_t pid;		back=is_back(input);	len=strlen(input);	out_filename=(char *)malloc((len+1)*(sizeof(char)));	in_filename=(char *)malloc((len+1)*(sizeof(char)));	real_order=(char *)malloc((len+1)*(sizeof(char)));	//读取字符串中的命令,并存放于real_order中	for(i=0;i<len;i++)	{		if (input[i]!='>'&&input[i]!='<')			real_order[i]=input[i];		else		{			if (input[i]=='>')				flag_out=1;			if (input[i]=='<')				flag_in=1;			break;		}	}

⌨️ 快捷键说明

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