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

📄 redirect.c

📁 Linux下实现shell的部分功能
💻 C
字号:
#include "ysh.h"
#include "extern.h"

int redirect(char*in,int len)
{
	char *argv[20],*filename[20];
	pid_t pid;
	int i,j,k,fd_in,fd_out,is_in=-1,is_out=-1,num=0;
	int is_back=0,status=0;

/********************命令解析********************/
	/*argv[]用于存放命令和参数,filename用于存放重定向文件名,is_in,is_out分别是重定向输入标记和输出标记*/
	for (i=0,j=0,k=0;i<=len;i++) {
		if (in[i]==' '||in[i]=='\t'||in[i]=='\0'||in[i]=='<'||in[i]=='>') {
			if (in[i]=='>'||in[i]=='<') {
				if (num<3){ /*num存放重定向符号的出现次数*/
					num++;
					if (in[i]=='<')
						is_in=num-1; /*存在重定向输入is_in置-1*/
					else
						is_out=num-1; /*存在重定向输出is_out置-1*/

					if (j>0 && num==1) { /*处理命令和重定向符号相连的问题*/
						buf[j++]='\0';
						argv[k]=(char *) malloc(sizeof(char)*j);
						strcpy(argv[k],buf);
						k++;
						j=0; /*为读取下一命令或参数作准备*/
					}
				}else {
					printf("Error command!\n");
					return 0;
				}
			}
			if (j==0)
				continue;
			else {
				buf[j++]='\0';
				if (num==0) { /*尚未遇到重定向符号,字符串是参数或命令*/
					argv[k]=(char *) malloc(sizeof(char)*j);
					strcpy(argv[k],buf);
					k++;
					j=0;
				}else { /*遇到重定向符号,字符串是文件名*/
					filename[status]=(char *) malloc(sizeof(char)*j);
					strcpy(filename[status++],buf);
					j=0;
				}
			}
		}else { /*父进程*/
			if (in[i]=='&' && in[i+1]=='\0') { /*是否为后台命令*/
				is_back=1;
				continue;
			}
			buf[j++]=in[i];
		}
	}

/********************寻找命令文件********************/
	argv[k]=(char *) malloc(sizeof(char));
	argv[k]=(char *) 0; /*最后一参数置空*/

	if (is_founded(argv[0])==0) { /*查找命令文件*/
		printf("This command is not founded!\n");
		for (i=0;i<=k;i++)
			free(argv[i]);
		return 0;
	}

/********************命令的执行**********************/
	if ((pid=fork())==0) {
		if (is_out!=-1) { /*存在输出重定向*/
			if ((fd_out=open(filename[is_out],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1) { /*将文件描述符fd_out指向文件*/
				printf ("Can not open %s \n",filename[is_out]);
				return 0;
			}
		}
		
		if (is_in!=-1) { /*存在输入重定向*/
			if ((fd_in=open(filename[is_in],O_RDONLY,S_IRUSR|S_IWUSR))==-1) { /*将文件描述符fd_in指向文件*/
				printf("Can not open %s \n",filename[is_in]);
				return 0;
			}
		}

		if (is_out!=-1) {
			/*使用dup2函数将标准输出重定向到fd_out上,这样原来输出到标准输出的内容,将输出到fd_out所指向的文件。这就达到了重定向的目的*/
			if (dup2(fd_out,STDOUT_FILENO)==-1) {
				printf("Redirect standard out error!\n");
				exit(1);
			}
		}

		if (is_in!=-1) {
			/*使用dup2函数将标准输入重定向到fd_in上,这样原来从标准输入输入的内容,将从fd_in所指向的文件输入。这就达到了重定向的目的*/
			if (dup2(fd_in,STDIN_FILENO)==-1) {
				printf("Redirect standard in error!\n");
				exit(1);
			}
		}

		execv(buf,argv);
	}else { /*父进程*/
		if (is_back==0) /*判断是否需要等待子进程的完成*/
			waitpid(pid,&status,0);
	}

/********************释放空间************************/
	for (i=0;i<=k;i++)
		free(argv[i]);
	if (is_out!=-1) {
		free(filename[is_out]);
		close(fd_out);
	}
	if (is_in!=-1) {
		free(filename[is_in]);
		close(fd_in);
	}
	return 0;
}

⌨️ 快捷键说明

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