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

📄 utility.c

📁 用纯C语言编写的一个Linux下的Shell
💻 C
📖 第 1 页 / 共 3 页
字号:
		{      Error(-5,NULL,NULL,states, args[1]); 		
                        return -2; 
		}
	 //如果目录改变成功,修改PWD的值
     current_dir=(char *)malloc(MAX_BUFFER);//分配内存空间
     if(!current_dir)        //如果内存空间分配失败
	     Error(-9,NULL,NULL,states,"malloc failed!");            
     getcwd(current_dir,MAX_BUFFER);  //获取当前工作目录
     setenv("PWD",current_dir,1);     //修改PWD的值
     free(current_dir);
     return 0;
}    // end function "my_cd"



/*   Function "my_clear " : used to execute the command "clear"    */
void my_clear(void)    
{      // system("clear");	
	pid_t newpid;
    switch (newpid=fork( ))
       {
           case -1:
                                    Error(-9,NULL,NULL,NULL,"fork");
          case 0:   // execution in child process 
                                   execlp("clear",NULL,NULL); //
                                   Error(-9,NULL,NULL,NULL,"execlp"); // error if return from exec                                    
	       default:      waitpid(newpid, NULL, WUNTRACED);                                    fprintf(stderr,"Clear screen!\n");///////////////////////////// 
      }// end switch	 
         return;
}    // end function "my_clear"


/*   Function "my_dir " : used to execute the command "dir"    */
int my_dir(char **args,const Redirect *Inputs, int *states)//
{
       FILE  *inputfile ;
	   pid_t newpid;       DIR   *pdir;       int   i;        char   filepath[MAX_PATH], dirpath[MAX_PATH], dirname[MAX_PATH];         /*    处理路径   */              if(states[4]) 
		{
	      	if(args[1])///invalid arguments                                              Error(-2,args+1,NULL,NULL,"dir");                            if(--states[1])                 Error(-3,NULL,Inputs,states,"dir");
	         get_fullpath(filepath,Inputs->filename);
    	     inputfile=fopen(filepath,"r");  //  open file  
	         if(inputfile==NULL)//  can not open   
			 {    Error(-6,NULL,NULL,states,Inputs->filename);		    
		          return -2;   // File Error 
			 }         		  	                                                fgets(dirname,MAX_PATH,inputfile);   //             fclose(inputfile);                   args[1] = strtok(dirname," \t\n\r");//                              		     i=2;               while (( args[i] = strtok(NULL," \t\n\r") ) )  i++;                                                                     
		}         else  if (states[1])   //  invalid input redirection       e.g.   cd  /home <a.txt                            Error(-3,NULL,Inputs,states,"dir");

        if(args[1])   //the argument of pathname is given  
		{                     
	         if(args[2])   // more than one argument                                            Error(-2,args+2,NULL,NULL,"dir");         
	         get_fullpath(dirpath,args[1]);                                           						                       
		} //end  " if(args[1]) " 	   	   
       else strcpy(dirpath, "."); //  just   "dir"   means   " dir . "
       /* 以下开始检查路径是否存在 */
       pdir=opendir(dirpath);             
       if(pdir==NULL)	//如果不存在					
        {         Error(-5,NULL,NULL,states,args[1]);		
                  return -2 ;
        }
        /* 以下开始执行dir指令 */
       switch (newpid=fork( ))
              {
                   case -1:
                                       Error(-9,NULL,NULL,states,"fork");
                   case 0:       // execution in child process                                                          				                                           execlp( "ls","ls" ,"-al", dirpath, NULL);     ///  ls                                
                                       Error(-9,NULL,NULL,states,"execlp"); // error if return from exec		                                      		
	               default:   waitpid(newpid, NULL, WUNTRACED);
               }    // end switch	 
      return 0;
}    // end  function  "my_dir" 


