exit statuses behave correctly now (like bash)

This commit is contained in:
Jack Halford 2017-02-02 00:56:16 +01:00
parent 6ad4ca1848
commit 0d8610ca65
8 changed files with 42 additions and 18 deletions

View file

@ -33,6 +33,7 @@
# define IS_PIPESTART(a) (a & PROCESS_PIPESTART) # define IS_PIPESTART(a) (a & PROCESS_PIPESTART)
# define IS_PIPEEND(a) (a & PROCESS_PIPEEND) # define IS_PIPEEND(a) (a & PROCESS_PIPEEND)
# define IS_PIPESINGLE(a) (a & (PROCESS_PIPESTART | PROCESS_PIPEEND))
# include "libft.h" # include "libft.h"
# include "types.h" # include "types.h"
@ -95,7 +96,7 @@ void fd_reset(void);
char *ft_findexec(char *path, char *file); 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); void ast_free(void *data, size_t content_size);

View file

@ -45,7 +45,7 @@ struct s_jobc
# include "exec.h" # include "exec.h"
t_process *job_getprocess(pid_t pid); t_list *job_getprocess(pid_t pid);
int job_addprocess(t_process *p); int job_addprocess(t_process *p);
void job_update_id(void); void job_update_id(void);
void job_update_rank(void); void job_update_rank(void);

View file

@ -57,7 +57,6 @@ int exec_command(t_btree **ast)
} }
p->av = NULL; p->av = NULL;
p->pid = 0; p->pid = 0;
/* p->attributes = PROCESS_PIPESTART | PROCESS_PIPEEND; */
p->attributes &= ~(PROCESS_STATE_MASK | PROCESS_TYPE_MASK); p->attributes &= ~(PROCESS_STATE_MASK | PROCESS_TYPE_MASK);
btree_delone(ast, &ast_free); btree_delone(ast, &ast_free);
return (0); return (0);

View file

@ -21,11 +21,10 @@ int launch_process(t_process *p)
if (p->attributes & PROCESS_UNKNOWN) if (p->attributes & PROCESS_UNKNOWN)
{ {
ft_dprintf(2, "{red}%s: command not found: %s{eoc}\n", SHELL_NAME, p->av[0]); ft_dprintf(2, "{red}%s: command not found: %s{eoc}\n", SHELL_NAME, p->av[0]);
set_exitstatus(127); set_exitstatus(127, 1);
return (1);
} }
else if (p->attributes & PROCESS_BUILTIN && p->fdout == STDOUT) else if (p->attributes & PROCESS_BUILTIN && IS_PIPESINGLE(p->attributes))
set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env)); set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env), 1);
else else
{ {
p->attributes &= ~PROCESS_STATE_MASK; p->attributes &= ~PROCESS_STATE_MASK;
@ -34,7 +33,8 @@ int launch_process(t_process *p)
&& access(p->path, X_OK) == -1) && access(p->path, X_OK) == -1)
{ {
ft_dprintf(2, "{red}%s: permission denied: %s{eoc}\n", SHELL_NAME, p->av[0]); 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(); pid = fork();
if (pid == 0) if (pid == 0)
@ -43,15 +43,16 @@ int launch_process(t_process *p)
process_setsig(); process_setsig();
process_redirect(p); process_redirect(p);
(*p->execf)(p->path, p->av, data_singleton()->env); (*p->execf)(p->path, p->av, data_singleton()->env);
exit(42); exit(43);
} }
else if (pid > 0) else if (pid > 0)
{ {
p->pid = pid; p->pid = pid;
process_setgroup(p, pid); process_setgroup(p, pid);
return (0);
} }
else if (pid == -1) else if (pid == -1)
perror("fork"); ft_dprintf(2, "{red}internal fork error{eoc}\n");
} }
return (0); return (1);
} }

View file

@ -12,11 +12,27 @@
#include "minishell.h" #include "minishell.h"
void set_exitstatus(int status) void set_exitstatus(int status, int override)
{ {
char *astatus; char *astatus;
int exitval;
astatus = ft_itoa(status); if (override)
builtin_setenv("setenv", (char*[3]){"?", astatus}, data_singleton()->env); 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); ft_strdel(&astatus);
} }

View file

@ -12,7 +12,7 @@
#include "job_control.h" #include "job_control.h"
t_process *job_getprocess(pid_t pid) t_list *job_getprocess(pid_t pid)
{ {
t_jobc *jobc; t_jobc *jobc;
t_job *j; t_job *j;
@ -25,7 +25,7 @@ t_process *job_getprocess(pid_t pid)
{ {
j = jlist->content; j = jlist->content;
if ((lst = ft_lst_find(j->first_process, &pid, &process_cmp_pid))) if ((lst = ft_lst_find(j->first_process, &pid, &process_cmp_pid)))
return (lst->content); return (lst);
jlist = jlist->next; jlist = jlist->next;
} }
return (NULL); return (NULL);

View file

@ -14,11 +14,16 @@
void job_remove(int id) void job_remove(int id)
{ {
t_jobc *jobc; t_jobc *jobc;
t_job *j;
t_process *p;
jobc = &data_singleton()->jobc; jobc = &data_singleton()->jobc;
j = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content;
if (job_is_completed(id)) if (job_is_completed(id))
{ {
p = ft_lstlast(j->first_process)->content;
set_exitstatus(p->status, 0);
if (id < data_singleton()->jobc.current_id) if (id < data_singleton()->jobc.current_id)
data_singleton()->jobc.current_id = id; data_singleton()->jobc.current_id = id;
ft_lst_delif(&jobc->first_job, &id, job_cmp_id, job_free); ft_lst_delif(&jobc->first_job, &id, job_cmp_id, job_free);

View file

@ -14,12 +14,14 @@
int process_mark_status(pid_t pid, int status) int process_mark_status(pid_t pid, int status)
{ {
t_list *plist;
t_process *p; t_process *p;
if (pid > 1) if (pid > 1)
{ {
if ((p = job_getprocess(pid))) if ((plist = job_getprocess(pid)))
{ {
p = plist->content;
p->status = status; p->status = status;
if (WIFSTOPPED(status)) if (WIFSTOPPED(status))
{ {