diff --git a/42sh/Makefile b/42sh/Makefile index 1a249d59..b20dd88f 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -57,6 +57,7 @@ exec/process_redirect.c\ exec/process_reset.c\ exec/process_setexec.c\ exec/process_setgroup.c\ +exec/process_setsig.c\ exec/set_exitstatus.c\ glob/dir_glob.c\ glob/expand_brace.c\ diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h index ea6efda7..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" @@ -46,6 +47,7 @@ struct s_process pid_t pid; int fdin; int fdout; + int toclose; int status; t_flag attributes; }; @@ -83,8 +85,9 @@ int exec_command(t_btree **ast); int launch_process(t_process *p); int process_setexec(t_type type, t_process *p); -int process_setgroup(t_process *p); +int process_setgroup(t_process *p, pid_t pid); int process_redirect(t_process *p); +void process_setsig(void); void process_free(void *content, size_t content_size); void process_reset(void); @@ -93,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 0cbba450..dac7a201 100644 --- a/42sh/src/exec/exec_command.c +++ b/42sh/src/exec/exec_command.c @@ -57,7 +57,7 @@ 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/exec_pipe.c b/42sh/src/exec/exec_pipe.c index 8e777ae1..cd454b9b 100644 --- a/42sh/src/exec/exec_pipe.c +++ b/42sh/src/exec/exec_pipe.c @@ -25,11 +25,13 @@ int exec_pipe(t_btree **ast) DG("pipe %i->%i", fds[PIPE_WRITE], fds[PIPE_READ]); p->fdout = fds[PIPE_WRITE]; start = IS_PIPESTART(p->attributes); + p->toclose = fds[PIPE_READ]; p->attributes &= ~PROCESS_PIPEEND; ft_exec(&(*ast)->left); p->attributes &= ~PROCESS_PIPESTART; + p->toclose = STDIN; close(fds[PIPE_WRITE]); p->fdout = STDOUT; p->fdin = fds[PIPE_READ]; diff --git a/42sh/src/exec/launch_process.c b/42sh/src/exec/launch_process.c index 116af8ed..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,26 +33,26 @@ 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) { - process_setgroup(p); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTSTP, SIG_DFL); - signal(SIGTTIN, sigttin_handler); - signal(SIGTTOU, sigttou_handler); - signal(SIGCHLD, SIG_DFL); + process_setgroup(p, 0); + 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/process_redirect.c b/42sh/src/exec/process_redirect.c index fed5209d..77830bb0 100644 --- a/42sh/src/exec/process_redirect.c +++ b/42sh/src/exec/process_redirect.c @@ -14,15 +14,15 @@ int process_redirect(t_process *p) { + if (p->toclose != STDIN) + close(p->toclose); if (p->fdin != STDIN) { - /* DG("redirect STDIN to %i", p->fdin); */ dup2(p->fdin, STDIN); close(p->fdin); } if (p->fdout != STDOUT) { - /* DG("redirect STDOUT to %i", p->fdout); */ dup2(p->fdout, STDOUT); close(p->fdout); } diff --git a/42sh/src/exec/process_setgroup.c b/42sh/src/exec/process_setgroup.c index 4cf1e1c4..186ed6d9 100644 --- a/42sh/src/exec/process_setgroup.c +++ b/42sh/src/exec/process_setgroup.c @@ -13,23 +13,18 @@ #include "job_control.h" #include "exec.h" -int process_setgroup(t_process *p) +int process_setgroup(t_process *p, pid_t pid) { - t_job *job; - int pid; + t_job *j; (void)p; - job = &data_singleton()->exec.job; - pid = getpid(); - if (job->pgid == 0) - job->pgid = pid; - if (setpgid(pid, job->pgid)) - DG("setpgid(%i, %i) failed", pid, job->pgid); - if (JOB_IS_FG(job->attributes)) - { - signal(SIGTTOU, SIG_IGN); - tcsetpgrp(STDIN, job->pgid); - signal(SIGTTOU, SIG_DFL); - } + if (!SHELL_HAS_JOBC(data_singleton()->opts)) + return (0); + j = &data_singleton()->exec.job; + if (!j->pgid) + j->pgid = pid ? pid : getpid(); + setpgid(pid, j->pgid); + if (pid == 0 && JOB_IS_FG(j->attributes)) + tcsetpgrp(STDIN, j->pgid); return (0); } diff --git a/42sh/src/exec/process_setsig.c b/42sh/src/exec/process_setsig.c new file mode 100644 index 00000000..b2a68b09 --- /dev/null +++ b/42sh/src/exec/process_setsig.c @@ -0,0 +1,11 @@ +#include "exec.h" + +void process_setsig(void) +{ + /* signal(SIGINT, SIG_DFL); */ + signal(SIGQUIT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGCHLD, SIG_DFL); +} 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_format_head.c b/42sh/src/job-control/job_format_head.c index e463a269..c7b8854f 100644 --- a/42sh/src/job-control/job_format_head.c +++ b/42sh/src/job-control/job_format_head.c @@ -18,7 +18,6 @@ void job_format_head(t_job *j) int rank[2]; job_getrank(&rank); - DG("rank[0]=%i,rank[1]=%i", rank[0], rank[1]); if (j->id == rank[0]) crank = '+'; else if (j->id == rank[1]) 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_getrank.c b/42sh/src/job-control/job_getrank.c index aadd7745..f07263e0 100644 --- a/42sh/src/job-control/job_getrank.c +++ b/42sh/src/job-control/job_getrank.c @@ -24,11 +24,9 @@ void job_getrank(int (*rank)[2]) jlist = jobc->first_job; (*rank)[0] = 0; (*rank)[1] = 0; - DG("check 1"); while (jlist && i < 2) { job = jlist->content; - DG("check 2: id=%i", job->id); if (job_is_stopped(job->id)) (*rank)[i++] = job->id; jlist = jlist->next; 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/job_run.c b/42sh/src/job-control/job_run.c index ce5c0f07..bd9d0f48 100644 --- a/42sh/src/job-control/job_run.c +++ b/42sh/src/job-control/job_run.c @@ -16,5 +16,8 @@ void job_run(t_job *job, int foreground) { mark_job_as_running(job); job_format(job, JOBS_OPTS_L); - foreground ? put_job_in_foreground(job, 1) : put_job_in_background(job, 1); + if (foreground) + put_job_in_foreground(job, 1); + else + put_job_in_background(job, 1); } diff --git a/42sh/src/job-control/job_wait.c b/42sh/src/job-control/job_wait.c index 1c49950a..62f5ebef 100644 --- a/42sh/src/job-control/job_wait.c +++ b/42sh/src/job-control/job_wait.c @@ -17,8 +17,9 @@ int job_wait(int id) pid_t pid; int status; - if (job_is_stopped(id) || job_is_completed(id)) + if (job_is_stopped(id)) return (0); + job_update_status(); pid = waitpid(WAIT_ANY, &status, WUNTRACED); while (!process_mark_status(pid, status) && !job_is_completed(id) diff --git a/42sh/src/job-control/process_mark_status.c b/42sh/src/job-control/process_mark_status.c index b02290e7..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)) { @@ -32,7 +34,7 @@ int process_mark_status(pid_t pid, int status) p->attributes |= PROCESS_COMPLETED; if (WIFSIGNALED(status)) ft_printf("{mag}%d: Terminated by signal %d.\n{eoc}", - (int)pid, WTERMSIG(p->status)); + (int)pid, WTERMSIG(status)); } return (0); } diff --git a/42sh/src/job-control/put_job_in_background.c b/42sh/src/job-control/put_job_in_background.c index 8de13514..02357157 100644 --- a/42sh/src/job-control/put_job_in_background.c +++ b/42sh/src/job-control/put_job_in_background.c @@ -12,10 +12,10 @@ #include "job_control.h" -int put_job_in_background(t_job *job, int cont) +int put_job_in_background(t_job *j, int cont) { if (cont) - if (kill(-job->pgid, SIGCONT) < 0) - perror("kill (SIGCONT)"); + if (kill(-j->pgid, SIGCONT) < 0) + DG("kill(SIGCONT) failed"); return (0); } diff --git a/42sh/src/job-control/put_job_in_foreground.c b/42sh/src/job-control/put_job_in_foreground.c index 1df2c754..187ca02f 100644 --- a/42sh/src/job-control/put_job_in_foreground.c +++ b/42sh/src/job-control/put_job_in_foreground.c @@ -12,27 +12,26 @@ #include "job_control.h" -int put_job_in_foreground(t_job *job, int cont) +int put_job_in_foreground(t_job *j, int cont) { t_jobc *jobc; jobc = &data_singleton()->jobc; + tcsetpgrp(STDIN, j->pgid); + tcsetattr(STDIN, TCSADRAIN, &jobc->shell_tmodes); + if (cont) { - signal(SIGTTOU, SIG_IGN); - if (tcsetpgrp(STDIN, job->pgid) == -1) - return (1); - signal(SIGTTOU, sigttou_handler); - tcsetattr(STDIN, TCSANOW, &job->tmodes); - if (kill(-job->pgid, SIGCONT) < 0) - perror("kill (SIGCONT)"); + tcsetattr(STDIN, TCSADRAIN, &j->tmodes); + if (kill(-j->pgid, SIGCONT) < 0) + DG("kill(SIGCONT) failed"); } - job_wait(job->id); - job_remove(job->id); - signal(SIGTTOU, SIG_IGN); + job_wait(j->id); + job_remove(j->id); + tcsetpgrp(STDIN, jobc->shell_pgid); - signal(SIGTTOU, sigttou_handler); - tcgetattr(STDIN, &job->tmodes); + + tcgetattr(STDIN, &j->tmodes); tcsetattr(STDIN, TCSADRAIN, &jobc->shell_tmodes); return (0); } diff --git a/42sh/src/job-control/sigint_handler.c b/42sh/src/job-control/sigint_handler.c index de5ec7dd..9ca6a1b3 100644 --- a/42sh/src/job-control/sigint_handler.c +++ b/42sh/src/job-control/sigint_handler.c @@ -15,5 +15,5 @@ void sigint_handler(int signo) { (void)signo; - DG("got SIGINT in process %i", getpid()); + DG("pid:%i got SIGINT", getpid()); } diff --git a/42sh/src/job-control/sigttin_handler.c b/42sh/src/job-control/sigttin_handler.c index 1b424bf5..95197fce 100644 --- a/42sh/src/job-control/sigttin_handler.c +++ b/42sh/src/job-control/sigttin_handler.c @@ -15,5 +15,5 @@ void sigttin_handler(int signo) { (void)signo; - DG("got SIGTTIN"); + DG("got SIGTTIN, pid=%i, pgid=%i", getpid(), getpgrp()); } diff --git a/42sh/src/job-control/sigttou_handler.c b/42sh/src/job-control/sigttou_handler.c index a999d1e1..e89a5641 100644 --- a/42sh/src/job-control/sigttou_handler.c +++ b/42sh/src/job-control/sigttou_handler.c @@ -15,5 +15,5 @@ void sigttou_handler(int signo) { (void)signo; - DG("got SIGTTOU"); + DG("got SIGTTOU, pid=%i, pgid=%i", getpid(), getpgid(getpid())); } diff --git a/42sh/src/line-editing/readline.c b/42sh/src/line-editing/readline.c index 154089c8..09a58998 100644 --- a/42sh/src/line-editing/readline.c +++ b/42sh/src/line-editing/readline.c @@ -66,6 +66,7 @@ void ft_reset_stats_term(int signal) int ft_readline(void) { signal(SIGWINCH, ft_reset_stats_term); + ft_save_stats_term(); if (tcsetattr(0, TCSANOW, ft_stats_term_termcaps()) == -1) return (-1); if (data_singleton()->line.input) diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index a575c718..6731ea08 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -28,7 +28,6 @@ int shell_single_command(char *command) return (0); if (ft_post_tokenize(&token, command)) return (1); - DG("after post_tokenize"); token_print(token); if (ft_parse(&ast, &token)) return (1); diff --git a/42sh/src/main/shell_init.c b/42sh/src/main/shell_init.c index b540d564..d33221da 100644 --- a/42sh/src/main/shell_init.c +++ b/42sh/src/main/shell_init.c @@ -28,9 +28,8 @@ void shell_init(int ac, char **av) signal(SIGINT, sigint_handler); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, sigtstp_handler); - /* signal(SIGTSTP, SIG_IGN); */ - signal(SIGTTIN, sigttin_handler); - signal(SIGTTOU, sigttou_handler); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); signal(SIGCHLD, sigchld_handler); *shell_pgid = getpid(); if (setpgid(*shell_pgid, *shell_pgid))