mostly compile-time error fixing
This commit is contained in:
parent
e3b344bbb9
commit
fc53e40a4f
34 changed files with 257 additions and 172 deletions
|
|
@ -67,6 +67,7 @@ int launch_process(t_process *p);
|
||||||
int process_setexec(t_process *p);
|
int process_setexec(t_process *p);
|
||||||
int process_setgroup(t_process *p);
|
int process_setgroup(t_process *p);
|
||||||
int process_redirect(t_process *p);
|
int process_redirect(t_process *p);
|
||||||
|
void process_free(void *content, size_t content_size);
|
||||||
|
|
||||||
void fd_redirect(void);
|
void fd_redirect(void);
|
||||||
void fd_reset(void);
|
void fd_reset(void);
|
||||||
|
|
|
||||||
|
|
@ -14,24 +14,29 @@
|
||||||
# define JOB_CONTROL_H
|
# define JOB_CONTROL_H
|
||||||
|
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
# include <sys/wait.h>
|
||||||
# include <termios.h>
|
# include <termios.h>
|
||||||
# include "libft.h"
|
# include "libft.h"
|
||||||
# include "types.h"
|
# include "types.h"
|
||||||
# include "exec.h"
|
|
||||||
|
|
||||||
# define PROCESS_COMPLETED 1 << 0
|
# define PROCESS_COMPLETED (1 << 0)
|
||||||
# define PROCESS_STOPED 1 << 1
|
# define PROCESS_STOPPED (1 << 1)
|
||||||
# define PROCESS_BUILTIN 1 << 2
|
# define PROCESS_BUILTIN (1 << 2)
|
||||||
# define PROCESS_BINARY 1 << 3
|
# define PROCESS_BINARY (1 << 3)
|
||||||
# define PROCESS_SCRIPT 1 << 4
|
# define PROCESS_SCRIPT (1 << 4)
|
||||||
# define PROCESS_UNKNOWN 1 << 5
|
# define PROCESS_UNKNOWN (1 << 5)
|
||||||
|
|
||||||
|
# define JOB_NOTIFIED (1 << 0)
|
||||||
|
# define JOB_BG (1 << 1)
|
||||||
|
# define JOB_IS_BG(j) (j & JOB_BG)
|
||||||
|
# define JOB_IS_FG(j) !(j & JOB_BG)
|
||||||
|
|
||||||
|
|
||||||
struct s_job
|
struct s_job
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
pid_t pgid;
|
pid_t pgid;
|
||||||
char notified;
|
t_flag attributes;
|
||||||
int foreground;
|
|
||||||
t_list *first_process;
|
t_list *first_process;
|
||||||
struct termios tmodes;
|
struct termios tmodes;
|
||||||
};
|
};
|
||||||
|
|
@ -45,12 +50,20 @@ struct s_jobc
|
||||||
struct termios shell_tmodes;
|
struct termios shell_tmodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
int job_addprocess(t_process *p);
|
# include "exec.h"
|
||||||
void job_update_id(void);
|
|
||||||
void job_print_change(t_job *job, int status);
|
|
||||||
void job_update_rank(void);
|
|
||||||
|
|
||||||
void job_new(char **av, pid_t pid);
|
t_process *job_getprocess(pid_t pid);
|
||||||
|
int job_addprocess(t_process *p);
|
||||||
|
void job_update_id(void);
|
||||||
|
void job_print_change(t_job *job, int status);
|
||||||
|
void job_update_rank(void);
|
||||||
|
void job_notify_new(t_job *job);
|
||||||
|
int job_wait(t_job *job);
|
||||||
|
|
||||||
|
int put_job_in_foreground(t_job *job, int cont);
|
||||||
|
int put_job_in_background(t_job *job, int cont);
|
||||||
|
|
||||||
|
void job_new(char **av, pid_t pid);
|
||||||
|
|
||||||
void job_free(void *content, size_t content_size);
|
void job_free(void *content, size_t content_size);
|
||||||
int job_cmp_pid(t_job *job, pid_t *pid);
|
int job_cmp_pid(t_job *job, pid_t *pid);
|
||||||
|
|
@ -62,4 +75,6 @@ void sigchld_handler(int signo);
|
||||||
void sigint_handler(int signo);
|
void sigint_handler(int signo);
|
||||||
void sigtstp_handler(int signo);
|
void sigtstp_handler(int signo);
|
||||||
|
|
||||||
|
int process_cmp_pid(t_process *p, pid_t *pid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,6 @@
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
|
|
||||||
typedef long long t_type;
|
|
||||||
typedef struct s_line t_line;
|
|
||||||
typedef struct s_comp t_comp;
|
|
||||||
typedef struct s_exec t_exec;
|
|
||||||
typedef struct s_jobc t_jobc;
|
|
||||||
typedef enum e_mode t_mode;
|
|
||||||
|
|
||||||
enum e_mode
|
enum e_mode
|
||||||
{
|
{
|
||||||
|
|
@ -66,20 +60,15 @@ struct s_data
|
||||||
t_jobc jobc;
|
t_jobc jobc;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct s_data t_data;
|
|
||||||
typedef enum e_qstate t_qstate;
|
|
||||||
|
|
||||||
extern t_stof g_builtins[];
|
extern t_stof g_builtins[];
|
||||||
extern pid_t g_pid;
|
extern pid_t g_pid;
|
||||||
|
|
||||||
t_data *data_singleton();
|
|
||||||
|
|
||||||
void shell_init(void);
|
void shell_init(void);
|
||||||
void shell_exit(void);
|
void shell_exit(void);
|
||||||
int data_init(void);
|
int data_init(void);
|
||||||
void data_exit(void);
|
void data_exit(void);
|
||||||
|
|
||||||
|
|
||||||
void ft_expand_dollar(char **av, char **env);
|
void ft_expand_dollar(char **av, char **env);
|
||||||
char *ft_findexec(char *path, char *file);
|
char *ft_findexec(char *path, char *file);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
#ifndef TYPES_H
|
#ifndef TYPES_H
|
||||||
# define TYPES_H
|
# define TYPES_H
|
||||||
|
|
||||||
|
typedef long long t_type;
|
||||||
|
typedef struct s_line t_line;
|
||||||
|
typedef struct s_comp t_comp;
|
||||||
|
typedef struct s_exec t_exec;
|
||||||
|
typedef struct s_jobc t_jobc;
|
||||||
|
typedef enum e_mode t_mode;
|
||||||
|
|
||||||
|
typedef struct s_data t_data;
|
||||||
|
typedef enum e_qstate t_qstate;
|
||||||
|
|
||||||
typedef struct s_job t_job;
|
typedef struct s_job t_job;
|
||||||
typedef struct s_jobc t_jobc;
|
typedef struct s_jobc t_jobc;
|
||||||
typedef struct s_execmap t_execmap;
|
typedef struct s_execmap t_execmap;
|
||||||
|
|
@ -21,4 +31,6 @@ typedef long long t_type;
|
||||||
typedef long long t_flag;
|
typedef long long t_flag;
|
||||||
typedef int (t_execf)(const char *path, char *const argv[], char *const envp[]);
|
typedef int (t_execf)(const char *path, char *const argv[], char *const envp[]);
|
||||||
|
|
||||||
|
t_data *data_singleton();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,34 +12,38 @@
|
||||||
|
|
||||||
#include "minishell.h"
|
#include "minishell.h"
|
||||||
|
|
||||||
int builtin_setenv(char **av, t_data *data)
|
int builtin_setenv(const char *path, char *const av[], char *const envp[])
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
char **env;
|
char ***env;
|
||||||
|
int i;
|
||||||
|
|
||||||
env = data->env;
|
(void)envp;
|
||||||
|
(void)path;
|
||||||
|
i = 0;
|
||||||
|
env = &data_singleton()->env;
|
||||||
DG("doing setenv now");
|
DG("doing setenv now");
|
||||||
if (ft_strcmp(av[0], "setenv") == 0)
|
if (ft_strcmp(av[0], "setenv") == 0)
|
||||||
av++;
|
av++;
|
||||||
if (!av[0])
|
if (!av[0])
|
||||||
{
|
{
|
||||||
ft_sstrprint(data->env, '\n');
|
ft_sstrprint(*env, '\n');
|
||||||
ft_putchar('\n');
|
ft_putchar('\n');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str = ft_str3join(av[0], "=", av[1]);
|
str = ft_str3join(av[0], "=", av[1]);
|
||||||
while (*env)
|
while ((*env)[i])
|
||||||
{
|
{
|
||||||
if (ft_strcmp(*env, av[0]) == '=')
|
if (ft_strcmp((*env)[i], av[0]) == '=')
|
||||||
{
|
{
|
||||||
ft_strdel(env);
|
ft_strdel(*env);
|
||||||
*env = str;
|
(*env)[i] = str;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
env++;
|
i++;
|
||||||
}
|
}
|
||||||
data->env = ft_sstradd(data->env, str);
|
*env = ft_sstradd(*env, str);
|
||||||
ft_strdel(&str);
|
ft_strdel(&str);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
||||||
|
|
@ -12,21 +12,23 @@
|
||||||
|
|
||||||
#include "minishell.h"
|
#include "minishell.h"
|
||||||
|
|
||||||
int builtin_unsetenv(char **av, t_data *data)
|
int builtin_unsetenv(const char *path, char *const av[], char *const envp[])
|
||||||
{
|
{
|
||||||
char **env;
|
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
char ***env;
|
||||||
|
|
||||||
env = data->env;
|
(void)envp;
|
||||||
|
(void)path;
|
||||||
|
env = &data_singleton()->env;
|
||||||
i = 1;
|
i = 1;
|
||||||
while (av[i])
|
while (av[i])
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
while (env[j])
|
while ((*env)[j])
|
||||||
{
|
{
|
||||||
if (ft_strcmp(env[j], av[i]) == '=')
|
if (ft_strcmp((*env)[j], av[i]) == '=')
|
||||||
ft_sstrdel(env, j);
|
ft_sstrdel(*env, j);
|
||||||
else
|
else
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
int exec_ampersand(t_btree **ast)
|
int exec_ampersand(t_btree **ast)
|
||||||
{
|
{
|
||||||
data_singleton()->exec.job.foreground = 1;
|
data_singleton()->exec.job.attributes |= JOB_BG;
|
||||||
ft_exec(&(*ast)->left);
|
ft_exec(&(*ast)->left);
|
||||||
data_singleton()->exec.job.foreground = 0;
|
data_singleton()->exec.job.attributes &= ~JOB_BG;
|
||||||
ft_exec(&(*ast)->right);
|
ft_exec(&(*ast)->right);
|
||||||
btree_delone(ast, &ast_free);
|
btree_delone(ast, &ast_free);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,25 @@
|
||||||
int exec_command(t_btree **ast)
|
int exec_command(t_btree **ast)
|
||||||
{
|
{
|
||||||
t_astnode *node;
|
t_astnode *node;
|
||||||
t_process *process;
|
t_process *p;
|
||||||
t_job *job;
|
t_job *job;
|
||||||
|
|
||||||
node = (*ast)->item;
|
node = (*ast)->item;
|
||||||
process = &data_singleton()->exec.process;
|
p = &data_singleton()->exec.process;
|
||||||
job = &data_singleton()->exec.job;
|
job = &data_singleton()->exec.job;
|
||||||
process->argv = ft_sstrdup(node->data.sstr);
|
p->argv = ft_sstrdup(node->data.sstr);
|
||||||
DG("gonna launch_process");
|
DG("gonna launch_process");
|
||||||
process_setexec(process);
|
DG("job attr=%i", job->attributes);
|
||||||
launch_process(process);
|
process_setexec(p);
|
||||||
job_addprocess(process);
|
launch_process(p);
|
||||||
|
if (p->fdout == STDOUT)
|
||||||
|
{
|
||||||
|
if (JOB_IS_FG(job->attributes))
|
||||||
|
put_job_in_foreground(job, 0);
|
||||||
|
else
|
||||||
|
put_job_in_background(job, 0);
|
||||||
|
}
|
||||||
|
job_addprocess(p);
|
||||||
btree_delone(ast, &ast_free);
|
btree_delone(ast, &ast_free);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ int launch_process(t_process *p)
|
||||||
exec = &data_singleton()->exec;
|
exec = &data_singleton()->exec;
|
||||||
if (p->attributes & PROCESS_UNKNOWN)
|
if (p->attributes & PROCESS_UNKNOWN)
|
||||||
ft_dprintf(2, "%s: command not found: %s\n", SHELL_NAME, p->argv[0]);
|
ft_dprintf(2, "%s: command not found: %s\n", SHELL_NAME, p->argv[0]);
|
||||||
if (p->attributes & PROCESS_BUILTIN && p->fdout != STDOUT)
|
else if (p->attributes & PROCESS_BUILTIN && p->fdout != STDOUT)
|
||||||
set_exitstatus((*p->execf)(p->path, p->argv, data_singleton()->env));
|
set_exitstatus((*p->execf)(p->path, p->argv, data_singleton()->env));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,27 @@
|
||||||
int process_setexec(t_process *p)
|
int process_setexec(t_process *p)
|
||||||
{
|
{
|
||||||
if ((p->execf = is_builtin(p)))
|
if ((p->execf = is_builtin(p)))
|
||||||
|
{
|
||||||
|
DG("process is a builtin");
|
||||||
p->attributes &= PROCESS_BUILTIN;
|
p->attributes &= PROCESS_BUILTIN;
|
||||||
|
}
|
||||||
else if (ft_strchr(p->argv[0], '/'))
|
else if (ft_strchr(p->argv[0], '/'))
|
||||||
{
|
{
|
||||||
|
DG("process is a script");
|
||||||
p->execf = &execve;
|
p->execf = &execve;
|
||||||
p->attributes &= PROCESS_SCRIPT;
|
p->attributes &= PROCESS_SCRIPT;
|
||||||
p->path = ft_strdup(p->argv[0]);
|
p->path = ft_strdup(p->argv[0]);
|
||||||
}
|
}
|
||||||
else if (!(p->path = ft_findexec(ft_getenv(
|
else if ((p->path = ft_findexec(ft_getenv(
|
||||||
data_singleton()->env, "PATH"), p->argv[0])))
|
data_singleton()->env, "PATH"), p->argv[0])))
|
||||||
{
|
{
|
||||||
|
DG("process is binary");
|
||||||
p->execf = &execve;
|
p->execf = &execve;
|
||||||
p->attributes &= PROCESS_BINARY;
|
p->attributes &= PROCESS_BINARY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DG("process is unknown type");
|
||||||
p->execf = NULL;
|
p->execf = NULL;
|
||||||
p->attributes &= PROCESS_UNKNOWN;
|
p->attributes &= PROCESS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,20 @@
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "job_control.h"
|
#include "job_control.h"
|
||||||
|
#include "exec.h"
|
||||||
|
|
||||||
int process_setgroup(t_process *p)
|
int process_setgroup(t_process *p)
|
||||||
{
|
{
|
||||||
t_job *job;
|
t_job *job;
|
||||||
|
int pid;
|
||||||
|
|
||||||
job = data_singleton()->exec.job;
|
(void)p;
|
||||||
|
job = &data_singleton()->exec.job;
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
if (job->pgid == 0)
|
if (job->pgid == 0)
|
||||||
job->pgid = pid;
|
job->pgid = pid;
|
||||||
setpgid(pid, job->pgid);
|
setpgid(pid, job->pgid);
|
||||||
if (job->foreground)
|
if (JOB_IS_FG(job->attributes))
|
||||||
tcsetpgrp(STDIN_FILENO, job->pgid);
|
tcsetpgrp(STDIN_FILENO, job->pgid);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,6 @@ void set_exitstatus(int status)
|
||||||
char *astatus;
|
char *astatus;
|
||||||
|
|
||||||
astatus = ft_itoa(status);
|
astatus = ft_itoa(status);
|
||||||
builtin_setenv((char*[3]){"?", astatus}, data_singleton());
|
builtin_setenv("shell", (char*[3]){"?", astatus}, data_singleton()->env);
|
||||||
ft_strdel(&astatus);
|
ft_strdel(&astatus);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,26 +14,26 @@
|
||||||
|
|
||||||
int check_chlds()
|
int check_chlds()
|
||||||
{
|
{
|
||||||
int status;
|
/* int status; */
|
||||||
pid_t pid;
|
/* pid_t pid; */
|
||||||
t_job *job;
|
/* t_job *job; */
|
||||||
t_list **start;
|
/* t_list **start; */
|
||||||
t_list *list;
|
/* t_list *list; */
|
||||||
|
|
||||||
DG("gonna check childs");
|
/* DG("gonna check childs"); */
|
||||||
start = &data_singleton()->jobc.list;
|
/* start = &data_singleton()->jobc.list; */
|
||||||
pid = waitpid(-1, &status, WNOHANG);
|
/* pid = waitpid(-1, &status, WNOHANG); */
|
||||||
DG("waitpid = %i", pid);
|
/* DG("waitpid = %i", pid); */
|
||||||
list = *start ? ft_lst_find(*start, &pid, job_cmp_pid) : NULL;
|
/* list = *start ? ft_lst_find(*start, &pid, job_cmp_pid) : NULL; */
|
||||||
if (list)
|
/* if (list) */
|
||||||
{
|
/* { */
|
||||||
job = list->content;
|
/* job = list->content; */
|
||||||
if (job->id < data_singleton()->jobc.current_id)
|
/* if (job->id < data_singleton()->jobc.current_id) */
|
||||||
data_singleton()->jobc.current_id = job->id;
|
/* data_singleton()->jobc.current_id = job->id; */
|
||||||
job_print_change(job, status);
|
/* job_print_change(job, status); */
|
||||||
ft_lst_delif(start, list->content, ft_addrcmp, job_free);
|
/* ft_lst_delif(start, list->content, ft_addrcmp, job_free); */
|
||||||
job_update_rank();
|
/* job_update_rank(); */
|
||||||
return (1);
|
/* return (1); */
|
||||||
}
|
/* } */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,17 @@ int job_addprocess(t_process *p)
|
||||||
|
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
job = &data_singleton()->exec.job;
|
job = &data_singleton()->exec.job;
|
||||||
if (p->fdin == STDIN)
|
if (JOB_IS_BG(job->attributes) && p->fdin == STDIN)
|
||||||
{
|
{
|
||||||
job->id = current_id;
|
|
||||||
job_update_id();
|
job_update_id();
|
||||||
|
job->id = jobc->current_id;
|
||||||
ft_lstadd(&jobc->first_job, ft_lstnew(job, sizeof(*job)));
|
ft_lstadd(&jobc->first_job, ft_lstnew(job, sizeof(*job)));
|
||||||
if (job->foreground)
|
jobc->rank[1] = jobc->rank[0];
|
||||||
put_job_in_foreground(job, 0);
|
jobc->rank[0] = job->id;
|
||||||
else
|
|
||||||
put_job_in_background(job, 0);
|
|
||||||
}
|
}
|
||||||
if (p->fdout = STDOUT)
|
job = jobc->first_job->content;
|
||||||
job_notify_new(first_job);
|
if (JOB_IS_BG(job->attributes) && p->fdout == STDOUT)
|
||||||
first_job = jobc->first_job->content;
|
job_notify_new(job);
|
||||||
ft_lstadd(first_job->process, ft_lstnew(p, sizeof(*p)));
|
ft_lstadd(&job->first_process, ft_lstnew(p, sizeof(*p)));
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@ void job_free(void *content, size_t content_size)
|
||||||
|
|
||||||
(void)content_size;
|
(void)content_size;
|
||||||
job = content;
|
job = content;
|
||||||
ft_strdel(&job->command);
|
ft_lstdel(&job->first_process, &process_free);
|
||||||
free(job);
|
free(job);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
42sh/src/job-control/job_getprocess.c
Normal file
20
42sh/src/job-control/job_getprocess.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "job_control.h"
|
||||||
|
|
||||||
|
t_process *job_getprocess(pid_t pid)
|
||||||
|
{
|
||||||
|
t_jobc *jobc;
|
||||||
|
t_job *j;
|
||||||
|
t_list *lst;
|
||||||
|
t_list *jlist;
|
||||||
|
|
||||||
|
jobc = &data_singleton()->jobc;
|
||||||
|
jlist = jobc->first_job;
|
||||||
|
while (jlist)
|
||||||
|
{
|
||||||
|
j = jlist->content;
|
||||||
|
if ((lst = ft_lst_find(j->first_process, &pid, &process_cmp_pid)))
|
||||||
|
return (lst->content);
|
||||||
|
jlist = jlist->next;
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
int job_is_completed(t_job *job)
|
int job_is_completed(t_job *job)
|
||||||
{
|
{
|
||||||
t_list *lst;
|
t_list *lst;
|
||||||
t_process *process;
|
t_process *p;
|
||||||
|
|
||||||
lst = job->lst;
|
lst = job->first_process;
|
||||||
while (lst)
|
while (lst)
|
||||||
{
|
{
|
||||||
process = lst->content;
|
p = lst->content;
|
||||||
if (!(process->attributes & PROCESS_COMPLETED))
|
if (!(p->attributes & PROCESS_COMPLETED))
|
||||||
return (0);
|
return (0);
|
||||||
lst = lst->next;
|
lst = lst->next;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
int job_is_stopped(t_job *job)
|
int job_is_stopped(t_job *job)
|
||||||
{
|
{
|
||||||
t_list *lst;
|
t_list *lst;
|
||||||
t_process *process;
|
t_process *p;
|
||||||
|
|
||||||
lst = job->lst;
|
lst = job->first_process;
|
||||||
while (lst)
|
while (lst)
|
||||||
{
|
{
|
||||||
process = lst->content;
|
p = lst->content;
|
||||||
if (!(process->attributes & (PROCESS_COMPLETED | PROCESS_STOPPED)))
|
if (!(p->attributes & (PROCESS_COMPLETED | PROCESS_STOPPED)))
|
||||||
return (0);
|
return (0);
|
||||||
lst = lst->next;
|
lst = lst->next;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* job_new.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2016/12/10 16:51:54 by jhalford #+# #+# */
|
|
||||||
/* Updated: 2016/12/13 11:53:11 by jhalford ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "job_control.h"
|
|
||||||
|
|
||||||
void job_new(char **av, pid_t pid)
|
|
||||||
{
|
|
||||||
t_job job;
|
|
||||||
t_data *data;
|
|
||||||
|
|
||||||
data = data_singleton();
|
|
||||||
DG("got new job");
|
|
||||||
if (data->mode == MODE_INPUT)
|
|
||||||
DG("am in MODE_INPUT");
|
|
||||||
else if (data->mode == MODE_EXEC)
|
|
||||||
DG("am in MODE_EXEC");
|
|
||||||
job.command = ft_sstrcat(av, ' ');
|
|
||||||
DG("job command '%s'", job.command);
|
|
||||||
job.pid = pid;
|
|
||||||
job_update_id();
|
|
||||||
DG("id = %i", data->jobc.current_id);
|
|
||||||
job.id = data->jobc.current_id;
|
|
||||||
data->jobc.rank[1] = data->jobc.rank[0];
|
|
||||||
data->jobc.rank[0] = job.id;
|
|
||||||
ft_lstadd(&data->jobc.list, ft_lstnew(&job, sizeof(job)));
|
|
||||||
job_announce(data->jobc.list->content);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* job_print_change.c :+: :+: :+: */
|
/* job_notify_change.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "minishell.h"
|
#include "minishell.h"
|
||||||
|
|
||||||
void job_print_change(t_job *job, int status)
|
void job_notify_change(t_job *job, int status)
|
||||||
{
|
{
|
||||||
char rank;
|
char rank;
|
||||||
|
|
||||||
|
|
@ -21,12 +21,12 @@ void job_print_change(t_job *job, int status)
|
||||||
rank = '+';
|
rank = '+';
|
||||||
else if (job->id == data_singleton()->jobc.rank[1])
|
else if (job->id == data_singleton()->jobc.rank[1])
|
||||||
rank = '-';
|
rank = '-';
|
||||||
ft_printf("{mag}[%i] %c %i ", job->id, rank, job->pid);
|
ft_printf("{mag}[%i] %c ", job->id, rank);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
ft_printf("{gre}done{mag}");
|
ft_printf("{gre}done{mag}");
|
||||||
else if (status == 9)
|
else if (status == 9)
|
||||||
ft_printf("{red}killed{mag}");
|
ft_printf("{red}killed{mag}");
|
||||||
else
|
else
|
||||||
ft_printf("exit %i", status);
|
ft_printf("exit %i", status);
|
||||||
ft_printf("\t%s{eoc}\n", job->command);
|
/* ft_printf("\t%s{eoc}\n", job->command); */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ void job_notify_new(t_job *job)
|
||||||
{
|
{
|
||||||
t_list *process;
|
t_list *process;
|
||||||
|
|
||||||
process = job->first_process;
|
|
||||||
ft_printf("{mag}[%i]", job->id);
|
ft_printf("{mag}[%i]", job->id);
|
||||||
|
process = job->first_process;
|
||||||
while (process)
|
while (process)
|
||||||
{
|
{
|
||||||
ft_printf(" %i", ((t_process*)process->content)->pid);
|
ft_printf(" %i", ((t_process*)process->content)->pid);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ void job_update_id(void)
|
||||||
|
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
id = &jobc->current_id;
|
id = &jobc->current_id;
|
||||||
start = jobc->list;
|
start = jobc->first_job;
|
||||||
while (ft_lst_find(start, id, job_cmp_id))
|
while (ft_lst_find(start, id, job_cmp_id))
|
||||||
{
|
{
|
||||||
*id += 1;
|
*id += 1;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ void job_update_rank()
|
||||||
t_list *list;
|
t_list *list;
|
||||||
|
|
||||||
jobc = &data_singleton()->jobc;
|
jobc = &data_singleton()->jobc;
|
||||||
list = jobc->list;
|
list = jobc->first_job;
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
job = list->content;
|
job = list->content;
|
||||||
|
|
|
||||||
7
42sh/src/job-control/job_wait.c
Normal file
7
42sh/src/job-control/job_wait.c
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "job_control.h"
|
||||||
|
|
||||||
|
int job_wait(t_job *job)
|
||||||
|
{
|
||||||
|
(void)job;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* job_cmp_pid.c :+: :+: :+: */
|
/* process_cmp_pid.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "minishell.h"
|
#include "minishell.h"
|
||||||
|
|
||||||
int job_cmp_pid(t_job *job, pid_t *pid)
|
int process_cmp_pid(t_process *p, pid_t *pid)
|
||||||
{
|
{
|
||||||
return (job->pid - *pid);
|
return (p->pid - *pid);
|
||||||
}
|
}
|
||||||
24
42sh/src/job-control/process_free.c
Normal file
24
42sh/src/job-control/process_free.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* process_free.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2016/12/12 13:02:05 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "job_control.h"
|
||||||
|
|
||||||
|
void process_free(void *content, size_t content_size)
|
||||||
|
{
|
||||||
|
t_process *p;
|
||||||
|
|
||||||
|
(void)content_size;
|
||||||
|
p = content;
|
||||||
|
ft_strdel(&p->path);
|
||||||
|
ft_sstrfree(p->argv);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
42
42sh/src/job-control/process_mark_status.c
Normal file
42
42sh/src/job-control/process_mark_status.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* process_mark_status.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2016/12/12 13:02:05 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "job_control.h"
|
||||||
|
|
||||||
|
int process_mark_status(pid_t pid, int status)
|
||||||
|
{
|
||||||
|
t_process *p;
|
||||||
|
t_jobc *jobc;
|
||||||
|
|
||||||
|
jobc = &data_singleton()->jobc;
|
||||||
|
if (pid > 0)
|
||||||
|
{
|
||||||
|
if ((p = job_getprocess(pid)))
|
||||||
|
{
|
||||||
|
p->status = status;
|
||||||
|
if (WIFSTOPPED(status))
|
||||||
|
p->attributes &= PROCESS_STOPPED;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->attributes &= PROCESS_COMPLETED;
|
||||||
|
if (WIFSIGNALED(status))
|
||||||
|
ft_printf("%d: Terminated by signal %d.\n",
|
||||||
|
(int) pid, WTERMSIG (p->status));
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
ft_dprintf(STDERR, "No child process %d.\n", pid);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@ int put_job_in_background(t_job *job, int cont)
|
||||||
{
|
{
|
||||||
/* Send the job a continue signal, if necessary. */
|
/* Send the job a continue signal, if necessary. */
|
||||||
if (cont)
|
if (cont)
|
||||||
if (kill (-j->pgid, SIGCONT) < 0)
|
if (kill (-job->pgid, SIGCONT) < 0)
|
||||||
perror ("kill (SIGCONT)");
|
perror ("kill (SIGCONT)");
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,22 +16,24 @@ int put_job_in_foreground(t_job *job, int cont)
|
||||||
{
|
{
|
||||||
t_jobc *jobc;
|
t_jobc *jobc;
|
||||||
|
|
||||||
|
jobc = &data_singleton()->jobc;
|
||||||
/* Put the job into the foreground. */
|
/* Put the job into the foreground. */
|
||||||
tcsetpgrp(shell_terminal, job->pgid);
|
tcsetpgrp(STDIN_FILENO, job->pgid);
|
||||||
/* Send the job a continue signal, if necessary. */
|
/* Send the job a continue signal, if necessary. */
|
||||||
if (cont)
|
if (cont)
|
||||||
{
|
{
|
||||||
tcsetattr (shell_terminal, TCSADRAIN, &job->tmodes);
|
tcsetattr (STDIN_FILENO, TCSADRAIN, &job->tmodes);
|
||||||
if (kill(- job->pgid, SIGCONT) < 0)
|
if (kill(- job->pgid, SIGCONT) < 0)
|
||||||
perror("kill (SIGCONT)");
|
perror("kill (SIGCONT)");
|
||||||
}
|
}
|
||||||
/* Wait for it to report. */
|
/* Wait for it to report. */
|
||||||
wait_for_job(j);
|
job_wait(job);
|
||||||
|
|
||||||
/* Put the shell back in the foreground. */
|
/* Put the shell back in the foreground. */
|
||||||
tcsetpgrp(shell_terminal, jobc->shell_pgid);
|
tcsetpgrp(STDIN_FILENO, jobc->shell_pgid);
|
||||||
|
|
||||||
/* Restore the shell’s terminal modes. */
|
/* Restore the shell’s terminal modes. */
|
||||||
tcgetattr(shell_terminal, &job->tmodes);
|
tcgetattr(STDIN_FILENO, &job->tmodes);
|
||||||
tcsetattr(shell_terminal, TCSADRAIN, &jobc->shell_tmodes);
|
tcsetattr(STDIN_FILENO, TCSADRAIN, &jobc->shell_tmodes);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,5 @@ void sigchld_handler(int signo)
|
||||||
|
|
||||||
(void)signo;
|
(void)signo;
|
||||||
data = data_singleton();
|
data = data_singleton();
|
||||||
if (data->mode == MODE_INPUT)
|
DG("got asynchronous notification (SIGCHLD)");
|
||||||
{
|
|
||||||
DG("got SIGCHLD in MODE_INPUT (asynchronos notification)");
|
|
||||||
check_chlds();
|
|
||||||
ft_putstr(SHELL_PROMPT);
|
|
||||||
ft_putstr(data->line.input);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DG("got SIGCHLD in MODE_EXEC, will check before next prompt");
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,6 @@ int ft_prompt(void)
|
||||||
t_data *data;
|
t_data *data;
|
||||||
|
|
||||||
data = data_singleton();
|
data = data_singleton();
|
||||||
while (data->jobc.list)
|
|
||||||
{
|
|
||||||
/* usleep(500 * 1000); */
|
|
||||||
if (check_chlds())
|
|
||||||
continue ;
|
|
||||||
else
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
ft_putstr(SHELL_PROMPT);
|
ft_putstr(SHELL_PROMPT);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,19 @@ int data_init(void)
|
||||||
data->line.input = NULL;
|
data->line.input = NULL;
|
||||||
data->env = ft_sstrdup(environ);
|
data->env = ft_sstrdup(environ);
|
||||||
data->line.history = NULL;
|
data->line.history = NULL;
|
||||||
data->exec.fdin = STDIN;
|
data->exec.process.fdin = STDIN;
|
||||||
data->exec.fdout = STDOUT;
|
data->exec.process.fdout = STDOUT;
|
||||||
|
data->exec.process.pid = 0;
|
||||||
data->exec.aol_status = NULL;
|
data->exec.aol_status = NULL;
|
||||||
data->exec.aol_search = 0;
|
data->exec.aol_search = 0;
|
||||||
data->exec.amp = 0;
|
data->exec.job.id = 0;
|
||||||
data->jobc.list = NULL;
|
data->exec.job.pgid = 0;
|
||||||
|
data->exec.job.attributes = 0;
|
||||||
|
data->exec.job.first_process = 0;
|
||||||
|
data->jobc.first_job = NULL;
|
||||||
data->jobc.current_id = 1;
|
data->jobc.current_id = 1;
|
||||||
data->jobc.rank[0] = 0;
|
data->jobc.rank[0] = 0;
|
||||||
data->jobc.rank[1] = 0;
|
data->jobc.rank[1] = 0;
|
||||||
data->jobc.job.id = 0;
|
|
||||||
data->jobc.job.pgid = 0;
|
|
||||||
data->jobc.job.notified = 0;
|
|
||||||
data->jobc.job.foreground = 0;
|
|
||||||
if (!(data->line.history = ft_dlstnew(NULL, 0)))
|
if (!(data->line.history = ft_dlstnew(NULL, 0)))
|
||||||
return (-1);
|
return (-1);
|
||||||
if ((term_name = ft_getenv(data->env, "TERM")) == NULL)
|
if ((term_name = ft_getenv(data->env, "TERM")) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ int main(void)
|
||||||
/* btree_apply_infix(ast, &ft_putast2); */
|
/* btree_apply_infix(ast, &ft_putast2); */
|
||||||
if (ft_exec(&ast))
|
if (ft_exec(&ast))
|
||||||
return (1);
|
return (1);
|
||||||
|
DG("end of loop");
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ void shell_init(void)
|
||||||
if (isatty(STDIN_FILENO))
|
if (isatty(STDIN_FILENO))
|
||||||
{
|
{
|
||||||
while (tcgetpgrp(STDIN_FILENO) != (*shell_pgid = getpgrp()))
|
while (tcgetpgrp(STDIN_FILENO) != (*shell_pgid = getpgrp()))
|
||||||
kill(*shell_pgid, SIGTTIN);
|
kill(-*shell_pgid, SIGTTIN);
|
||||||
signal(SIGINT, sigint_handler);
|
signal(SIGINT, sigint_handler);
|
||||||
signal(SIGQUIT, SIG_IGN);
|
signal(SIGQUIT, SIG_IGN);
|
||||||
signal(SIGTSTP, sigtstp_handler);
|
signal(SIGTSTP, sigtstp_handler);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue