/** * Parse and execute a command. */ int parse_command( command_t *c, int level, command_t *father) { int returnare; if (c->op == OP_NONE) { /* execute a simple command */ if(c->scmd != NULL && c->cmd1 == NULL && c->cmd2 == NULL) return parse_simple( c->scmd, level, c); } switch (c->op) { case OP_SEQUENTIAL: /* execute the commands one after the other */ returnare = parse_command( c->cmd1, level++, c); returnare = parse_command( c->cmd2, level++, c); return returnare; break; case OP_PARALLEL: /* execute the commands simultaneously */ do_in_parallel( c->cmd1, c->cmd2, level++, c); break; case OP_CONDITIONAL_NZERO: /* execute the second command only if the first one * returns non zero */ returnare = parse_command( c->cmd1, level++,c); if(returnare != 0) returnare = parse_command( c->cmd2, level++, c); return returnare; break; case OP_CONDITIONAL_ZERO: /* execute the second command only if the first one * returns zero */ returnare = parse_command(c->cmd1, level++, c); if(returnare == 0) returnare = parse_command( c->cmd2, level++, c); return returnare; break; case OP_PIPE: /* redirect the output of the first command to the * input of the second */ return do_on_pipe( c->cmd1, c->cmd2, level++, c); break; default: assert(false); } return 0; /* replace with actual exit code of command */ }
/** * Parse and execute a command. */ int parse_command(command_t *c, int level, command_t *father, void *h) { /* TODO sanity checks */ if (c->op == OP_NONE) { /* TODO execute a simple command */ /* TODO replace with actual exit code of command */ return parse_simple(c->scmd, level, father, (HANDLE*)h); } switch (c->op) { case OP_SEQUENTIAL: /* TODO execute the commands one after the other */ parse_command(c->cmd1, level+1, c, (HANDLE*)h); return parse_command(c->cmd2, level+1, c, (HANDLE*)h); break; case OP_PARALLEL: /* TODO execute the commands simultaneously */ if(do_in_parallel(c->cmd1, c->cmd2, level, father)){ return 0; } return -1; break; case OP_CONDITIONAL_NZERO: /* TODO execute the second command only if the first one * returns non zero */ if(parse_command(c->cmd1, level+1, c, (HANDLE*)h)){ return parse_command(c->cmd2, level+1, c, (HANDLE*)h); } break; case OP_CONDITIONAL_ZERO: /* TODO execute the second command only if the first one * returns zero */ if(parse_command(c->cmd1, level+1, c, (HANDLE*)h) == FALSE){ return parse_command(c->cmd2, level+1, c, (HANDLE*)h); } break; case OP_PIPE:{ /* TODO redirect the output of the first command to the * input of the second */ struct simple_command_t *cmds[100]; unsigned int x = 0; if (do_on_pipe(c, level, father, cmds, &x)){ return 0; } else{ return -1; } break; } default: return SHELL_EXIT; } return 0; /* TODO replace with actual exit code of command */ }
/** * Run commands by creating an annonymous pipe (cmd1 | cmd2) */ static bool do_on_pipe(command_t *s, int level, command_t *father, simple_command_t *queue[100], unsigned int *queue_len) { SECURITY_ATTRIBUTES sa; STARTUPINFO siStartupInfo; PROCESS_INFORMATION piProcessInfo; HANDLE hOutFile = INVALID_HANDLE_VALUE; HANDLE hInFile = INVALID_HANDLE_VALUE; HANDLE hErrFile = INVALID_HANDLE_VALUE; BOOL changed = FALSE; unsigned int i; HANDLE fdes[30][2]; if(!s) return true; if(s->scmd){ queue[*queue_len] = s->scmd; (*queue_len)++; return true; } if(s->cmd1 != NULL){ do_on_pipe(s->cmd1, level+1, s, queue, queue_len); } if(s->cmd2 != NULL){ do_on_pipe(s->cmd2, level+1, s, queue, queue_len); } if(s->up == NULL || s->up->op != OP_PIPE){ //initializare atribute securitate ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; ZeroMemory(&siStartupInfo, sizeof(siStartupInfo)); ZeroMemory(&piProcessInfo, sizeof(piProcessInfo)); siStartupInfo.cb = sizeof(siStartupInfo); //creare n-1 pipe-uri for(i = 0; i < (*queue_len) - 1 ; i++){ changed = CreatePipe(&fdes[i][0], &fdes[i][1], &sa, 11* 1024 *1024); } redirrect_command(queue[0], &siStartupInfo, &hInFile, &hOutFile, &hErrFile); RedirectHandle(&siStartupInfo, fdes[0][1], STD_OUTPUT_HANDLE); exec_simple_proc(queue[0], hErrFile, sa, siStartupInfo, piProcessInfo); close_handles(hInFile, hOutFile, hErrFile); CloseHandle(fdes[0][1]); for(i = 1; i < (*queue_len) - 1; ++i){ redirrect_command(queue[0], &siStartupInfo, &hInFile, &hOutFile, &hErrFile); RedirectHandle(&siStartupInfo, fdes[i][1], STD_OUTPUT_HANDLE); RedirectHandle(&siStartupInfo, fdes[i-1][0], STD_INPUT_HANDLE); exec_simple_proc(queue[i], hErrFile, sa, siStartupInfo, piProcessInfo); close_handles(hInFile, hOutFile, hErrFile); CloseHandle(fdes[i][1]); CloseHandle(fdes[i-1][0]); } redirrect_command(queue[(*queue_len)-1], &siStartupInfo, &hInFile, &hOutFile, &hErrFile); RedirectHandle(&siStartupInfo, fdes[(*queue_len)-2][0], STD_INPUT_HANDLE); exec_simple_proc(queue[(*queue_len)-1], hErrFile, sa, siStartupInfo, piProcessInfo); close_handles(hInFile, hOutFile, hErrFile); CloseHandle(fdes[(*queue_len)-2][0]); } return true; /* TODO replace with actual exit status */ }