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

📄 utility.c

📁 应用UNIX的fork()等系统调用
💻 C
📖 第 1 页 / 共 3 页
字号:
							 exit (0);
				   default:  waitpid(newpid, NULL, WUNTRACED); 
				}
			}
			else 
			{   
				if(states[0]&&(args[1]|| states[1]))
				       {            back_bat++;
				                     flag=1;
				      }
			          output_num=states[2]; /////////
			         my_bat(args,Inputs,Outputs,states);       //////
				 if(flag)   back_bat--;
			         output_num=0;////////////
			}
		        if(states[0])   exit(1);   
		                else   return 0;  
		}

        if(states[2])// set output Redirection : use freopen() 
		   {
                         get_fullpath(filepath, Outputs->filename);
			 outputfile=freopen(filepath, Outputs->opentype,stdout);
			 if(outputfile==NULL) 
			 {       Error(-6,NULL,NULL,NULL,Outputs->filename);				 
			         if(states[0]) exit(1);   
		                  else    return -4;  
			 }		     		   
		   }		 				 

       // check for internal/external command   	
          if (!strcmp(args[0],"cd")) // "cd "  command				   
             my_cd(args,Inputs,states);	

	else if (!strcmp(args[0],"clr")||!strcmp(args[0],"clear")) // "clear"  command
                {       // system("clear");
                        if(output_num==0 ) 
			          my_clear( );  // my_clear()里,使用exec调用clear	                		      			
                         if(args[1]|| states[1]||states[2])     //  no argument is needed after "clear"                                Error(4,NULL,NULL,NULL,args[0]); 	              }
 
        else if (!strcmp(args[0],"dir")) // "dir"  command 
            my_dir(args,Inputs,states);
				
        else if (!strcmp(args[0],"echo"))  // "echo" command
              my_echo(args,Inputs,states); // ???

        else if (!strcmp(args[0],"environ"))  // "environ" command               {  
                       list_environ( );                        if(states[1])//   invalid input redirection        e.g.   environ   <m.txt                                        Error(-3,NULL,Inputs,states,"environ");                      if(args[1])    // no argument is needed after "pwd"                             Error(-2,args+1,NULL,NULL,"environ");               }
				
        else if (!strcmp(args[0],"help")||!strcmp(args[0],"?"))   // "help" command
            {        my_help(args,Outputs,states); ///////////////////////////                      if(states[1])    // no argument is needed after "pwd"                             Error(-3,NULL,Inputs,states,args[0]);               }

      else if (!strcmp(args[0],"pause"))   // "pause" command
		{                        if(args[1]|| states[1]|| states[2])     //  no argument is needed after "pause"                                Error(4,NULL,NULL,NULL,args[0]); 				
		        if(states[0]+back_bat==0) //                                        ////////////////////////////////
                              getpass("Pause!\npress <Enter> key to continue... ");                                                 
		} 

         else  if (!strcmp(args[0],"pwd"))   // "pwd" command		                {		
                         show_pwd(  );                         if(states[1])//   invalid input redirection        e.g.   environ   <m.txt                                        Error(-3,NULL,Inputs,states,"pwd");                      if(args[1])    // no argument is needed after "pwd"                             Error(-2,args+1,NULL,NULL,"pwd");                             }
		 
         // check for external excutive file,  e.g.    ls    
         else {                            
                           strcpy(parent,"parent=") ;        
                            strcat(parent, getenv("shell"));                                              
                           switch (newpid=fork( ))
                           {
                                 case -1:   Error(-9,NULL,NULL,NULL,"fork");
                                 case 0:   // execution in child process                                                                  
                                                    if(states[1])// input redirection 
                                                        {	         get_fullpath(filepath,Inputs->filename);
                                                                         inputfile= freopen(filepath,"r",stdin); // open file 
                                                                         if(inputfile==NULL) 
							                       {    Error(-6,NULL,NULL,NULL,Inputs->filename);                                                                   
                                                                                     exit(1); 
								              }
				                        }
                                                      putenv( parent); //                                        
                                                      execvp(args[0],args);                                                    
						      Error(-1,args,NULL,NULL,NULL);// 										                                                                 
                                                     if(inputfile)  fclose(inputfile);                                                                                     exit(0);
			         default:    if(states[0]==0 )waitpid(newpid, NULL, WUNTRACED);  
                           } // end  'switch' 	
                 }  //end  ' else'       

	 if(outputfile)
		 {    fclose(outputfile);
		      freopen("/dev/tty","w",stdout);
		 }         
		 
	 if(states[2]>1)// more output 
		 {       states[2]--;////                         
                         my_spawn (args, Inputs, Outputs+1,states) ;///////
		 }

	 if(states[0]) exit(0);   
	 else return 0; 
}//  end  function   my_spawn( )

/*   Function "Error"  :    used to report errors   */
int Error(int errortype,char **args,const Redirect *  IOputs,const int *states, char * msg) //    
{          int i;        if(isbat)  // if executes from batchfile
		fprintf(stderr,"***Line %d of inputfile \"%s\": ",bat_line,batchfile);        switch(errortype)             {                 case  1:       fprintf(stderr,"Format Error: invlid argument '%s'(Letter %d), without openfile!\n",open,letter);// <  >>  >                                       fprintf(stderr,"Type 'help redirection'  to get help information abbout '<'  '>>' and '>'\n");                                        break;                 case  2:       fprintf(stderr,"Format Error(Letter %d): '%s' followed by invlid argument '%c'!\n", letter,open,*msg); // <  >> >                                        fprintf(stderr,"Type 'help redirection'  to get help information abbout '<'  '>>' and '>'\n");                                        break;                 case  0:      fprintf(stderr," %s\n",msg);  //                                      break;                 case 3:        fprintf(stderr,"Sorry: no help information about \"%s\" found in the manual of myshell!\n",msg);
                                      fprintf(stderr,"Type \"man %s\" to search in the manual of system.\nNote: press the key <Q> to exit the search.\n",msg);	                                         break;                 case 4:        fprintf(stderr,"Note: no argument is needed after \"%s\" , except the background-execute flag '&' .",msg);   //                                        fprintf(stderr,"Type 'help %s'  to get usage abbout '%s' .\n",msg,msg);                                                                       break;                  case 5:       fprintf(stderr,"System Note: can not open more than %d files as %s !\n",MAX_OPEN,msg);                                        break;                  case  -1:     fprintf(stderr,"System Warning: \"");
                                     while (*args)
                                              fprintf(stderr,"%s ",*args++);
                                     fprintf(stderr,"\b\" is not internal command or executive file!\n"); 
                                     if(isbat==0&&output_num==0)//
	                                         fprintf(stderr,"Type \"help command\" to see supported internal commands.\n");                                                                            break; //abort( );                 case  -2:   fprintf(stderr,"Format Warning: invalid  arguments \"" ) ;                                      while(*args)                                                 fprintf(stderr,"%s ",*args++);                                      fprintf(stderr,"\b\"  after command \"%s\" ! \n",msg);                                       break;                 case  -3:   fprintf(stderr,"Invalid  input redirection: ");                                      for(i=0;i<states[1];i++)                                                 fprintf(stderr,"\"<%s\" ",IOputs[i].filename);                                       fprintf(stderr,"after \"%s\" !\n",msg);                                      break;                 case  -4:   fprintf(stderr,"Invalid  output redirection: ");                                       for(i=0;i<states[1];i++)                                                 fprintf(stderr,"\"%s%s\" ",IOputs[i].opentype,IOputs[i].filename);                                      fprintf(stderr,"after \"%s\" !\n",msg);                                      break;                 case  -5:    fprintf(stderr,"Path Error : \"%s\":  not a directory or not exist!\n",msg);                                       break;                 case  -6:   fprintf(stderr,"File Error: can not open file \"%s\"  !\n",msg);                                      break;                 case -7:   fprintf(stderr,"Overflow Error: the assigned dirpath is longer than permitted longth(%d)!\n",MAX_PATH);                                      break;                                default:    fprintf(stderr,"%s: %s\n", strerror(errno), msg);                                       break;                                      abort( );                 }            return 1; 
}     /*   Function "my_delay" : used to delay   */void my_delay(int n){         n=n*1000000;        while(n--) ;}


/*   Function "get_fullpath" : used to get the full path of a file or a directory   */
void get_fullpath(char *fullpath,const char *shortpath)  // 
{       
	  int i,j; 
	  i=j=0;	  
	  fullpath[0]=0; 
	  char *old_dir, *current_dir;                       
      if(shortpath[0]=='~')// e.g.  ~/os
      {
         strcpy(fullpath, getenv("HOME"));
         j=strlen(fullpath);     
		 i=1; 
      }	  
	           else  if(shortpath[0]=='.'&&shortpath[1]=='.')// e.g.  ../os          {                                   old_dir=getenv("PWD");                 chdir("..");                
                 current_dir=(char *)malloc(MAX_BUFFER);//分配内存空间
               if(!current_dir)        //如果内存空间分配失败
	                 Error(-9,NULL,NULL,NULL,"malloc failed!");                                       
                getcwd(current_dir,MAX_BUFFER);  //获取当前工作目录                strcpy(fullpath, current_dir);
                j=strlen(fullpath);     
		        i=2;                    chdir(old_dir);         }       else   if(shortpath[0]=='.')// e.g.   ./os           {                    strcpy(fullpath, getenv("PWD"));
                j=strlen(fullpath);     
		        i=1;          }     else if(shortpath[0]!='/')// e.g.   os/project1             {                       strcpy(fullpath, getenv("PWD"));                strcat(fullpath, "/");
                j=strlen(fullpath);                    
		        i=0;          }          strcat(fullpath+j,shortpath+i); 
	  return; 
}


