mostly compile-time error fixing

This commit is contained in:
Jack Halford 2016-12-14 23:26:29 +01:00
parent e3b344bbb9
commit fc53e40a4f
34 changed files with 257 additions and 172 deletions

View file

@ -67,6 +67,7 @@ int launch_process(t_process *p);
int process_setexec(t_process *p);
int process_setgroup(t_process *p);
int process_redirect(t_process *p);
void process_free(void *content, size_t content_size);
void fd_redirect(void);
void fd_reset(void);

View file

@ -14,24 +14,29 @@
# define JOB_CONTROL_H
# include <sys/types.h>
# include <sys/wait.h>
# include <termios.h>
# include "libft.h"
# include "types.h"
# include "exec.h"
# define PROCESS_COMPLETED 1 << 0
# define PROCESS_STOPED 1 << 1
# define PROCESS_BUILTIN 1 << 2
# define PROCESS_BINARY 1 << 3
# define PROCESS_SCRIPT 1 << 4
# define PROCESS_UNKNOWN 1 << 5
# define PROCESS_COMPLETED (1 << 0)
# define PROCESS_STOPPED (1 << 1)
# define PROCESS_BUILTIN (1 << 2)
# define PROCESS_BINARY (1 << 3)
# define PROCESS_SCRIPT (1 << 4)
# 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
{
int id;
pid_t pgid;
char notified;
int foreground;
t_flag attributes;
t_list *first_process;
struct termios tmodes;
};
@ -45,12 +50,20 @@ struct s_jobc
struct termios shell_tmodes;
};
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);
# include "exec.h"
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);
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 sigtstp_handler(int signo);
int process_cmp_pid(t_process *p, pid_t *pid);
#endif

View file

@ -30,12 +30,6 @@
# include <signal.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
{
@ -66,20 +60,15 @@ struct s_data
t_jobc jobc;
};
typedef struct s_data t_data;
typedef enum e_qstate t_qstate;
extern t_stof g_builtins[];
extern pid_t g_pid;
t_data *data_singleton();
void shell_init(void);
void shell_exit(void);
int data_init(void);
void data_exit(void);
void ft_expand_dollar(char **av, char **env);
char *ft_findexec(char *path, char *file);

View file

@ -13,6 +13,16 @@
#ifndef 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_jobc t_jobc;
typedef struct s_execmap t_execmap;
@ -21,4 +31,6 @@ typedef long long t_type;
typedef long long t_flag;
typedef int (t_execf)(const char *path, char *const argv[], char *const envp[]);
t_data *data_singleton();
#endif

View file

@ -12,34 +12,38 @@
#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 **env;
char ***env;
int i;
env = data->env;
(void)envp;
(void)path;
i = 0;
env = &data_singleton()->env;
DG("doing setenv now");
if (ft_strcmp(av[0], "setenv") == 0)
av++;
if (!av[0])
{
ft_sstrprint(data->env, '\n');
ft_sstrprint(*env, '\n');
ft_putchar('\n');
}
else
{
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);
*env = str;
ft_strdel(*env);
(*env)[i] = str;
return (0);
}
env++;
i++;
}
data->env = ft_sstradd(data->env, str);
*env = ft_sstradd(*env, str);
ft_strdel(&str);
}
return (0);

View file

