版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux下Shell的实现说明文档作业一实验要求:Shell能够解析的语法为:commandline:=pipecommand|pipecommand"&"commandline|emptypipecommand:=redirectcommand|pipecommand"|"redirectcommandredirectcommand:=command">"outfile|command"<"infile|command"<"infile">"outfile|command">"outfile"<"infile|commandcommand:=program|commandargument1、需求说明和分析:本作业要求为实现一个类似于bash的shell。要求支持后台命令,管道,重定向这三个基本功能。并在此基础上,实现一些简单的内部命令,例如cd,pwd等等。2、设计方案:1、首先利用readline()函数读到用户输入的shell命令,采用一个数组来保存shell命令,数组有固定的大小。2、在main()函数中根据字符串中是否存在"&"字符判断是否为后台进程。如果是后台命令则判断是否是多条指令,如果不是将分割后的命令传递给pipel()函数,如果是的话分割之后利用while循环将命令传递给pipel()函数。如果不是后台进程,需要用waitpid()函数等待子进程结束后父进程才继续。3、在pipel()函数中,将shell命令根据"|"字符分割成一个个重定向命令,利用fork()得到子进程,并完成管道的设置,然后对每个重定向命令调用redirect()函数(如果没有"|",则将整个shell命令调用redirect()函数)。4、在redirect函数里面,根据有没有”>”,”<”来判断是否需要重定向。如果不需要重定向,就直接对参数列表调用execv(char*,char**)函数执行命令。如果需要重定向,进行相应的处理,再调用execv()函数。3、储存结构1、帮助文档的结构,方便Help命令的构建。structHELP_DOC{char*usage[lengthOfBUILTIN_COMMANDS];//用法char*info[lengthOfBUILTIN_COMMANDS];//介绍};2、后台命令管理链表的结构,用于jobs指令的后台储存。typedefstructBACK_JOBS{pid_tpid;//记录进程名的pidchar*cmd;intstatus;//三种状态0为DONE1为RUNNING2为STOPPED}BACK_JOB;3、History命令需要的数据的链表节点结构typedefstructNode{intid;charcmd[100];//储存每条打过的命令structNode*next;}NODE;4、shell基本功能的实现难点1、管道的实现管道输出核心代码为:order=trim(strtok(cmd,"|"));other=trim(strtok(NULL,""));if(!other)redirect(order);else{pipe(&fd[0]);if((pid=fork())==0){close(fd[0]);close(STD_OUT);dup(fd[1]);close(fd[1]);redirect(order);}else{close(fd[1]);close(STD_IN);dup(fd[0]);close(fd[0]);waitpid(pid,&status,0);pipel(other);}}关闭管道输入端,将标准输出重定向到管道输出,然后关闭管道输出。管道输入的核心代码也是类似的。2、输入输出重定向首先判断是否有输入输出重定向,用标志记录,我把类型分为6种,根据这六种不同的类型,进行不同的重定向的方法。然后在以下核心代码中实现重定向,即把标准输入输出定向到指定的文件。if(type==4||type==5||type==6){if((fd_out=creat(outfile,0755))==-1){fprintf(stderr,"#error:redirectstandardouterror\n");return-1;}close(STD_OUT);dup(fd_out);close(fd_out);}if(type==3||type==5||type==6){if((fd_in=open(infile,O_RDONLY,S_IRUSR|S_IWUSR))==-1){fprintf(stderr,"#error:can'topeninputfile'%s'\n",infile);return-1;}close(STD_IN);dup(fd_in);close(fd_in);}3、后台运行的实现后台运行相对来说比较简单,主要是利用字符处理函数,来确认cmdline中是否有’&’这个符号,如果有的话,使后台标记位为1;如果没有的话,使后台标记位为0。这样在子进程创建完毕之后,父进程通过判断后台标记位来决定是否运行wait_pid函数。这样就实现了后台运行。4、词法分析的实现个人觉得,在编写shell是,词法分析是一个虽然没有很大技术含量,但十分繁琐也是十分重要的环节。尤其,如果要做的完善些,处理空格,引入错误机制等。判断管道,重定向,后台命令等都是在进行词法分析,占用了很大的代码量。而这些代码又几乎都是相似的。在网上看到更加复杂的shell采用了词法分析工具来进行词法分析,这联系到了上学期所学的编译原理课程设计。而我并没有采用陈英老师提供的词法分析工具,使用了模块化的strtok来对cmdline进行词法分析,也一样达到了很好的效果。5、shell内部命令的实现难点1、cd命令的实现cd命令的实现主要依赖于系统调用chdir()。我们通过将第一个参数传入chdir就可以进行一次成功的cd调用。通过判断chdir()不同的返回值可以判断出更改目录成功与否,并能输出错误原因。2、jobs命令的实现jobs命令要求维护一个链表,每次当有一个后台进程运行的时候,都要向这个链表中添加一个数据。并当子进程结束的时候会向父进程发送SIGCHLD信号,父进程也就是Shell要处理这个信号,并且将后台进程链表中相应的进程进行处理。3、exit命令的实现exit命令分两部分实现。第一,当词法分析到exit的时候直接调用系统调用exit()就可以了。第二,退出之前要判断一下后台进程链表中是否还有未执行完的任务,如果有未执行完的任务,要提示用户,取消退出。4、kill命令的实现kill命令的实现是通过信号来实现的。参数就是进程的pid,利用kill系统调用可以向相应的进程发送SIGQUIT信号来使进程强制退出。5、help命令的实现help命令需要的文档在程序一开始运行的时候就进行初始化,当需要的时候判断help的参数,并在数组中搜索所对应的序号,打印出来即可。6、history,!#,!-#的实现和jobs命令类似,history也需要维护一个链表,将打过的每个命令都添加到链表里面。而!#和!-#就是对链表进行搜索,根据数字的不同,进行不同次数的溯回。7、ctrl+z,ctrl+c的实现两个组合键的功能比较类似,都是产生信号量。其中ctrl+c产生一个信号量,shell程序只要忽略这个信号量即可,这个信号量会自动结束子程序的。而Ctrl+z比较复杂一点,他会产生两个信号量,一个是SIGSTCP,一个是SIGCHLD。需要在这两个信号量中都作出处理。具体为shell要忽略Ctrl+z信号量,并查看这个进程时候是否以前储存在后台程序中而作出相应的添加或者忽略的处理。还有就是要及时进行状态的切换,这就要求储存后台程序的数据结构中必须有一条是程序状态。8、bg,fg的实现fg的实现相对来说比较简单一点,只要得到想要转到前台的进程的pid,并让shell执行waitpid即可。而bg要通过kill这个系统调用给相应pid的进程发送信号量,其中要考虑到进程状态的转换的问题。9、左右键与上下键切换历史的实现这个基本就是对readline库的调用,如果想实现就详细阅读一下readline库的使用方法,并无太多技术含量。6、用户手册:参加其他shell,基本实现了shell的基本功能。7、编写过程遇到的问题1、内存问题是编写shell过程中遇到的最大的问题,可能对于申请释放内存不够熟练,经常出现内存的错误。2、信号的理解是重中之重,在和同学的讨论的过程中也发现Ctrl+z的实现是比较困难的。而没有Ctrl+z这个功能,后面的bg和fg都无法顺利的实现。8、测试代码dulang@ubuntu:~$./Shell-------------*Welcome*-------------dulang:~$lsabcout.cshell0.9.cshellproblem公共的文档examples.desktopout.txtShell1shellPS.c模板下载inshellshell.ctest视频音乐outShellShell.cworkspace图片桌面dulang:~$ls>abcdulang:~$catabcabcexamples.desktopinoutout.cout.txtshellShellshell0.9.cShell1shell.cShell.cshellproblemshellPS.ctestworkspace公共的模板视频图片文档下载音乐桌面dulang:~$ls|grepshell|grep.cshell0.9.cshell.cshellPS.cdulang:~$ls|grepshell|grep.c>abcddulang:~$catabcdshell0.9.cshell.cshellPS.cdulang:~$cdShell#error:thisisnotadirectorynamedulang:~$cdworkspacedulang:/home/dulang/workspace$cd..dulang:~$sleep5&[1]5255RUNNINGsleep5dulang:~$jobs[1]5255RUNNINGsleep5dulang:~$jobs[1]5255DONEsleep5dulang:~$sleep10^Z[2]5260STOPPEDThisisastopprocess.dulang:~$jobs[1]5255DONEsleep5[2]5260STOPPEDThisisastopprocess.dulang:~$fg1dulang:~$fg2dulang:~$jobs[1]5255DONEsleep5[2]5260DONEThisisastopprocess.dulang:~$historyid:18historyid:17jobsid:16fg2id:15fg1id:14jobsid:13sleep10id:12jobsid:11jobsid:10sleep5&id:9cd..id:8cdworkspaceid:7cdShellid:6catabcdid:5ls|grepshell|grep.c>abcdid:4ls|grepshell|grep.cid:3catabcid:2ls>abcid:1lsdulang:~$!-1id:18historyid:17jobsid:16fg2id:15fg1id:14jobsid:13sleep10id:12jobsid:11jobsid:10sleep5&id:9cd..id:8cdworkspaceid:7cdShellid:6catabcdid:5ls|grepshell|grep.c>abcdid:4ls|grepshell|grep.cid:3catabcid:2ls>abcid:1lsdulang:~$!1abcoutShellShell.cworkspace图片桌面abcdout.cshell0.9.cshellproblem公共的文档examples.desktopout.txtShell1shellPS.c模板下载inshellshell.ctest视频音乐dulang:~$pwd/home/dulangdulang:~$10、附录(源程序):============================================================================11、Name:Shell.c12、Author:Dulang13、Version:14、Copyright:dulang@copyrightnotice15、Description:ShellinC,Ansi-style16、============================================================================17、*/18、19、#include<stdio.h>20、#include<string.h>21、#include<stdlib.h>22、#include<unistd.h>23、#include<grp.h>24、#include<sys/types.h>25、#include<sys/wait.h>26、#include<sys/stat.h>27、#include<fcntl.h>28、#include<errno.h>29、#include<signal.h>30、#include<readline/readline.h>31、#include<readline/history.h>32、#defineSTD_IN033、#defineSTD_OUT134、#defineMAXORD2035、#defineMAXPARA836、#defineMAX_BACK_JOBS_NUM2037、#defineSIGSTCP2038、#definelengthOfBUILTIN_COMMANDS1039、40、staticintback_jobs_ptr=0;41、char*st[]={"DONE","RUNNING","STOPPED"};42、intcurrentpid;//记录当前shell运行的pid.43、intisCtrlz;44、enumBUILTIN_COMMANDS{NO_SUCH_BUILTIN=0,EXIT,CD,HISTORY,DO_HIS_CMD,PWD,KILL,HELP,JOBS};45、//fortabcompletion46、char*commands[]={"cd","cp","chmod",47、"exit",48、"mv","man"49、"rm","rmdir",50、"vi","bg","fg","grep","ls","cat",51、"history","help",52、"jobs","kill"53、"ps","pwd"};54、55、structHELP_DOC{56、char*usage[lengthOfBUILTIN_COMMANDS];57、char*info[lengthOfBUILTIN_COMMANDS];58、};59、char*trim(constchar*str);60、intis_back(char*order);61、intpipel(char*cmd);62、char*if_exist(char*order);63、voidhandle_sigchld(ints);64、voidhandle_sigint(ints);65、voidhandle_sigstcp(ints);66、voidinitWithHelpDoc(structHELP_DOC*);67、voiddo_help(char*);68、voiddo_pwd();69、//后台进程70、typedefstructBACK_JOBS{71、pid_tpid;72、char*cmd;73、intstatus;74、}BACK_JOB;75、76、typedefstructNode{77、intid;78、charcmd[100];79、structNode*next;80、}NODE;81、82、structBACK_JOBS*back_jobs[MAX_BACK_JOBS_NUM];83、staticNODE*head;84、structHELP_DOC*help_doc;85、86、intpipel(char*cmd){87、char*trim(constchar*str);88、intredirect(char*cmd);89、90、intfd[2],status,pid;91、char*order,*other;92、order=trim(strtok(cmd,"|"));93、other=trim(strtok(NULL,""));94、if(!other)95、redirect(order);96、else{97、pipe(&fd[0]);98、if((pid=fork())==0){99、close(fd[0]);100、close(STD_OUT);101、dup(fd[1]);102、close(fd[1]);103、redirect(order);104、}else{105、close(fd[1]);106、close(STD_IN);107、dup(fd[0]);108、close(fd[0]);109、waitpid(pid,&status,0);110、pipel(other);111、}112、}113、return1;114、}115、116、intredirect(char*cmd){117、char*trim(constchar*str);118、voiddo_cd(char*argv[]);119、120、char*order=trim(cmd),*order_path,*real_order;121、char*infile,*outfile,*arg[MAXPARA],*buffer;122、inti,type=2,fd_out,fd_in;123、124、for(i=0;i<strlen(cmd);i++){125、if(cmd[i]=='<')126、type++;127、if(cmd[i]=='>')128、type=type*2;129、}130、if(type==3||type==6)131、real_order=trim(strtok(cmd,"<"));132、elseif(type==4||type==5)133、real_order=trim(strtok(cmd,">"));134、elseif(type==2)135、real_order=trim(cmd);136、else{137、fprintf(stderr,"#error:badredirectionform\n");138、return-1;139、}140、141、arg[0]=trim(strtok(real_order,""));142、for(i=1;(arg[i]=trim(strtok(NULL,"")))!=NULL;i++)143、;144、if(strcmp(arg[0],"history")==0){145、while(head->next!=NULL){146、printf("id:%d%s\n",head->id,head->cmd);147、head=head->next;148、}149、exit(1);150、return1;151、}152、if(strcmp(arg[0],"jobs")==0){153、inti=1;154、for(;i<MAX_BACK_JOBS_NUM;i++){155、if(back_jobs[i]!=NULL)156、printf("[%d]%d%s\t\t\t\t%s\n",i,back_jobs[i]->pid,157、st[back_jobs[i]->status],back_jobs[i]->cmd);158、}159、exit(1);160、return1;161、}162、if(strcmp(arg[0],"help")==0){163、do_help(arg[1]);164、exit(1);165、return1;167、if(strcmp(arg[0],"pwd")==0){168、do_pwd();169、exit(1);170、return1;171、}172、if((order_path=if_exist(arg[0]))==NULL){173、fprintf(stderr,"#error:thiscommanddoesn'texist\n");174、exit(1);175、return-1;176、}177、switch(type){178、case2:179、break;180、case3:181、buffer=strtok(order,"<");182、infile=trim(strtok(NULL,""));183、break;184、case4:185、buffer=strtok(order,">");186、outfile=trim(strtok(NULL,""));187、break;188、case5:189、buffer=strtok(order,">");190、outfile=trim(strtok(NULL,"<"));191、infile=trim(strtok(NULL,""));192、break;193、case6:194、buffer=strtok(order,"<");195、infile=trim(strtok(NULL,">"));196、outfile=trim(strtok(NULL,""));197、break;198、default:199、return-1;200、}201、202、if(type==4||type==5||type==6){203、if((fd_out=creat(outfile,0755))==-1){204、fprintf(stderr,"#error:redirectstandardouterror\n");205、return-1;206、}207、close(STD_OUT);208、dup(fd_out);209、close(fd_out);211、212、if(type==3||type==5||type==6){213、if((fd_in=open(infile,O_RDONLY,S_IRUSR|S_IWUSR))==-1){214、fprintf(stderr,"#error:can'topeninputfile'%s'\n",infile);215、return-1;216、}217、close(STD_IN);218、dup(fd_in);219、close(fd_in);220、}221、execv(order_path,arg);222、223、exit(0);224、return1;225、}226、227、intis_back(char*order){228、intlen=strlen(order);229、if(order[len-1]=='&'){230、order[len]='\0';231、return1;232、}else233、return0;234、}235、236、voiddo_cd(char*argv[]){237、if(argv[1]!=NULL){238、if(chdir(argv[1])<0){239、switch(errno){240、caseENOENT:241、fprintf(stderr,"#error:directorycan'tbefound\n");242、break;243、caseENOTDIR:244、fprintf(stderr,"#error:thisisnotadirectoryname\n");245、break;246、caseEACCES:247、fprintf(stderr,"#error:youhavenorighttoaccess\n");248、break;249、default:250、fprintf(stderr,"#error:unknownerror\n");251、}252、}253、}254、}255、256、voiddo_help(char*argv){257、inti;258、if(argv==NULL){259、i=HELP;260、}261、elseif(strcmp(argv,"cd")==0){262、i=CD;263、}elseif(strcmp(argv,"exit")==0){264、i=EXIT;265、}elseif(strcmp(argv,"history")==0){266、i=HISTORY;267、}elseif(strcmp(argv,"pwd")==0){268、i=PWD;269、}elseif(strcmp(argv,"help")==0){270、i=HELP;271、}elseif(strcmp(argv,"jobs")==0){272、i=JOBS;273、}274、printf("%s\n",help_doc->usage[i]);275、printf("%s\n",help_doc->info[i]);276、return;277、}278、279、char*if_exist(char*order){280、char*all_path,*p,*path,*buffer;281、intlen;282、all_path=getenv("PATH");283、buffer=trim(all_path);284、len=strlen(all_path)+strlen(order);285、if((path=(char*)malloc(len*(sizeof(char))))==0){286、fprintf(stderr,"#error:can'tmallocenoughspaceforbuffer\n");287、returnNULL;288、}289、p=strtok(buffer,":");290、while(p){291、strcat(strcat(strcpy(path,p),"/"),order);292、if(access(path,F_OK)==0){293、returnpath;294、}295、p=strtok(NULL,":");296、}297、strcpy(path,order);298、if(access(path,F_OK)==0)299、returnpath;300、returnNULL;301、}302、303、char*trim(constchar*str){304、inti,j,k;305、char*order;306、if(str==NULL)307、returnNULL;308、for(i=0;i<strlen(str);i++)309、if(str[i]!=''&&str[i]!='')310、break;311、for(j=strlen(str)-1;j>-1;j--)312、if(str[j]!=''&&str[j]!='')313、break;314、if(i<=j){315、if((order=(char*)malloc((j-i+2)*(sizeof(char))))==0){316、fprintf(stderr,"#error:can'tmallocenoughspace\n");317、returnNULL;318、}319、for(k=0;k<j-i+1;k++)320、order[k]=str[k+i];321、order[k]='\0';322、returnorder;323、}else324、returnNULL;325、}326、327、voidhandle_sigchld(ints){328、/*executenon-blockingwaitpid,loopbecausewemayonlyreceive329、*asinglesignalifmultipleprocessesexitaroundthesametime.330、*/331、//printf("recieve%dpid%d.\n",s,currentpid);332、333、inti=1;334、if(isCtrlz==0)335、{336、for(;i<MAX_BACK_JOBS_NUM;i++){337、if(back_jobs[i]==NULL)338、continue;339、if(back_jobs[i]->pid==currentpid){340、back_jobs[i]->status=0;341、break;342、}343、}344、}else{345、isCtrlz=0;346、}347、pid_tpid;348、while((pid=waitpid(0,NULL,WNOHANG))>0){349、inti=1;350、for(;i<MAX_BACK_JOBS_NUM;i++){351、if(back_jobs[i]==NULL)352、continue;353、if(back_jobs[i]->pid==pid){354、back_jobs[i]->status=0;355、break;356、}357、}358、}359、}360、361、voidhandle_sigint(ints){362、//printf("Asigintreceive.");363、return;364、}365、366、voidhandle_sigstcp(ints){367、inti=1;368、isCtrlz=1;//告诉另一个信号处理函数,这是一个ctrlz369、intflag=0;//如果等于0,则代表这个程序没有被后台过。370、printf("\n");371、//kill(currentpid,SIGSTCP);372、for(;i<MAX_BACK_JOBS_NUM;i++){373、if(back_jobs[i]==NULL)374、continue;375、if(back_jobs[i]->pid==currentpid){376、back_jobs[i]->status=2;377、flag=1;378、break;379、}380、}381、382、if(flag==0){383、back_jobs_ptr++;384、back_jobs[back_jobs_ptr]=(structBACK_JOBS*)malloc(385、sizeof(structBACK_JOBS*));386、back_jobs[back_jobs_ptr]->pid=currentpid;387、back_jobs[back_jobs_ptr]->cmd=(char*)malloc(100);388、strcpy(back_jobs[back_jobs_ptr]->cmd,"Thisisastopprocess.");389、back_jobs[back_jobs_ptr]->status=2;390、printf("[%d]%d%s\t\t\t\t%s\n",back_jobs_ptr,391、back_jobs[back_jobs_ptr]->pid,392、st[back_jobs[back_jobs_ptr]->status],393、back_jobs[back_jobs_ptr]->cmd);394、}395、return;396、}397、398、voidinitWithHelpDoc(structHELP_DOC*help_doc){399、help_doc->usage[EXIT]="exit:exit";400、help_doc->info[EXIT]="Exittheshell.";401、402、help_doc->usage[CD]="cd:cd[dir]";403、help_doc->info[CD]=404、"Changetheshellworkingdirectory.\405、\n\tChangethecurrentdirectorytoDIR.\406、\n\tThedefaultDIRisthevalueoftheHOMEshellvariable.";407、408、help_doc->usage[HISTORY]="history:history[-c][-snum]";409、help_doc->info[HISTORY]=410、"Displayormanipulatethehistorylist.\411、\n\tDisplaythehistorylistwithlinenumbers,prefixingeachmodified\412、\n\tentrywitha`*'.AnargumentofNlistsonlythelastNentries.\413、\n\414、\n\tOptions:\415、\n\t-c\t\tclearthehistorylistbydeletingalloftheentries\416、\n\t-snum\tsizeofthehistorybuffertonum";417、418、help_doc->usage[PWD]="pwd:pwd";419、help_doc->info[PWD]="Printthenameofthecurrentworkingdirectory.";420、421、help_doc->usage[HELP]="help:help[pattern...]";422、help_doc->info[HELP]=423、"Displayinformationaboutbuiltincommands.\424、\n\tArguments:\425、\n\tPATTERNPatternspecifiyingahelptopic";426、427、help_doc->usage[JOBS]="jobs:jobs";428、help_doc->info[JOBS]=429、"Displaystatusofjobs.\430、\n\tListstheactivejobs.JOBSPECrestrictsoutputtothatjob.";431、}432、433、voiddo_pwd(){434、chardirname[100];435、if(getcwd(dirname,99)==NULL){436、fprintf(stderr,"getcwderror\n");437、}438、else{439、printf("%s\n",dirname);440、}441、}442、char*command_generator(constchar*text,intstate){443、char*name;444、staticintlist_index,len;445、446、if(!state){447、list_index=0;448、len=strlen(text);449、}450、451、while(name=commands[list_index]){452、list_index++;453、454、if(strncmp(name,text,len)==0)455、return(strdup(name));456、}457、458、return((char*)NULL);459、}460、461、462、char**command_completion(constchar*text,intstart,intend){463、char**matches=NULL;464、465、if(start==0)466、matches=rl_completion_matches(text,command_generator);467、468、return(matches);469、}470、471、voidinitialize_readline(){472、rl_attempted_completion_function=(CPPFunction*)command_completion;473、474、}475、476、intmain(void){477、signal(SIGCHLD,handle_sigchld);478、signal(SIGINT,handle_sigint);479、signal(SIGSTCP,handle_sigstcp);480、481、charall_order[100],*order[MAXORD];482、inti,pid,status,number=1,back,historyid=1;483、charbuf[80],prompt[100];484、chartmp[80];485、memset(tmp,0,sizeof(tmp));486、char*username,*arg[MAXPARA];487、structgroup*data;488、489、head=(NODE*)malloc(sizeof(NODE));490、strcat(head->cmd,"intial");491、data=getgrgid(getgid());492、username=data->gr_name;493、strcat(tmp,"/home/");494、strcat(tmp,username);495、496、//help文档497、help_doc=(structHELP_DOC*)malloc(20*sizeof(structHELP_DOC*));498、initialize_readline();499、initWithHelpDoc(help_doc);500、printf("-------------*Welcome*-------------\n");501、while(1){502、getcwd(buf,sizeof(buf));503、if(strcmp(tmp,buf)==0){504、memset(buf,0,sizeof(buf));505、buf[0]='~';506、buf[1]='\0';507、}508、sprintf(prompt,"%s:%s$",username,buf);509、//printf("%s",prompt);510、//strcat(prompt,username);511、//strcat(prompt,":");512、//strcat(prompt,buf);513、//strcat(prompt,"$");514、//printf("%s",prompt);515、516、//fgets(all_order,sizeof(all_order),stdin);517、//gets(all_order);518、char*t;519、t=readline(prompt);520、sprintf(all_order,"%s",t);521、if(all_order==NULL||trim(all_order)==NULL)522、continue;523、//储存历史命令524、NODE*next;525、next=(NODE*)malloc(sizeof(NODE));526、next->id=historyid++;527、strcpy(next->cmd,trim(all_order));528、next->next=head;529、head=next;530、add_history(all_order);531、532、back=is_back(trim(all_order));533、if(strcmp(trim(all_order),"exit")==0){534、inti=1;535、inte=1;536、for(;i<MAX_BACK_JOBS_NUM;i++){537、if(back_jobs[i]!=NULL){538、if(back_jobs[i]->status!=0){539、e=0;540、break;541、}542、}543、544、}545、if(e==0){546、fprintf(stdout,547、"Somejobsareundone,pleasestopthemfirst.\n");548、fprintf(stdout,"Type\"jobs\"toseethem.\n");549、continue;550、}else{551、printf("-------------*Goodbye*-------------\n");552、exit(-1);553、}554、}555、if(trim(all_order)[0]=='!'&&trim(all_order)[1]=='-'){556、inti;557、sscanf(trim(all_order),"!-%d",&i);558、if(i<0)fprintf(stderr,"!##mustbeanegativenumber.");559、NODE*p;560、p=head;561、intj,flag=0;562、for(j=0;j<i;j++){563、p=p->next;564、if(p==NULL){565、fprintf(stderr,"!##mustbealessthanhistorynumber.");566、flag=1;567、}568、}569、if(flag==1)continue;570、strcpy(all_order,p->cmd);571、historyid=historyid-1;572、head=head->next;573、}elseif(trim(all_order)[0]=='!'){574、inti;575、ss
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论