/* ****************************** Command Functions ********************************** */

/*   Function "my_cd" : used to execute the command "cd"    */
int my_cd (char **args,const Redirect *Inputs,int *states)//
{   
    char dirpath[MAX_PATH], filepath[MAX_PATH], dirname[MAX_PATH];	  //='\0';
    char  *current_dir; 
	int i,flag;
        FILE *inputfile;          
	if(states[4]) 
	{
		if(args[1])///invalid arguments                                              Error(-2,args+1,NULL,NULL,"cd");                                   if(--states[1])                 Error(-3,NULL,Inputs+1,states,"cd");	   
	           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," \b\n\r");////       		    i=2;                        while (( args[i] = strtok(NULL," \b\n\r") ) )  i++;                                                        
	  }           else  if (states[1])   //  invalid input redirection       e.g.   cd  /home <a.txt     or   cd  <a.txt <b.txt                 Error(-3,NULL,Inputs,states,"cd");

      if(args[1])   //the argument of pathname is given  
	 {                     
	       if(args[2])   // more than one argument                                            Error(-2,args+2,NULL,NULL,"cd");         
	       get_fullpath(dirpath,args[1]);                                           						                       
	 } //end  " if(args[1]) " 

     else 	{    fprintf(stdout,"%s\n",getenv("PWD"));
		       return 0;
		}
			   		      
        flag=chdir(dirpath);   //改变工作目录
        if(flag)	//如果改变失败					
		{      Error(-5,NULL,NULL,states, args[1]); 		
                        return -2; 
		}
	 //如果目录改变成功,修改PWD的值
       current_dir=(char *)malloc(MAX_BUFFER);//分配内存空间

⌨️ 快捷键说明

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