#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 20 char 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(indexlen) { 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;iargs[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