void eval_line(const char* s) { int type; char* token; // Your code here! // build the command command* c = command_alloc(); while ((s = parse_shell_token(s, &type, &token)) != NULL) command_append_arg(c, token); // execute it if (c->argc) run_list(c); command_free(c); }
void eval_command_line(const char* s, zombies* z) { int type; char* token; // commandlist contains command groups separated by ';' or '&' command** commandlist = (command**) malloc(sizeof(command*)); // keep track of how many command groups wehave int listcontent = 1; // Your code here! // build the command command* c = command_alloc(); // the first command group commandlist[0] = c; while ((s = parse_shell_token(s, &type, &token)) != NULL) { if(type == TOKEN_CONTROL) { // seeing a ';' means we have to make a new command group if(token[0] == ';') { c = command_alloc(); commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*)); commandlist[listcontent] = c; ++listcontent; // seeing a '&' means we have to make a new command group } else if(token[0] == '&' && !token[1]) { c->background = 1; c = command_alloc(); commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*)); commandlist[listcontent] = c; ++listcontent; // putting into new command group so that we can conditionally evaluate it } else if(token[0] == '&' && token[1] == '&') { c = command_alloc(); c->needcondition = 0; commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*)); commandlist[listcontent] = c; ++listcontent; // within a command group, mark it as piping if seeing '|' } else if(token[0] == '|' && !token[1]) { c->piping = 1; command_append_arg(c, type, token); // putting into new command group so that we can conditionally evaluate it } else if(token[0] == '|' && token[1] == '|') { c = command_alloc(); c->needcondition = 1; commandlist = (command**) realloc(commandlist, (listcontent + 1)*sizeof(command*)); commandlist[listcontent] = c; ++listcontent; } } else if(type == TOKEN_REDIRECTION) { // redirecting standard input if(token[0] == '<' || token[0] == '0') { c->redirectstdin = 1; // redirecting standard output } else if(token[0] == '>' || token[0] == '1') { c->redirectstdout = 1; // redirecting standard error } else if(token[0] == '2' && token[1] == '>') { c->redirectstderr = 1; } } else { // the token following a redirection token must be a file name that should be dup'ed // then clears the flag if(c->redirectstdin) { c->stdinfilename = token; c->redirectstdin = 0; } else if(c->redirectstdout) { c->stdoutfilename = token; c->redirectstdout = 0; } else if(c->redirectstderr) { c->stderrfilename = token; c->redirectstderr = 0; // all other normal tokens } else { command_append_arg(c, type, token); } } } // execute the command int condition = -1; // exit condition of previous command for(int i = 0; i < listcontent; i++) { if (commandlist[i]->argc) // test if this command group should run if (commandlist[i]->needcondition == -1 || (commandlist[i]->needcondition == 0 && condition == 0) || (commandlist[i]->needcondition == 1 && condition != 0)) eval_command(commandlist[i], &condition, z); command_free(commandlist[i]); } free(commandlist); }