@ -12,21 +12,23 @@
#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 j;
char ***env;
env = data->env;
(void)envp;
(void)path;
env = &data_singleton()->env;
i = 1;
while (av[i])
{
j = 0;
while (env[j])
while ((*env)[j])
{
if (ft_strcmp(env[j], av[i]) == '=')
ft_sstrdel(env, j);
if (ft_strcmp((*env)[j], av[i]) == '=')
ft_sstrdel(*env, j);
else
j++;
}

View file

@ -14,9 +14,9 @@
int exec_ampersand(t_btree **ast)
{
data_singleton()->exec.job.foreground = 1;
data_singleton()->exec.job.attributes |= JOB_BG;
ft_exec(&(*ast)->left);
data_singleton()->exec.job.foreground = 0;
data_singleton()->exec.job.attributes &= ~JOB_BG;
ft_exec(&(*ast)->right);
btree_delone(ast, &ast_free);
return (0);

View file

@ -15,17 +15,25 @@
int exec_command(t_btree **ast)
{
t_astnode *node;
t_process *process;
t_process *p;
t_job *job;
node = (*ast)->item;
process = &data_singleton()->exec.process;
p = &data_singleton()->exec.process;
job = &data_singleton()->exec.job;
process->argv = ft_sstrdup(node->data.sstr);
p->argv = ft_sstrdup(node->data.sstr);
DG("gonna launch_process");
process_setexec(process);
launch_process(process);
job_addprocess(process);
DG("job attr=%i", job->attributes);
process_setexec(p);
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);
return (0);
}

View file

@ -20,7 +20,7 @@ int launch_process(t_process *p)
exec = &data_singleton()->exec;
if (p->attributes & PROCESS_UNKNOWN)
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));
else
{

View file

@ -15,21 +15,27 @@
int process_setexec(t_process *p)
{
if ((p->execf = is_builtin(p)))
{
DG("process is a builtin");
p->attributes &= PROCESS_BUILTIN;
}
else if (ft_strchr(p->argv[0], '/'))
{
DG("process is a script");
p->execf = &execve;
p->attributes &= PROCESS_SCRIPT;
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])))
{
DG("process is binary");
p->execf = &execve;
p->attributes &= PROCESS_BINARY;
}
else
{
DG("process is unknown type");
p->execf = NULL;
p->attributes &= PROCESS_UNKNOWN;
}

View file

@ -11,16 +11,20 @@
/* ************************************************************************** */
#include "job_control.h"
#include "exec.h"
int process_setgroup(t_process *p)
{
t_job *job;
int pid;
job = data_singleton()->exec.job;
(void)p;
job = &data_singleton()->exec.job;
pid = getpid();
if (job->pgid == 0)
job->pgid = pid;
setpgid(pid, job->pgid);
if (job->foreground)
if (JOB_IS_FG(job->attributes))
tcsetpgrp(STDIN_FILENO, job->pgid);
return (0);
}

View file

@ -17,6 +17,6 @@ void set_exitstatus(int status)
char *astatus;
astatus = ft_itoa(status);
builtin_setenv((char*[3]){"?", astatus}, data_singleton());
builtin_setenv("shell", (char*[3]){"?", astatus}, data_singleton()->env);
ft_strdel(&astatus);
}

View file

@ -14,26 +14,26 @@
int check_chlds()
{
int status;
pid_t pid;
t_job *job;
t_list **start;
t_list *list;
/* int status; */
/* pid_t pid; */
/* t_job *job; */
/* t_list **start; */
/* t_list *list; */
DG("gonna check childs");
start = &data_singleton()->jobc.list;
pid = waitpid(-1, &status, WNOHANG);
DG("waitpid = %i", pid);
list = *start ? ft_lst_find(*start, &pid, job_cmp_pid) : NULL;
if (list)
{
job = list->content;
if (job->id < data_singleton()->jobc.current_id)
data_singleton()->jobc.current_id = job->id;
job_print_change(job, status);
ft_lst_delif(start, list->content, ft_addrcmp, job_free);
job_update_rank();
return (1);
}
/* DG("gonna check childs"); */
/* start = &data_singleton()->jobc.list; */
/* pid = waitpid(-1, &status, WNOHANG); */
/* DG("waitpid = %i", pid); */
/* list = *start ? ft_lst_find(*start, &pid, job_cmp_pid) : NULL; */
/* if (list) */
/* { */
/* job = list->content; */
/* if (job->id < data_singleton()->jobc.current_id) */
/* data_singleton()->jobc.current_id = job->id; */
/* job_print_change(job, status); */
/* ft_lst_delif(start, list->content, ft_addrcmp, job_free); */
/* job_update_rank(); */
/* return (1); */
/* } */
return (0);
}