/*   Function "my_echo " : used to execute the command "echo"    */
int my_echo (char **args,const Redirect *Inputs,int *states)//
 {
	   FILE * inputfile; 
	   char filepath[MAX_PATH];
	   char buf[MAX_BUFFER];
       int j,k;	   if(states[4])  // input redirection is before args[1] ,   e.g.     echo  <a.txt  hello   
	   {
		   if(args[1])    // args[1] is invalid                                     Error(-2,args+1,NULL,NULL,"echo");	                    
           for(j=0;j<states[1];j++) // e.g.  echo <a.txt <b.txt 
		   {   			   
		       get_fullpath(filepath,Inputs[j].filename);
               inputfile=fopen(filepath,"r");
               if(inputfile==NULL) 
			   {     Error(-6,NULL,NULL,NULL,Inputs[j].filename);				 
			         return -2; 
			   }
		       if(states[2]==0&&output_num==0)//  no output file  is open  
		       fprintf(stderr,"The contents of file \"%s\" is as follows:\n",Inputs[j].filename);
		       while (!feof(inputfile))    // display  the  contents  of  file  
				 {
                     if(fgets(buf, MAX_BUFFER, inputfile))  //
						    fprintf(stdout,"%s",buf); 
				 }	//				   		   
		       fclose(inputfile);
			   fprintf(stdout,"\n");	
		   }  		   
	   }
        
	   else {   if(states[1])//   invalid input redirection        e.g.    echo hello   <m.txt                            Error(-3,NULL,Inputs,states,"echo");                if(args[1])
                  {    for(k=1;k<states[3]-1;k++)  
		                   fprintf(stdout,"%s ",args[k]);//fputs(args[k],outputfile);  
				       fprintf(stdout,"%s",args[k]);  
				 }  
                fprintf(stdout,"\n");           	  			 	                    			                					
	   }   
   return 0;
}    // end  function  "my_echo"


/*   Function "list_environ" : used to execute the command "environ"  */
int list_environ (void) 
{		         
		 char ** env = environ;	            
		 while(*env) fprintf(stdout,"%s\n",*env++); 	                               
         return 0;        
}        

/*   Function "show_pwd" : used to execute the command "pwd"  */
int show_pwd (void)//  
{	 		               
         fprintf(stdout,"PWD=%s\n",getenv("PWD")); 		                 
         return 0;
}

/*  Function "my_help" : display the user manual;    seek  for  the key word such as  <help  dir> , output the file "readme" until meetin g  '#'   */
int my_help(char **args,const Redirect *Outputs,int *states)//
{        
	 FILE *readme;
     char buffer[MAX_BUFFER];  
	 char keywords [MAX_BUFFER]="<help ";   
	 int i,len; 
	 for(i=1;args[i];i++)
	 {
	      strcat(keywords,args[i]);
	      strcat(keywords," ");
	 }
	 len=strlen(keywords);
	 keywords[len-1]='>';
	 keywords[len]='\0';        
    if(!strcmp(keywords,"<help more>")) // "help more "  means showing the whole user manual!        {            strcpy(buffer,"more ");            strcat(buffer,getenv("readme_path"));            for(i=0;i<states[2];i++)               {  strcat(buffer,Outputs[i].open);                  strcat(buffer,Outputs[i].filename);               }              Execute(buffer);     //                               return 0;        }     readme=fopen(getenv("readme_path"),"r"); // 在运行myshell时,初始化阶段在环境变量里添加了readme_path项  

	 while(!feof(readme)&&fgets(buffer,MAX_BUFFER,readme))  // looking for keywords   such  as   <help dir>
	    {      if(strstr(buffer,keywords)) 
		       break;        }   
     while(!feof(readme)&&fgets(buffer,MAX_BUFFER,readme))//   display  from here   until meet   '#'
	 {
          if(buffer[0]=='#')
		       break;
          fputs(buffer,stdout);    // display help information 
	 }

     if(feof(readme))// if not found the key words
	 {	  keywords[len-1]='\0';   //  key words is  such as  "<help dir>"          Error(3,NULL,NULL,NULL,&keywords[6]);        
	 }
     if(readme) fclose(readme);
     return 0;
}

