int main(int argc, char *argv[]) { char cmd[MAX_CANON]; int history = 1; if (argc == 1) history = 0; else if ((argc > 2) || strcmp(argv[1], "history")) { fprintf(stderr, "Usage: %s [history]\n", argv[0]); return 1; } while(fgets(cmd, MAX_CANON, stdin) != NULL) { if (*(cmd + strlen(cmd) - 1) == '\n') *(cmd + strlen(cmd) - 1) = 0; if (history && !strcmp(cmd, "history")) showhistory(stdout); else if (runproc(cmd)) { perror("Failed to execute command"); break; } } printf("\n\n>>>>>>The list of commands executed is:\n"); showhistory(stdout); return 0; }
int main(int argc, char *argv[]) { /* Allocate enough space on the stack * for a long command */ char cmd[MAX_CANON]; int history = 1; /* The command was executed without arguments */ if (argc == 1) { history = 0; } else if ((argc > 2) || strcmp(argv[1], "history")) { /* Either too many arguments given, or the * command was not executed with "history" * as the first parameter. * * Print a usage message to stderr, and exit with * return value 1. */ fprintf(stderr, "Usage: %s [history]\n", argv[0]); return 1; } /* Read from stdin until we get to EOF, '\n', or * MAX_CANON - 1, and store what was read into * cmd. * * If fgets() fails, it will return NULL, and so * its return value is properly checked here. */ while (fgets(cmd, MAX_CANON, stdin) != NULL) { /* We are not assuming that a new line character * is read to avoid input truncation. * * If a newline character was read, then NULL * terminate the string by overwriting '\n' with 0. */ if (*(cmd + strlen(cmd) - 1) == '\n') { *(cmd + strlen(cmd) - 1) = 0; } /* * If the history command was read, and the history * flag was set as an argument, the print the history * to stdout. */ if (history && !strcmp(cmd, "history")) { showhistory(stdout); } /* Otherwise, run the command. * * There's a bug here. An error won't be detected * if runproc() does not return 0. This can happen * if, for example, time() returns -1. */ else if (runproc(cmd)) { perror("Failed to execute command"); break; } } /* We're done executing user commands. * Show the command history and exit with * return value 0. */ printf("\n\n>>>>>The list of commands executed is:\n"); showhistory(stdout); return 0; }
int main(void) { struct node *head=NULL; /* The head of linked list*/ char inputBuff[MAXLINE]; /* Input buffer to hold the command entered */ char inputValue[MAXLINE]; /* Store input buffer for history record*/ char *subinputValue; /* Store string value along to r command*/ char *args[MAXLINE/2+1]; /* Command line arguments */ char *history_args[MAXLINE/2+1]; /* Command line arguments */ int bkgnd; /* Equals 1 if a command is followed by '&', else 0 */ int size=0; /* The length of history*/ int index=1; /* The current index of command*/ int capacity=8; /* the initial capacity of history is 8 */ head=(struct node *) malloc(sizeof(struct node)); /*create a fake head, avoid null point error*/ while (1){ /* Program terminates normally inside setup */ bkgnd = 0; printf("CSE2431Sh$"); /* Shell prompt */ fflush(0); setup(inputBuff, args, &bkgnd,inputValue); /* Get next command */ if(inputBuff[0]=='\0'){ /*if input is null, break */ continue; } if(!strcmp(args[0],"r")&&args[1]==NULL){ /*if r without arguments, show error message*/ printf("r with no history number\n"); continue; } if(!strcmp(args[0],"r")){ /* Used to check the input value followed by command 'r' is num or string */ if((args[1][0]>='A')) { int tempi=0; /* Start index */ struct node *temp=NULL; /* Point to the command followed by 'r' */ while(inputValue[tempi]=='r'||inputValue[tempi]==' '){ tempi++; } subinputValue = &inputValue[tempi]; /*copy input value followed by 'r' to variable subinputValue*/ temp = searchstr(subinputValue,&head); /* call searchstr() to find target command*/ if(temp==NULL){ printf("can not find that command in history\n"); continue; } else{ strcpy(inputValue,temp->argsBuff); } }else if(searchindex(atoi(args[1]),&head,inputValue)==0){ continue; } } /*if command is 'sethistory'*/ if(!strcmp(args[0],"sethistory")){ if(args[1]==NULL||*args[1]=='0'){ printf("sethistory: must provide exactly one size\n"); }else{ capacity=atoi(args[1]); } continue; } /* The command read through command line or execute through command 'rr' or 'r' will store in history*/ if((!strcmp(args[0],"r")) ||(!strcmp(args[0],"rr")&&searchindex(index-1,&head,inputValue)==1) ||(strcmp(args[0],"r")&&strcmp(args[0],"rr"))){ add(index,inputValue,head,&size,capacity); index++; } /** In the child processs, first check the command, if it is 'history','h','rr','r','sethistory',then enter specific routine, execute specific operations.otherwise, call execvp() ***/ pid_t child; child = fork(); /*fork another process*/ if(child<0) { /*if fork failed, exit the process*/ fprintf(stderr,"Fork Failed"); exit(-1); } else if(child==0) { if(!strcmp(args[0],"history")||!strcmp(args[0],"h")) { /*if command is 'history' or 'h', call showhistory()*/ showhistory(head->next); exit(-1); } else if((!strcmp(args[0],"r")||!strcmp(args[0],"rr"))&&!recently(inputValue,history_args)) { /*if command is 'r' or 'rr'*/ if(!strcmp(history_args[0],"history")||!strcmp(history_args[0],"h")){ showhistory(head->next); exit(-1); }else if(execvp(history_args[0],history_args)){ printf("execvp: No such file or directory \n"); exit(-1); } } else if(strcmp(args[0],"sethistory")&&execvp(args[0],args)){ /*execute command line in child process*/ printf("execvp: No such file or directory \n"); exit(-1); } } else { int status=0; if(bkgnd==0) { waitpid(child,&status,0); /* parent will wait for the child process to complete*/ } if(status==1){ printf("error!"); } } } }
void typeline(bc *bc, char *preload,int echocr) { int i=0,j; int code; int backcount=0; char linesave[LINESIZE],ch; int linesin; char ref; int xdelta; char *p1,*p2; char token[128]; char *fake; int scrollback; int startx, starty; char spaces[256], *zerospaces; char *tail; int oldlen; memset(spaces, ' ', sizeof(spaces)); zerospaces = spaces + sizeof(spaces)-1; *zerospaces = 0; top: tail=""; startx = bc->txpos; starty = bc->typos; xdelta=0; linesin=bc->hcount>HISTSIZE ? HISTSIZE : bc->hcount; strcpy(bc->debline, preload); i=strlen(bc->debline); tprintf(bc, preload); ref=0; fake=0; scrollback=0; while(!(bc->flags & (BF_CCHIT | BF_QUIT))) { if(!fake) { SDL_Delay(10); scaninput(bc); code=takedown(bc); //if(code=='q' + MYALTED) exit(0); // alt-q } else { code=*fake++; if(!code) {fake=0;continue;} } if(code==-1) continue; if(code==MYPAGEUP || code==(MYPAGEUP|MYSHIFTED)) { if(code==MYPAGEUP) ++scrollback; else scrollback+=bc->tysize; scrollback=showhistory(bc, scrollback); continue; } else if(code==MYPAGEDOWN || code==(MYPAGEDOWN|MYSHIFTED)) { if(code==MYPAGEDOWN) --scrollback; else scrollback-=bc->tysize; if(scrollback<0) scrollback=0; scrollback=showhistory(bc, scrollback); if(scrollback) continue; else ++ref; } if(code==9 || code==4) { j=0; while(i+xdelta-j>0) { ch=bc->debline[i+xdelta-j-1]; if(!isalpha(ch) && !isdigit(ch) && ch!='_' && ch!='.') break; ++j; } p1=token; while(j) *p1++=bc->debline[i+xdelta-j--]; *p1=0; if(*token) { if(code==9) fake=complete(token); else { cr(bc); listall(token); ref=1; } } } else if(code==0x7f) { if(!xdelta) continue; p1=bc->debline+i+xdelta; p2=p1+1; while((*p1++=*p2++)); --i; ++xdelta; ++ref; } else if(code==MYLEFT) { if(i+xdelta>0) {--xdelta;++ref;} } else if(code==MYRIGHT) { if(xdelta<0) {++xdelta;++ref;} } else if(code==MYUP) { if(backcount<linesin) { if(!backcount) memcpy(linesave,bc->debline,LINESIZE); ++backcount; oldlen = strlen(bc->debline); memcpy(bc->debline, bc->debhist+LINESIZE*((bc->hcount-backcount) & (HISTSIZE-1)), LINESIZE); oldlen -= strlen(bc->debline); if(oldlen>0) tail=zerospaces-oldlen; xdelta=0; } ++ref; } else if(code==MYDOWN) { if(backcount) { --backcount; oldlen = strlen(bc->debline); if(!backcount) memcpy(bc->debline,linesave,LINESIZE); else memcpy(bc->debline,bc->debhist+LINESIZE*((bc->hcount-backcount) & (HISTSIZE-1)),LINESIZE); oldlen -= strlen(bc->debline); if(oldlen>0) tail=zerospaces-oldlen; xdelta=0; } ++ref; } else if(code>=0 && code<128) { if(code==8) { if(i+xdelta) { --i; p1=bc->debline+i+xdelta; p2=p1+1; while((*p1++=*p2++)); ++ref; } else continue; } else if(code==CR) { if(echocr) cr(bc); break; } else if(code>=0x20 && i<bc->txsize-1 && i<sizeof(bc->debline)-1) { p2=bc->debline+i; p1=p2+1; j=1-xdelta; while(j--) *p1--=*p2--; *p1=code; ++ref; } else continue; } if(ref) { if(scrollback) scrollback=showhistory(bc, 0); i=strlen(bc->debline); tprintf(bc, "\033%dx\033%dy%s %s\033%dx\033%dy", startx, starty, bc->debline, tail, i+xdelta+startx, starty); tail=""; ref=0; } } if(bc->flags & BF_CCHIT) { flushinput(bc); if(!(bc->flags & BF_RUNNING)) { bc->flags &= ~BF_CCHIT; preload=""; tprintf(bc, "\n"); goto top; } } if(i) { memcpy(bc->debhist+LINESIZE*(bc->hcount & (HISTSIZE-1)),bc->debline,LINESIZE); ++bc->hcount; } }