View file

@ -19,18 +19,17 @@ int job_addprocess(t_process *p)
jobc = &data_singleton()->jobc;
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->id = jobc->current_id;
ft_lstadd(&jobc->first_job, ft_lstnew(job, sizeof(*job)));
if (job->foreground)
put_job_in_foreground(job, 0);
else
put_job_in_background(job, 0);
jobc->rank[1] = jobc->rank[0];
jobc->rank[0] = job->id;
}
if (p->fdout = STDOUT)
job_notify_new(first_job);
first_job = jobc->first_job->content;
ft_lstadd(first_job->process, ft_lstnew(p, sizeof(*p)));
job = jobc->first_job->content;
if (JOB_IS_BG(job->attributes) && p->fdout == STDOUT)
job_notify_new(job);
ft_lstadd(&job->first_process, ft_lstnew(p, sizeof(*p)));
return (0);
}

View file

@ -18,6 +18,6 @@ void job_free(void *content, size_t content_size)
(void)content_size;
job = content;
ft_strdel(&job->command);
ft_lstdel(&job->first_process, &process_free);
free(job);
}

View 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);
}

View file

@ -15,13 +15,13 @@
int job_is_completed(t_job *job)
{
t_list *lst;
t_process *process;
t_process *p;
lst = job->lst;
lst = job->first_process;
while (lst)
{
process = lst->content;
if (!(process->attributes & PROCESS_COMPLETED))
p = lst->content;
if (!(p->attributes & PROCESS_COMPLETED))
return (0);
lst = lst->next;
}

View file

@ -15,13 +15,13 @@
int job_is_stopped(t_job *job)
{
t_list *lst;
t_process *process;
t_process *p;
lst = job->lst;
lst = job->first_process;
while (lst)
{
process = lst->content;
if (!(process->attributes & (PROCESS_COMPLETED | PROCESS_STOPPED)))
p = lst->content;
if (!(p->attributes & (PROCESS_COMPLETED | PROCESS_STOPPED)))
return (0);
lst = lst->next;
}

View file

@ -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);
}

View file

@ -1,7 +1,7 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* job_print_change.c :+: :+: :+: */
/* job_notify_change.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
@ -12,7 +12,7 @@
#include "minishell.h"
void job_print_change(t_job *job, int status)
void job_notify_change(t_job *job, int status)
{
char rank;
@ -21,12 +21,12 @@ void job_print_change(t_job *job, int status)
rank = '+';
else if (job->id == data_singleton()->jobc.rank[1])
rank = '-';
ft_printf("{mag}[%i] %c %i ", job->id, rank, job->pid);
ft_printf("{mag}[%i] %c ", job->id, rank);
if (status == 0)
ft_printf("{gre}done{mag}");
else if (status == 9)
ft_printf("{red}killed{mag}");
else
ft_printf("exit %i", status);
ft_printf("\t%s{eoc}\n", job->command);
/* ft_printf("\t%s{eoc}\n", job->command); */
}

View file

