Ver código fonte

job_control: norm launch_proc

emartine
Elouan Martinet 2 anos atrás
pai
commit
56d9f5e42e
  1. 1
      Makefile
  2. 2
      src/job_control.h
  3. 107
      src/job_control/launch_proc.c
  4. 65
      src/job_control/launch_proc2.c

1
Makefile

@ -115,6 +115,7 @@ SRC := \
readline/vi_delete_motion_c.c \
job_control/launch_job.c \
job_control/launch_proc.c \
job_control/launch_proc2.c \
job_control/init_job.c \
job_control/create_job.c \
job_control/free_jobs.c \

2
src/job_control.h

@ -25,7 +25,6 @@ struct s_proc
char **env;
char path[PATH_MAX + 1];
pid_t pid;
int completed;
int stopped;
int status;
int std_in;
@ -77,5 +76,6 @@ void free_arr(char **arr);
void free_job(t_job *job);
void free_proc(t_proc *proc);
void free_exec(void);
void wait_job(t_proc *proc);
#endif

107
src/job_control/launch_proc.c

@ -12,66 +12,6 @@
#include "twenty_one_sh.h"
int get_return_status(int status)
{
if (WIFEXITED(status))
return (WEXITSTATUS(status));
else if (WIFSIGNALED(status))
return (1000 + WTERMSIG(status));
else if (WIFSTOPPED(status))
return (2000 + WSTOPSIG(status));
return (1);
}
static void wait_job(t_proc *proc)
{
int status;
pid_t wpid;
t_proc *cur;
if (proc->next)
return ;
// TODO set job as launched?
// TODO the rest is for foreground, background is other stuff
tcsetpgrp(g_shell.term, proc->job->pgid);
// TODO cont stuff (only for `fg`) goes here (DRY)
// TODO ^^^^
// FIXME wait job func
status = 0;
while (proc->job->running > 0 && (wpid = waitpid(WAIT_ANY /*-proc->job->head_proc->pid*/, &status, WUNTRACED/* | WCONTINUED*/)) >= 0) // TODO replace by WAIT_ANY when we do background
{
if (WIFSTOPPED(status))
{
kill(wpid, SIGTERM); // TODO
kill(wpid, SIGCONT); // TODO
continue ;
}
cur = proc->job->head_proc;
while (cur)
{
if (wpid == cur->pid)
{
cur->completed = 1; // FIXME
proc->job->running--;
if (!cur->next)
{
if (WIFSIGNALED(status))
g_shell.exit_code = 1000 + WTERMSIG(status);
else
g_shell.exit_code = WEXITSTATUS(status);
}
break ;
}
cur = cur->next;
}
status = 0;
}
// FIXME ^^^^
tcsetpgrp(g_shell.term, g_shell.pgid);
tcgetattr(g_shell.term, &proc->job->tmodes);
cooked_terminal();
}
static void proc_parent(t_proc *proc)
{
proc->job->running++;
@ -91,7 +31,7 @@ static void proc_child(t_proc *proc)
if (proc->job->pgid == 0)
proc->job->pgid = getpid();
setpgid(0, proc->job->pgid);
tcsetpgrp(g_shell.term, proc->job->pgid); // FIXME don't do this in background
tcsetpgrp(g_shell.term, proc->job->pgid);
clear_signals();
if (proc->prev)
dup2(proc->prev->tunnel[0], STDIN_FILENO);
@ -106,21 +46,8 @@ static void proc_child(t_proc *proc)
}
}
void launch_proc(t_proc *proc)
static int launch_proc_error(t_proc *proc)
{
if ((proc->arg && !proc->is_builtin) || proc->next || proc->prev)
{
if ((proc->pid = fork()) < 0)
return ; //TODO fork error
else if (proc->pid > 0)
{
proc_parent(proc);
return ;
}
proc_child(proc);
}
if (command_redir(proc->cmd) < 0)
proc->error = 125;
if (proc->error)
{
if (proc->find_error)
@ -133,11 +60,17 @@ void launch_proc(t_proc *proc)
clean_shell();
exit(g_shell.exit_code);
}
return ;
return (-1);
}
return (0);
}
static void launch_proc_end(t_proc *proc)
{
if (!proc->arg || proc->is_builtin)
{
g_shell.exit_code = proc->arg ? start_builtin(proc->arg, proc->envl) : 0;
g_shell.exit_code = proc->arg ? start_builtin(proc->arg,
proc->envl) : 0;
command_redir_restore(proc->cmd);
if (proc->next || proc->prev)
{
@ -154,3 +87,23 @@ void launch_proc(t_proc *proc)
fatal_exit(7);
}
}
void launch_proc(t_proc *proc)
{
if ((proc->arg && !proc->is_builtin) || proc->next || proc->prev)
{
if ((proc->pid = fork()) < 0)
fatal_exit(SH_ENOMEM);
else if (proc->pid > 0)
{
proc_parent(proc);
return ;
}
proc_child(proc);
}
if (command_redir(proc->cmd) < 0)
proc->error = 125;
if (launch_proc_error(proc) < 0)
return ;
launch_proc_end(proc);
}

65
src/job_control/launch_proc2.c

@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* launch_proc2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: emartine <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/04/30 18:45:08 by emartine #+# #+# */
/* Updated: 2019/04/30 18:45:09 by emartine ### ########.fr */
/* */
/* ************************************************************************** */
#include "twenty_one_sh.h"
int get_return_status(int status)
{
if (WIFEXITED(status))
return (WEXITSTATUS(status));
else if (WIFSIGNALED(status))
return (128 + WTERMSIG(status));
else if (WIFSTOPPED(status))
return (256 + WSTOPSIG(status));
return (1);
}
static void wait_job_loop(t_proc *proc, int *status, pid_t wpid, t_proc *cur)
{
while (proc->job->running > 0 && (wpid = waitpid(WAIT_ANY, status,
WUNTRACED)) >= 0)
{
if (WIFSTOPPED(*status))
{
kill(wpid, SIGTERM);
kill(wpid, SIGCONT);
continue ;
}
cur = proc->job->head_proc;
while (cur)
{
if (wpid == cur->pid)
{
proc->job->running--;
if (!cur->next)
g_shell.exit_code = get_return_status(*status);
break ;
}
cur = cur->next;
}
*status = 0;
}
}
void wait_job(t_proc *proc)
{
int status;
if (proc->next)
return ;
tcsetpgrp(g_shell.term, proc->job->pgid);
status = 0;
wait_job_loop(proc, &status, 0, NULL);
tcsetpgrp(g_shell.term, g_shell.pgid);
tcgetattr(g_shell.term, &proc->job->tmodes);
cooked_terminal();
}
Carregando…
Cancelar
Salvar