diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h index 777b4097..aaee3466 100644 --- a/42sh/includes/exec.h +++ b/42sh/includes/exec.h @@ -33,6 +33,7 @@ # define IS_PIPESTART(a) (a & PROCESS_PIPESTART) # define IS_PIPEEND(a) (a & PROCESS_PIPEEND) +# define IS_PIPESINGLE(a) (a & (PROCESS_PIPESTART | PROCESS_PIPEEND)) # include "libft.h" # include "types.h" @@ -95,7 +96,7 @@ void fd_reset(void); char *ft_findexec(char *path, char *file); -void set_exitstatus(int status); +void set_exitstatus(int status, int override); void ast_free(void *data, size_t content_size); diff --git a/42sh/includes/job_control.h b/42sh/includes/job_control.h index f93e4b0f..76a72498 100644 --- a/42sh/includes/job_control.h +++ b/42sh/includes/job_control.h @@ -45,7 +45,7 @@ struct s_jobc # include "exec.h" -t_process *job_getprocess(pid_t pid); +t_list *job_getprocess(pid_t pid); int job_addprocess(t_process *p); void job_update_id(void); void job_update_rank(void); diff --git a/42sh/src/exec/exec_command.c b/42sh/src/exec/exec_command.c index 13b002f5..fecfa33d 100644 --- a/42sh/src/exec/exec_command.c +++ b/42sh/src/exec/exec_command.c @@ -57,7 +57,6 @@ int exec_command(t_btree **ast) } p->av = NULL; p->pid = 0; - /* p->attributes = PROCESS_PIPESTART | PROCESS_PIPEEND; */ p->attributes &= ~(PROCESS_STATE_MASK | PROCESS_TYPE_MASK); btree_delone(ast, &ast_free); return (0); diff --git a/42sh/src/exec/launch_process.c b/42sh/src/exec/launch_process.c index 970b5d25..db991821 100644 --- a/42sh/src/exec/launch_process.c +++ b/42sh/src/exec/launch_process.c @@ -21,11 +21,10 @@ int launch_process(t_process *p) if (p->attributes & PROCESS_UNKNOWN) { ft_dprintf(2, "{red}%s: command not found: %s{eoc}\n", SHELL_NAME, p->av[0]); - set_exitstatus(127); - return (1); + set_exitstatus(127, 1); } - else if (p->attributes & PROCESS_BUILTIN && p->fdout == STDOUT) - set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env)); + else if (p->attributes & PROCESS_BUILTIN && IS_PIPESINGLE(p->attributes)) + set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env), 1); else { p->attributes &= ~PROCESS_STATE_MASK; @@ -34,7 +33,8 @@ int launch_process(t_process *p) && access(p->path, X_OK) == -1) { ft_dprintf(2, "{red}%s: permission denied: %s{eoc}\n", SHELL_NAME, p->av[0]); - return (-1); + set_exitstatus(126, 1); + return (1); } pid = fork(); if (pid == 0) @@ -43,15 +43,16 @@ int launch_process(t_process *p) process_setsig(); process_redirect(p); (*p->execf)(p->path, p->av, data_singleton()->env); - exit(42); + exit(43); } else if (pid > 0) { p->pid = pid; process_setgroup(p, pid); + return (0); } else if (pid == -1) - perror("fork"); + ft_dprintf(2, "{red}internal fork error{eoc}\n"); } - return (0); + return (1); } diff --git a/42sh/src/exec/set_exitstatus.c b/42sh/src/exec/set_exitstatus.c index 584abdcc..19c79d48 100644 --- a/42sh/src/exec/set_exitstatus.c +++ b/42sh/src/exec/set_exitstatus.c @@ -12,11 +12,27 @@ #include "minishell.h" -void set_exitstatus(int status) +void set_exitstatus(int status, int override) { char *astatus; + int exitval; - astatus = ft_itoa(status); - builtin_setenv("setenv", (char*[3]){"?", astatus}, data_singleton()->env); + if (override) + exitval = status; + else + { + if (WIFEXITED(status)) + exitval = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + exitval = 128 + WTERMSIG(status); + else + { + DG("fail: process was not exited nor signaled."); + return ; + } + } + astatus = ft_itoa(exitval); + builtin_setenv("setenv", (char*[]){"setenv", "?", astatus, 0}, + data_singleton()->env); ft_strdel(&astatus); } diff --git a/42sh/src/job-control/job_getprocess.c b/42sh/src/job-control/job_getprocess.c index b5223287..a5d421c3 100644 --- a/42sh/src/job-control/job_getprocess.c +++ b/42sh/src/job-control/job_getprocess.c @@ -12,7 +12,7 @@ #include "job_control.h" -t_process *job_getprocess(pid_t pid) +t_list *job_getprocess(pid_t pid) { t_jobc *jobc; t_job *j; @@ -25,7 +25,7 @@ t_process *job_getprocess(pid_t pid) { j = jlist->content; if ((lst = ft_lst_find(j->first_process, &pid, &process_cmp_pid))) - return (lst->content); + return (lst); jlist = jlist->next; } return (NULL); diff --git a/42sh/src/job-control/job_remove.c b/42sh/src/job-control/job_remove.c index 6c779b89..9c94db11 100644 --- a/42sh/src/job-control/job_remove.c +++ b/42sh/src/job-control/job_remove.c @@ -14,11 +14,16 @@ void job_remove(int id) { - t_jobc *jobc; + t_jobc *jobc; + t_job *j; + t_process *p; jobc = &data_singleton()->jobc; + j = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content; if (job_is_completed(id)) { + p = ft_lstlast(j->first_process)->content; + set_exitstatus(p->status, 0); if (id < data_singleton()->jobc.current_id) data_singleton()->jobc.current_id = id; ft_lst_delif(&jobc->first_job, &id, job_cmp_id, job_free); diff --git a/42sh/src/job-control/process_mark_status.c b/42sh/src/job-control/process_mark_status.c index 21cf949c..e071c53f 100644 --- a/42sh/src/job-control/process_mark_status.c +++ b/42sh/src/job-control/process_mark_status.c @@ -14,12 +14,14 @@ int process_mark_status(pid_t pid, int status) { + t_list *plist; t_process *p; if (pid > 1) { - if ((p = job_getprocess(pid))) + if ((plist = job_getprocess(pid))) { + p = plist->content; p->status = status; if (WIFSTOPPED(status)) {