@ -16,8 +16,8 @@ void job_notify_new(t_job *job)
{
t_list *process;
process = job->first_process;
ft_printf("{mag}[%i]", job->id);
process = job->first_process;
while (process)
{
ft_printf(" %i", ((t_process*)process->content)->pid);

View file

@ -20,7 +20,7 @@ void job_update_id(void)
jobc = &data_singleton()->jobc;
id = &jobc->current_id;
start = jobc->list;
start = jobc->first_job;
while (ft_lst_find(start, id, job_cmp_id))
{
*id += 1;

View file

@ -19,7 +19,7 @@ void job_update_rank()
t_list *list;
jobc = &data_singleton()->jobc;
list = jobc->list;
list = jobc->first_job;
if (list)
{
job = list->content;

View file

@ -0,0 +1,7 @@
#include "job_control.h"
int job_wait(t_job *job)
{
(void)job;
return (0);
}

View file

@ -1,7 +1,7 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* job_cmp_pid.c :+: :+: :+: */
/* process_cmp_pid.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
@ -12,7 +12,7 @@
#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);
}

View 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);
}

View 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);
}

View file

@ -16,6 +16,7 @@ int put_job_in_background(t_job *job, int cont)
{
/* Send the job a continue signal, if necessary. */
if (cont)
if (kill (-j->pgid, SIGCONT) < 0)
if (kill (-job->pgid, SIGCONT) < 0)
perror ("kill (SIGCONT)");
return (0);
}

View file

@ -16,22 +16,24 @@ int put_job_in_foreground(t_job *job, int cont)
{
t_jobc *jobc;
jobc = &data_singleton()->jobc;
/* Put the job into the foreground. */
tcsetpgrp(shell_terminal, job->pgid);
tcsetpgrp(STDIN_FILENO, job->pgid);
/* Send the job a continue signal, if necessary. */
if (cont)
{
tcsetattr (shell_terminal, TCSADRAIN, &job->tmodes);
tcsetattr (STDIN_FILENO, TCSADRAIN, &job->tmodes);
if (kill(- job->pgid, SIGCONT) < 0)
perror("kill (SIGCONT)");
}
/* Wait for it to report. */
wait_for_job(j);
job_wait(job);
/* Put the shell back in the foreground. */
tcsetpgrp(shell_terminal, jobc->shell_pgid);
tcsetpgrp(STDIN_FILENO, jobc->shell_pgid);
/* Restore the shells terminal modes. */
tcgetattr(shell_terminal, &job->tmodes);
tcsetattr(shell_terminal, TCSADRAIN, &jobc->shell_tmodes);
tcgetattr(STDIN_FILENO, &job->tmodes);
tcsetattr(STDIN_FILENO, TCSADRAIN, &jobc->shell_tmodes);
return (0);
}

View file

@ -18,13 +18,5 @@ void sigchld_handler(int signo)
(void)signo;
data = data_singleton();
if (data->mode == MODE_INPUT)
{
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");
DG("got asynchronous notification (SIGCHLD)");
}

View file

@ -17,14 +17,6 @@ int ft_prompt(void)
t_data *data;
data = data_singleton();
while (data->jobc.list)
{
/* usleep(500 * 1000); */
if (check_chlds())
continue ;
else
break ;
}
ft_putstr(SHELL_PROMPT);
return (0);
}

View file

@ -23,19 +23,19 @@ int data_init(void)
data->line.input = NULL;
data->env = ft_sstrdup(environ);
data->line.history = NULL;
data->exec.fdin = STDIN;
data->exec.fdout = STDOUT;
data->exec.process.fdin = STDIN;
data->exec.process.fdout = STDOUT;
data->exec.process.pid = 0;
data->exec.aol_status = NULL;
data->exec.aol_search = 0;
data->exec.amp = 0;
data->jobc.list = NULL;
data->exec.job.id = 0;
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.rank[0] = 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)))
return (-1);
if ((term_name = ft_getenv(data->env, "TERM")) == NULL)

View file

@ -41,6 +41,7 @@ int main(void)
/* btree_apply_infix(ast, &ft_putast2); */
if (ft_exec(&ast))
return (1);
DG("end of loop");
}
return (0);
}

View file

@ -22,7 +22,7 @@ void shell_init(void)
if (isatty(STDIN_FILENO))
{
while (tcgetpgrp(STDIN_FILENO) != (*shell_pgid = getpgrp()))
kill(*shell_pgid, SIGTTIN);
kill(-*shell_pgid, SIGTTIN);
signal(SIGINT, sigint_handler);
signal(SIGQUIT, SIG_IGN);
signal(SIGTSTP, sigtstp_handler);