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 PROMPT_LAST_CHAR '>'#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); 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++;}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; memset(info,0,sizeof(execution_info)); while(index<arg_count) { argument *arg=args+index; if(arg->len) { if(arg->len==1) { if(arg->buf[0]==';') { ++index;// if(info->args[curr]) break;// else// continue; } else if(arg->buf[0]=='&') { info->background=1; ++index; break; } } info->args[curr++]=arg->buf; info->count++; index++; } else break; } return index;}__attribute__((unused)) static void dump_execinfo(execution_info* info) { printf("Command: %s\n", execinfo.background?"Run in background":"Run in forground"); for(int i=0;i<execinfo.count;++i) printf("Arg[%d]:%s\n",i,execinfo.args[i]);}void run_program(execution_info* info) { int program_fd=-1; if(!info->args[0]) return; // if it was a null command. if(info->args[0][0]=='/') program_fd =sys_open(info->args[0]+1,0); else 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_execve(program_fd,info->args);// 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) { char **argg=info->args; while(*argg){ print(*argg++); putch(' '); } printf(" returned %d\n",curr_line,retval); } } break; }}int main(void) { print("!rsh version 2. (C) Richard Whitty 2009\n"); for(;;) { print(PROMPT); flush(); line_len=fgets(stdin,curr_line,BUF_LEN); if(line_len==-1) { printf("\nLine too long!\n"); continue; }// printf("Got line: '%s' len: %d\n",curr_line,line_len); if(line_len==0) continue; if(strncmp(curr_line,"exit",5)==0) return 0; split_args(); int x=0; while(x<arg_count) { x=set_exec(x,&execinfo);// dump_execinfo(&execinfo); run_program(&execinfo); } } return 0;}