rendered paste body#include "api.h"#include "lib.h"// this one is going to be supporting multiple command lines etc.#define ALWAYS_REPORT_EXIT_CODE 0#define PROMPT "+>"#define BUF_LEN 256#define ARG_LEN 80#define ARG_MAX 20char curr_line[BUF_LEN];int line_len;typedef struct { int len; char buf[ARG_LEN];} argument;void append_arg(argument*arg,char c) { arg->buf[arg->len++]=c;}void reset_arg(argument*arg) { memset(arg,0,sizeof(arg));}argument args[ARG_MAX];int arg_count=0;void split_args() { argument *curr_arg=args; reset_arg(curr_arg); curr_arg->len=0; arg_count=0; char *curr=curr_line; char *end=curr_line+line_len; while(curr!=end) { switch(*curr) { case 0: break; case ';': case '&': // command seperators if(curr_arg->len) { curr_arg++; reset_arg(curr_arg); arg_count++; } append_arg(curr_arg,*curr); ++curr_arg; reset_arg(curr_arg); arg_count++; break; case ' ': if(curr_arg->len) { curr_arg++; reset_arg(curr_arg); arg_count++; } break; default: append_arg(curr_arg,*curr); break; } ++curr; } if(curr_arg->len) arg_count++;}int read_line() { for(int i=0;i<BUF_LEN;++i) { char c = getch(); switch(c) { case 0: // null byte, probably a keyboard key we've not mapped yet. --i; continue; case 8: // backspace. i-=2; continue; case '\n': c=0; default: curr_line[i]=c; break; } if(c==0) { return line_len=i; } } return -1;}typedef struct { int background; int count; char* args[ARG_MAX];} execution_info;execution_info execinfo;int set_exec(int index,execution_info* info) { int curr=0; info->background=0; info->count=0; for(int i=0;i<ARG_MAX;++i) { info->args[i]=0; } while(index<ARG_MAX) { argument *arg=args+index; if(arg->len) { if(arg->len==1) { if(arg->buf[0]==';') { ++index; break; } else if(arg->buf[0]=='&') { info->background=1; ++index; break; } } info->args[curr++]=arg->buf; info->count++; index++; } else break; } return index;}void run_program(execution_info* info) { int program_fd =sys_open(info->args[0],0); if(program_fd==-1) { printf("No such program: %s - errno=%d\n",curr_line,errno); return; } int retval=0; int childpid=sys_fork(); switch(childpid) { case -1: printf("Error forking: %d\n",childpid); break; case 0: sys_exec(program_fd); print("Could not execute program\n"); sys_exit(1); // doesn't return... default: sys_close(program_fd); if(info->background) { printf("Running %d in background.\n",childpid); }else{ sys_wait(&retval); if(retval || ALWAYS_REPORT_EXIT_CODE) printf("%s returned %d\n",curr_line,retval); } break; }}int main(void) { print("!rsh version 2. (C) Richard Whitty 2009\n"); for(;;) { print(PROMPT); flush(); int len=read_line(); if(len==-1) { printf("\nLine too long!\n"); continue; } if(len==0) continue; if(strncmp(curr_line,"exit",5)==0) return 0; split_args();// printf("Got %d args\n",arg_count);// for(int i=0;i<arg_count;++i) {// printf("args[%d]=%s\n",i,args[i].buf);// }// int com=0; int x=0; while(x<arg_count) { x=set_exec(x,&execinfo); //for(int x=set_exec(0,&execinfo);x<arg_count;x=set_exec(x,&execinfo)) {// printf("Command %d: %s\n",com++,execinfo.background?"Run in background":"Run in forground");// printf("x=%d - args=%d\n",x,arg_count);// for(int i=0;i<execinfo.count;++i) {// printf("Arg[%d]:%s\n",i,execinfo.args[i]);// } run_program(&execinfo); } } return 0;}