int check_cmd(char **cmd, int args_count, int logical, int _stdin, int _stdout) { /* * funkcja sprawdza przekazana komendę pod względem operatorów: "&", "1>", "2>" * przekazuje ją do wykonania i zwraca status wyjscia otrzymany od funkcji * wywołującej komendę */ if(cmd[0]) { for (int i=0; i < availible_cmds(); i++) { if (strcmp(commands_name[i], cmd[0]) == 0) { return (*commands_func[i])(cmd); } } int run_background = 0; // sprawdzamy czy mamy do czynienia z potokiem if (!has_pipe(cmd, args_count)) { for (int i = 0; i < args_count; i++) { // stdout if (strcmp(cmd[i], ">") == 0) { if (!cmd[i + 1]) { fprintf(stderr, "Brakujący argument dla przekierowania\n"); return 0; } } // stderr if (strcmp(cmd[i], "<") == 0) { if (!cmd[i + 1]) { fprintf(stderr, "Brakujący argument dla przekierowania\n"); return 0; } } // last arg if (i == args_count-1 && strcmp(cmd[i], "&") == 0) { cmd[args_count-1] = NULL; args_count--; run_background = 1; } } } int result = exec_cmd(cmd, args_count, run_background, logical, 0, 1, 0); return result; } return 0; }
void create_processes(char* buffer, char commands[][CMD_SIZE], char* envp[]) { int size = parse_cmds(buffer, commands); int pip[2], total = 0, pipe_in = 0; switch(fork()) { case -1: shell_error("fork()"); case 0: while(total != size) { if(pipe(pip) == -1) shell_error("pipe()"); //printf("pip : %d, %d\n", pip[0], pip[1]); char* temp[CMD_SIZE]; char* args[CMD_SIZE]; int used = separate_commands(total, commands, size, temp); get_arguments(temp, used, args); //NULL TERMINATED //print_args(temp, used); //print_args2(args); int in = get_stdin(temp, used, pipe_in); //get instream and outstream. int out = get_stdout(temp, used, pip); //printf("%d : %d\n", in, out); prepare_to_execute(args, envp, in, out); pipe_in = has_pipe(temp, used, pip); //printf("[%d]\n", pipe_in); total += used; } exit(1); default: if(!has_bg(commands, size)) if (wait(0) == -1) shell_error("wait()"); } }
int exec_cmd(char **args, int args_count, int run_background, int logical, int _stdin, int _stdout, int is_child) { /* * Funkcja tworzy potomka który wykonuje przekazana komende. * * Parametry: * is_child - informuje funkcję czy została ona wywołana przez potomka procesu głównego */ pid_t pid; int status; if (run_background && logical) { fprintf(stderr, "Polecenia warunkowe nie mogą występować dla poleceń uruchamianych w tle!\n"); return 0; } pid = fork(); switch (pid) { // error case -1: { perror("SOPshell fork"); status = EXIT_FAILURE; break; } // child case 0: { int pipe_idx = has_pipe(args, args_count); pid_t child_pid = -1; if(pipe_idx) { int _pipe[2]; if (pipe(_pipe) == -1) { perror("SOPshell pipe"); exit(EXIT_FAILURE); } child_pid = fork(); switch (child_pid) { case -1: { perror("SOPshell fork"); status = EXIT_FAILURE; break; } case 0: { if(args_count - pipe_idx - 1 > 0) { close(_pipe[1]); return exec_cmd(&args[pipe_idx + 1], args_count - pipe_idx - 1, run_background, logical, _pipe[0], _stdout, 1); } else { exit(EXIT_SUCCESS); } } default: { char ** new_args = malloc((pipe_idx) * sizeof(args[0])); memcpy(new_args, args, pipe_idx * sizeof(args[0])); new_args[pipe_idx] = NULL; args = new_args; args_count = pipe_idx; close(_pipe[0]); _stdout = _pipe[1]; } } }; dup2(_stdin, 0); dup2(_stdout, 1); int redirect_stdout = has_char(args, args_count, '>'); if (redirect_stdout && args[redirect_stdout+1]) { int fd = open(args[redirect_stdout+1], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); if(fd == -1) { perror("SOPshell open"); } else { args[redirect_stdout] = NULL; args_count = redirect_stdout; dup2(fd, _stdout); close(fd); } } int redirect_stdin = has_char(args, args_count, '<'); if (redirect_stdin && args[redirect_stdin+1]) { int fd = open(args[redirect_stdin+1], O_RDONLY); if(fd == -1) { perror("SOPshell open"); } args[redirect_stdin] = NULL; dup2(fd, _stdin); close(fd); } int result = execvp(args[0], args); if (result == -1) { fprintf(stderr, "SOPshell: komenda nie znaleziona: %s\n", args[0]); result = EXIT_FAILURE; } // ładnie zamykamy co otwieraliśmy close(_stdin); close(_stdout); exit(result); } // owner default: { if(run_background) { add_bg_process(args[0], pid); fprintf(stdout, "[%d] %s pid: %d\n", bg_proc_count, args[0], pid); } else { do { RUNNING = 1; waitpid(pid, &status, WUNTRACED); if(!RUNNING) { kill(pid, SIGINT); printf("\n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); if (WIFEXITED(status)) status = WEXITSTATUS(status); if (WIFSIGNALED(status)) status = EXIT_FAILURE; //printf("pid: %d, status:%d, WIFEXITED: %d, WEXITSTATUS: %d, WIFSIGNALED: %d, WTERMSIG: %d\n", pid, status, WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status)); } if (is_child) { exit(EXIT_SUCCESS); } } } //printf("status: %d", status); return status == EXIT_SUCCESS; }