/*   Function "my_bat" : used to execute the command "myshell" with a batchfile    */
int my_bat(char **args,const Redirect *Inputs,const Redirect *Outputs, int *states)//
{	
	  FILE *inputfile;  //
	  char filepath[MAX_PATH]; 
	  int i=0;      char fullpath_batchfile[MAX_PATH] ;  //  之前批处理文件的fullpath  e.g  执行  myshell a.bat, 在a.bat里有myshell b.bat                                                              //  fullpath_batchfile记录a.bat的路径,以防无限次循环   e.g  执行  myshell a.bat, 在a.bat里有myshell a.bat       pid_t  newpid; 
	  if(isbat)  // if executes from batchfile
          fprintf(stderr,"***Line %d of inputfile \"%s\": ",bat_line,batchfile);//
      if(states[4])  // e.g.  myshell <a.bat      ==>     myshell a.bat	  
	  {	  if(args[1])// e.g.   myshell <a.bat b.bat              fprintf(stderr,"Note: can not open more than one inputfile after commnad '%s' .\n",args[0]);          args[1]=Inputs->filename;                                           --states[1];         i=1;             
	  }
 
	  if(args[1])  // e.g.  myshell a.bat    myshell <a.bxt
	  {                if(states[1]>0)  //  e.g.    myshell a.txt <b.txt                 Error(-3,NULL,Inputs+i,states,args[0]);  //  invalid  input redirection            if(args[2])   // more than one argument   e.g.    myshell  a.txt  b.txt                                     Error(-2,args+2,NULL,NULL,args[0]);                             
		 get_fullpath(filepath,args[1]); 		         get_fullpath( fullpath_batchfile,batchfile) ;  //  批处理文件的fullpath
         if(isbat && !strcmp(fullpath_batchfile,filepath))// e.g.  myshell a.txt, 而a.txt 里有myshell a.txt 语句
		  {
		              fprintf(stderr,"Warning: commands not execute, it will cause infinite loop!!!\n");             
		              return -5; 
		  }
                    
         inputfile=fopen(filepath,"r");    //  打开输入重定向文件
        if(inputfile==NULL)// can not open  file ! 
	      {         Error(-6,NULL,NULL,NULL,args[1]);	
		            return -2; 
	      } 
         isbat=1; 	  // 
         strcpy(batchfile,args[1]);  
         fprintf(stderr,"Turn to execute the commands in batch file \"%s\" :\n",batchfile);       	
                      
	     if( ! output_num)//  
	         my_shell(inputfile,NULL,states);  //my_shell( )函数里从inputfile读命令行,并解析和执行,结果输出到OutPuts
	                                                               
	     else 
		     for(i=0;i<states[2];i++)// 
		        {                                                                             my_shell(inputfile,Outputs+i,states);///                     rewind(inputfile);///
	                 output_num--;///
			     }
         fclose(inputfile);
	     fprintf(stderr,"\nExecution of batch file \"%s\" is finished!\n",batchfile);
	     bat_line=isbat=0;    //  	   
	  }

	  else   if( output_num) //e.g.  myshell >b.txt >n.txt 
	  {
		  isbat=0; // 
		  switch(newpid=fork( ))
		     {   case -1:      Error(-9,NULL,NULL,states,"fork");
		         case 0:      fprintf(stderr,"Please type commands(the results will be writen into \"%s\"):\n",Outputs->filename);
			                  my_shell(stdin,Outputs,states); //                                                                                                                                                                    
						      exit(0);
		         default:    waitpid(newpid, NULL, WUNTRACED);  
		     }                      
		   if( output_num>1) // 
             {      fprintf(stderr,"\n");		          
	                output_num--;
	                my_bat(args,Inputs,Outputs+1,states);
		     }  		     
	  }
		       else//  just  "myshell" :  show the version  	 
		  fprintf(stdout,"myshell 1.0  Copyright @ Yang Fuqiang---01051312\n");		 
     
      return 0;
}

⌨️ 快捷键说明

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