📄 utility.c
字号:
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," \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 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)//
{ // fprintf(stderr,"mybat");
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 + -