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

📄 ush.c

📁 操作系统实验
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	<stdio.h>#include	<stdlib.h>#include	<unistd.h>#include	<signal.h>#include <string.h>#include	<dirent.h>#include	<sys/wait.h>#include	<sys/types.h>#include	<sys/stat.h>#include	<pwd.h>#include	<grp.h>char*  buf=NULL; 			       /* 缓冲区 ,用于存储命令行字符串  */int	 bufsize= 0;			    /* 缓冲区大小  */char*  arg_list[100]={0};      /* 用数组实现的命令行参数列表,每一个元素代表一个命令行参数,数组最大值为100,即命令行参数不能超过100个  */int    idex=0;                 /* 命令行参数数组索引  */int    special_cmd=0;          /* 指示命令类型的整形值 : 1,2 为重定向  3为管道*/int    token_num=0;            /* 命令行参数个数*/static short octarray[9]={  0400,0200,0100,0040,0020,0010,0004,0002,0001 };/*  文件权限*/static char  perms[10]  = "rwxrwxrwx";                                     /*  字符描述的文件权限*//***   功能:    获取命令行字符串,存储于buf指向的内存区域**   返回值:有字符输入,返回指向命令行字符串的指针;否则返回空值**   作者:    卢佳   20040094*/char* get_cmd(FILE * fin){    int	pos = 0;			       /* 缓冲区索引  */    char	ch;				       /* 输入字符  */        printf("bitsh<<");         /* 输出提示符  */  	 while((ch=getc(fin))!=EOF){  	     if(pos+1>=bufsize){				   if(bufsize==0)	                                 /*  分配初始内存块 */	  				    buf=(char*)malloc(100);			   else				                                 /*  内存不够时,继续扩充*/				    buf=(char*)realloc(buf,bufsize+100);			   bufsize+= BUFSIZ;		   		   }                   /* 到达命令末尾,则跳出循环*/		 if(ch=='\n')		  	 break;                  /* 否则,继续添加字符*/		 buf[pos++]=ch;	  }    if(ch==EOF&&pos== 0)		    /* 没有输入,返回NULL*/		  return NULL;			       	 buf[pos]='\0';                /* 添加文件结束标识  */	 bufsize=strlen(buf);                                                }/***   功能:    对命令行参数进行分析**   返回值:命令行参数列表(token表)**   作者:    卢佳 20040094*/void parse(){     char* token_start=buf;            /* 单词初始位置 */     char* token_end=buf;              /* 单词结束位置 */     int   len;                        /* 单词长度 */          while(1){                         /*   如果出现空格,退格,定位符或管道符号,则说明遇到一个单词 */         if(*token_end==' '||*token_end=='\t'||*token_end=='<'||*token_end=='>'||*token_end=='|') {                                  /*  为标记命令类型的special_cmd赋值 */             if(*token_end=='>'){                 special_cmd=1;                                   }             else if(*token_end=='<'){                 special_cmd=2;                                  }             else if(*token_end=='|'){                 special_cmd=3;                                  }                                    /*  将分析结果插入arg_list数组*/             len=token_end-token_start+1;                                 arg_list[idex]=(char*)malloc(len);                           memset(arg_list[idex],'\0',len);                       strncpy(arg_list[idex],token_start,len-1);                     idex++;             token_start=token_end+1;             token_num++;                      }                      /*  以下是对最后一个单词的处理*/        else if(*token_end=='\0'){                                        len=token_end-token_start+1;                                 arg_list[idex]=(char*)malloc(len);             memset(arg_list[idex],'\0',len);                           strncpy(arg_list[idex],token_start,len-1);                   idex++;             token_num++;             break;                     }           token_end++;          }}     /***   功能:       启动一个进程运行指定程序**  系统调用:execlp()**  作者:         卢佳  20040094*/int execute(char *argv[]){	int	pid ;	int	child_info = -1;	if ( argv[0] == NULL )				return 0;	if ((pid = fork())==-1)                /*创建子进程出现错误*/		perror("fork");	else if(pid==0){                       /*子进程执行体*/		signal(SIGINT, SIG_DFL);		signal(SIGQUIT, SIG_DFL);		execvp(argv[0], argv);		perror("cannot execute command\n");		exit(1);	}	else{                                 /*父进程执行体*/		if(wait(&child_info)==-1)			perror("wait");	}	return child_info;} /* **    功能:   一条命令执行完毕时,释放内存资源 **   返回值:无 **   作者:     卢佳  20040094 */           void free_buf(){    int i=0;    free(buf);    while(arg_list[i]!=NULL){        free(arg_list[i]);        i++;           }    idex=0;    bufsize=0;    buf=0;    token_num=0;}/***     功能:       处理重定向命令**    系统调用:execlp(),fork(),signal(),wait()**    返回值:     无**    作者:         卢佳  20040094*/void redirectory(char* source,char* destination){   int	pid ;   int   fd;   int	child_info = -1;                 		if ((pid = fork())==-1)                /*创建子进程出现错误*/		perror("fork");	else if(pid==0){                       /*子进程执行体*/		signal(SIGINT, SIG_DFL);		signal(SIGQUIT, SIG_DFL);		close(1);		fd = creat(destination,0644);		execlp(source,source,NULL);		perror("execlp");		exit(1);	}	else{                                 /*父进程执行体*/		if(wait(&child_info)==-1)			perror("wait");	}}/***   功能:         处理管道命令**   系统调用:fork(),pipe(),dup2()**  返回值:      无**  作者:          卢佳  20040094*/int pipe_op(char* source,char* destination){	 int	p[2];			         /* 两个文件描述符*/  	 int  status;              /* 进程状态*/	 switch(fork()){           /* 创建第一个进程*/	    case -1: 	            printf("cannot create process!\n");	    case  0:	            break;	    default:	            wait(&status);	            return(status);          }                  	 	 if(pipe(p)==-1){          /*  创建管道*/	     printf("can not create pipe!\n");	   }	   	 switch(fork()){           /*  创建第二个进程*/	     case -1:	             printf("cannot create process!\n");	     case  0:             /*  第二个子进程的标准输出连接到管道的输入*/	             dup2(p[1],1); 	             close(p[0]);	             close(p[1]);	             execlp(source,source,NULL);          /*  执行管道符号‘|’左边的命令*/	             printf("cannot execute!\n");	     default:             /*  第一个子进程的标准输入连接到管道的输出*/	            dup2(p[0],0);	            close(p[0]);	            close(p[1]);	            execlp(destination,destination,NULL); /*  执行管道符号‘|’右边的命令*/	            printf("cannot execute!\n");	   }}/***    功能:        移动文件到一个新的目录**   系统调用:link(),unlink()**    作者:         卢佳  20040094*/void move(){    if(link(arg_list[1],arg_list[2])==-1){        perror("link failed!\n");          }    if(unlink(arg_list[1])==-1){        perror("unlink failed!\n");        }   exit(0);} /* **   功能:       监视指定文件在一分钟内是否被修改,若是则给出警告 **  系统调用:stat() **  作者:         卢佳  20040094 */void watch_dog(){    int j;    struct stat sb;     time_t  last_time[11];    if(token_num>11){        fprintf(stderr,"too many files!\n");        exit(1);          }    for(j=1;j<token_num;j++){        if(stat(arg_list[j],&sb)==-1){            fprintf(stderr,"cannot stat!\n");            exit(1);                     }        last_time[j]=sb.st_mtime;         }   for(;;){       for(j=1;j<token_num;j++){           if(stat(arg_list[j],&sb)==-1||sb.st_mtime!=last_time[j]){                      fprintf(stderr,"look out: %s chaged\n",arg_list[j]);                      exit(0);                              }                   }       sleep(60);

⌨️ 快捷键说明

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