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

📄 utility.c

📁 用纯C语言编写的一个Linux下的Shell
💻 C
📖 第 1 页 / 共 3 页
字号:
				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);// 	                               my_delay(12); 	
                               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");                                                                     exit (0);//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);                                                       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," \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     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)	//如果改变失败					

⌨️ 快捷键说明

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