diff --git a/42sh/Makefile b/42sh/Makefile index b0d2688e..8dcf5189 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -67,6 +67,11 @@ $(D_OBJ)/%.o: $(D_SRC)/exec/%.c includes/exec.h @$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS) @echo "Compiling "$<"..." +$(D_OBJ)/%.o: $(D_SRC)/job-control/%.c includes/job_control.h + @$(MKDIR) $(D_OBJ) + @$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS) + @echo "Compiling "$<"..." + libft/libft.a: libft/src/*/*.c @echo "libft/libft.a" @$(MAKE) -C libft 2>/dev/null diff --git a/42sh/debug b/42sh/debug new file mode 100644 index 00000000..abab437d --- /dev/null +++ b/42sh/debug @@ -0,0 +1,32 @@ + main.c 23 start of shell + main.c 28 got command 'ls' + main.c 28 got command 'ls' + main.c 28 got command '""' + main.c 28 got command 'vim&' + & + +----+ + COM + main.c 28 got command 'jobs' + job_update_id.c 27 ID_UPDATE:2 + main.c 28 got command 'jobs' + main.c 28 got command '' + main.c 28 got command '' + main.c 28 got command 'jobs' + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT + sigint_handler.c 18 got SIGINT diff --git a/42sh/includes/builtin.h b/42sh/includes/builtin.h new file mode 100644 index 00000000..42f2543a --- /dev/null +++ b/42sh/includes/builtin.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:21:56 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:57:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUILTIN_H +# define BUILTIN_H + +# include "types.h" +# include "libft.h" + +t_execf *is_builtin(t_process *p); +int builtin_env(const char *path, char *const argv[], char *const envp[]); +int builtin_echo(const char *path, char *const argv[], char *const envp[]); +int builtin_cd(const char *path, char *const argv[], char *const envp[]); +int builtin_exit(const char *path, char *const argv[], char *const envp[]); +int builtin_setenv(const char *path, char *const argv[], char *const envp[]); +int builtin_unsetenv(const char *path, char *const argv[], char *const envp[]); +int builtin_jobs(const char *path, char *const av[], char *const envp[]); +int builtin_fg(const char *path, char *const av[], char *const envp[]); +int builtin_bg(const char *path, char *const av[], char *const envp[]); + +#endif diff --git a/42sh/includes/exec.h b/42sh/includes/exec.h index 15aac6df..4146a16e 100644 --- a/42sh/includes/exec.h +++ b/42sh/includes/exec.h @@ -6,48 +6,94 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */ -/* Updated: 2016/12/06 18:23:29 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 10:23:55 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef EXEC_H # define EXEC_H -# include "minishell.h" # define PIPE_READ 0 # define PIPE_WRITE 1 -typedef struct s_execfunc t_execfunc; +# define PROCESS_BUILTIN (1 << 0) +# define PROCESS_BINARY (1 << 1) +# define PROCESS_SCRIPT (1 << 2) +# define PROCESS_UNKNOWN (1 << 3) +# define PROCESS_PIPESTART (1 << 4) +# define PROCESS_PIPEEND (1 << 5) +# define PROCESS_COMPLETED (1 << 6) +# define PROCESS_SUSPENDED (1 << 7) +# define PROCESS_RUNNING (1 << 8) +# define PROCESS_CONTINUED (1 << 9) -struct s_execfunc +# define PROCESS_TYPE_MASK (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3) +# define PROCESS_STATE_MASK (1 << 6 | 1 << 7 | 1 << 8 | 1 << 9) + +# define IS_PIPESTART(a) (a & PROCESS_PIPESTART) +# define IS_PIPEEND(a) (a & PROCESS_PIPEEND) + +# include "libft.h" +# include "types.h" +# include "job_control.h" + +struct s_process { - t_type type; - int (*f)(t_btree **ast, t_data *data); + char **av; + char *path; + t_execf *execf; + pid_t pid; + int fdin; + int fdout; + int status; + t_flag attributes; }; -extern t_execfunc g_execfunc[]; +struct s_exec +{ + char *aol_status; + int aol_search; + t_job job; + t_process process; +}; -int ft_exec(t_btree **ast, t_data *data); +struct s_execmap +{ + t_type type; + int (*f)(t_btree **ast); +}; -int exec_semi(t_btree **ast, t_data *data); -int exec_or_if(t_btree **ast, t_data *data); -int exec_and_if(t_btree **ast, t_data *data); -int exec_pipe(t_btree **ast, t_data *data); +#include "minishell.h" -int exec_less(t_btree **ast, t_data *data); -int exec_great(t_btree **ast, t_data *data); -int exec_dgreat(t_btree **ast, t_data *data); -int exec_command(t_btree **ast, t_data *data); +extern t_execmap g_execmap[]; -void fd_redirect(t_data *data); -void fd_reset(t_data *data); +int ft_exec(t_btree **ast); + +int exec_semi(t_btree **ast); +int exec_ampersand(t_btree **ast); +int exec_or_if(t_btree **ast); +int exec_and_if(t_btree **ast); +int exec_pipe(t_btree **ast); + +int exec_less(t_btree **ast); +int exec_great(t_btree **ast); +int exec_dgreat(t_btree **ast); +int exec_command(t_btree **ast); + +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 process_reset(void); + +void fd_redirect(void); +void fd_reset(void); -int ft_cmd_process(char **argv, t_data *data); -int ft_cmd_exec(char *execpath, char **argv, t_data *data); char *ft_findexec(char *path, char *file); +void set_exitstatus(int status); + void ast_free(void *data, size_t content_size); -void set_exitstatus(t_data *data, int status); - #endif diff --git a/42sh/includes/ft_readline.h b/42sh/includes/ft_readline.h index 51c6a05c..0e557f2b 100644 --- a/42sh/includes/ft_readline.h +++ b/42sh/includes/ft_readline.h @@ -6,7 +6,7 @@ /* By: sbenning +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/08 18:02:25 by sbenning #+# #+# */ -/* Updated: 2017/01/10 11:46:49 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:22:13 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -105,9 +105,7 @@ struct s_line int select; t_curs curs; t_list *stack; - /*COMPATIBILITY*/ t_dlist *history; - t_list *qstack; }; /* diff --git a/42sh/includes/job_control.h b/42sh/includes/job_control.h new file mode 100644 index 00000000..bea10d93 --- /dev/null +++ b/42sh/includes/job_control.h @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_control.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 16:55:09 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:56:18 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef JOB_CONTROL_H +# define JOB_CONTROL_H + +# include +# include +# include +# include "libft.h" +# include "types.h" + +# 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) + +#define JOBS_OPTS_L (1 << 0) + +struct s_job +{ + int id; + pid_t pgid; + t_flag attributes; + t_list *first_process; + struct termios tmodes; +}; + +struct s_jobc +{ + t_list *first_job; + pid_t shell_pgid; + int current_id; + struct termios shell_tmodes; +}; + +# include "exec.h" + +t_process *job_getprocess(pid_t pid); +int job_addprocess(t_process *p); +void job_update_id(void); +void job_update_rank(void); + +int do_job_notification(void); +void job_notify_new(t_job *job); +void job_notify_change(int id); +void job_format(t_job *j, int rank[2], int opts); +void job_format_head(t_job *j, int rank[2]); + +void job_update_status(void); +void mark_job_as_running (t_job *j); +int process_mark_status(pid_t pid, int status); +int job_is_stopped(int id); +int job_is_completed(int id); + +void job_new(char **av, pid_t pid); +int job_wait(int id); +void job_remove(int id); +void job_free(void *content, size_t content_size); +void job_kill_all(void); + +int put_job_in_foreground(t_job *job, int cont); +int put_job_in_background(t_job *job, int cont); + +int job_cmp_pid(t_job *job, pid_t *pid); +int job_cmp_id(t_job *job, int *id); +void job_getrank(int (*rank)[2]); + +void sigchld_handler(int signo); +void sigint_handler(int signo); +void sigtstp_handler(int signo); +void sigttin_handler(int signo); +void sigttou_handler(int signo); + +int process_cmp_pid(t_process *p, pid_t *pid); +void process_format(t_list **p, int firstp, int opts); + +#endif diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h index 97ba7c4a..fbde230a 100644 --- a/42sh/includes/lexer.h +++ b/42sh/includes/lexer.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/01 12:15:50 by jhalford #+# #+# */ -/* Updated: 2016/12/05 14:11:52 by jhalford ### ########.fr */ +/* Updated: 2016/12/10 16:00:51 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/includes/line_editing.h b/42sh/includes/line_editing.h new file mode 100644 index 00000000..941853ac --- /dev/null +++ b/42sh/includes/line_editing.h @@ -0,0 +1,89 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* line-editing.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/10 13:38:21 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:46:19 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LINE_EDITING_H +# define LINE_EDITING_H + +# include "minishell.h" +# include +# include + +# define SHELL_PROMPT "$> " +# define BUFF_SIZE 32 +# define READ_BUF 32 +# define FT_KEY_C_C "\x3" +# define FT_KEY_C_D "\x4" +# define FT_KEY_C_H "\x8" +# define FT_KEY_TAB "\x9" +# define FT_KEY_ENTER "\xa" +# define FT_KEY_C_K "\xb" +# define FT_KEY_C_L "\xc" +# define FT_KEY_C_U "\x15" +# define FT_KEY_C_Z "\x1a" +# define FT_KEY_ESC "\x1b" +# define FT_KEY_UP "\x1b\x5b\x41" +# define FT_KEY_DOWN "\x1b\x5b\x42" +# define FT_KEY_RIGHT "\x1b\x5b\x43" +# define FT_KEY_LEFT "\x1b\x5b\x44" +# define FT_KEY_C_UP "\x1b\x4f\x41" +# define FT_KEY_C_DOWN "\x1b\x4f\x42" +# define FT_KEY_C_RIGHT "\x1b\x4f\x43" +# define FT_KEY_C_LEFT "\x1b\x4f\x44" +# define FT_KEY_SQUOTE "\x22" +# define FT_KEY_DQUOTE "\x27" +# define FT_KEY_BSLASH "\x5c" +# define FT_KEY_DEL "\x7f" + +enum e_qstate +{ + Q_NONE, + Q_QUOTE, + Q_DQUOTE, + Q_BACKSLASH, +}; + +typedef struct s_data t_data; +typedef enum e_qstate t_qstate; + +extern t_stof g_keys[]; + +int ft_interactive_sh(t_data *data); +int input_init(t_data *data); +int ft_set_termios(t_data *data, int input_mode); +int ft_prompt(void); + +int ft_history_add(t_data *data); + +int ft_clear_line(t_data *data, char *buf); +int ft_line_up(t_data *data, char *buf); +int ft_line_down(t_data *data, char *buf); +int ft_line_start(t_data *data, char *buf); +int ft_line_end(t_data *data, char *buf); + +int ft_key_del(t_data *data, char *buf); +int ft_key_enter(t_data *data, char *buf); +int ft_key_ctrl_d(t_data *data, char *buf); +int ft_key_ctrl_c(t_data *data, char *buf); +int ft_key_default(t_data *data, char *buf); + +int ft_history_up(t_data *data, char *buf); +int ft_history_down(t_data *data, char *buf); +int ft_cursor_left(t_data *data, char *buf); +int ft_cursor_right(t_data *data, char *buf); +int ft_word_left(t_data *data, char *buf); +int ft_word_right(t_data *data, char *buf); + +void qstate_none(t_qstate *new, char c); +void qstate_quote(t_qstate *new, char c); +void qstate_dquote(t_qstate *new, char c); + +#endif diff --git a/42sh/includes/minishell.h b/42sh/includes/minishell.h index 0bd144e4..0c7a7813 100644 --- a/42sh/includes/minishell.h +++ b/42sh/includes/minishell.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/10 13:07:44 by jhalford #+# #+# */ -/* Updated: 2017/01/10 11:50:31 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:12:41 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,70 +16,48 @@ # include "libft.h" +# include "types.h" # include "lexer.h" # include "parser.h" # include "ft_readline.h" # include "exec.h" +# include "builtin.h" +# include "job_control.h" # include # include # include # include # include +# include -typedef long long t_type; -typedef struct s_line t_line; -typedef struct s_comp t_comp; -typedef struct s_exec t_exec; -/* -struct s_line +enum e_mode { - t_dlist *history; - int input_pos; - t_list *qstack; - char *input; + MODE_INPUT, + MODE_EXEC, }; -*/ + struct s_comp { - int a; -}; - -struct s_exec -{ - int fdin; - int fdout; - char *aol_status; - int aol_search; + int a; }; struct s_data { - char **env; - t_exec exec; - t_line line; - t_comp comp; + char **env; + t_mode mode; + t_line line; + t_comp comp; + t_exec exec; + 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; -void sig_handler(int signo); -t_data *data_singleton(); -int data_init(t_data *data); -void data_exit(t_data *data); -void ft_cleanup(void); - -int ft_builtin(char **av, t_data *data); -int builtin_echo(char **av, t_data *data); -int builtin_cd(char **av, t_data *data); -int builtin_exit(char **av, t_data *data); -int builtin_setenv(char **av, t_data *data); -int builtin_unsetenv(char **av, t_data *data); -int builtin_env(char **av, t_data *data); +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); diff --git a/42sh/includes/types.h b/42sh/includes/types.h new file mode 100644 index 00000000..af8071d0 --- /dev/null +++ b/42sh/includes/types.h @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* types.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:11:48 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:45:35 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#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; +typedef struct s_process t_process; +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 diff --git a/42sh/libft b/42sh/libft index d799465c..af71e8b8 160000 --- a/42sh/libft +++ b/42sh/libft @@ -1 +1 @@ -Subproject commit d799465c2e0d51f24fe4d5cf1e51c5109a1617a0 +Subproject commit af71e8b8de26051cd63fde8ab82c90801bd835d8 diff --git a/42sh/script.sh b/42sh/script.sh index 1a566882..8fb9fff0 100755 --- a/42sh/script.sh +++ b/42sh/script.sh @@ -1,4 +1,5 @@ #!/bin/sh while [ 1 ]; do sleep 1 + echo "a" done diff --git a/42sh/src/builtin/builtin_cd.c b/42sh/src/builtin/builtin_cd.c index d42e6309..96278410 100644 --- a/42sh/src/builtin/builtin_cd.c +++ b/42sh/src/builtin/builtin_cd.c @@ -6,34 +6,35 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:57:53 by jhalford #+# #+# */ -/* Updated: 2016/12/03 11:58:14 by jhalford ### ########.fr */ +/* Updated: 2016/12/15 17:50:04 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "builtin.h" + #define CDOPT_L 0x001 #define CDOPT_P 0x002 #define HAS_CDOPT_P(x) (x & CD_OPT_P) #define HAS_CDOPT_L(x) (x & CD_OPT_L) #define CDERR_1 "cd: no such file or directory: %s\n" -static char *builtin_cd_special(char **av, char **env) +static char *builtin_cd_special(char *const av[], char *const env[]) { char *target; if (!*av) { - if (!(target = ft_getenv(env, "HOME"))) + if (!(target = ft_getenv((char**)env, "HOME"))) return (NULL); } else if (ft_strcmp(*av, "-") == 0) - target = ft_getenv(env, "OLDPWD"); + target = ft_getenv((char**)env, "OLDPWD"); else target = *av; return (target); } -static int builtin_cd_opts(char **av, int *opts) +static int builtin_cd_opts(char *const av[], int *opts) { int i; int j; @@ -60,7 +61,7 @@ static int builtin_cd_opts(char **av, int *opts) return (i); } -int builtin_cd(char **av, t_data *data) +int builtin_cd(const char *path, char *const av[], char *const envp[]) { int i; int opts; @@ -68,9 +69,9 @@ int builtin_cd(char **av, t_data *data) opts = 0; i = builtin_cd_opts(av, &opts); - if (!(target = builtin_cd_special(av + i, data->env))) + if (!(target = builtin_cd_special(av + i, envp))) return (0); - builtin_setenv((char*[3]){"OLDPWD", getcwd(NULL, 0)}, data); + builtin_setenv(path, (char*[3]){"OLDPWD", getcwd(NULL, 0)}, envp); if (chdir(target)) { ft_printf(CDERR_1, target); @@ -78,6 +79,6 @@ int builtin_cd(char **av, t_data *data) } else if (target != av[i]) ft_printf("%s\n", target); - builtin_setenv((char*[3]){"PWD", getcwd(NULL, 0)}, data); + builtin_setenv(path, (char*[3]){"PWD", getcwd(NULL, 0)}, envp); return (0); } diff --git a/42sh/src/builtin/builtin_echo.c b/42sh/src/builtin/builtin_echo.c index f559ebea..d044d7cf 100644 --- a/42sh/src/builtin/builtin_echo.c +++ b/42sh/src/builtin/builtin_echo.c @@ -6,15 +6,16 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:21:41 by jhalford #+# #+# */ -/* Updated: 2016/11/28 14:22:02 by jhalford ### ########.fr */ +/* Updated: 2016/12/13 17:58:14 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "builtin.h" -int builtin_echo(char **av, t_data *data) +int builtin_echo(const char *path, char *const av[], char *const envp[]) { - (void)data; + (void)envp; + (void)path; av++; while (*av) { diff --git a/42sh/src/builtin/builtin_env.c b/42sh/src/builtin/builtin_env.c index 90859d01..1262dd6e 100644 --- a/42sh/src/builtin/builtin_env.c +++ b/42sh/src/builtin/builtin_env.c @@ -6,33 +6,40 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:14:20 by jhalford #+# #+# */ -/* Updated: 2016/11/28 14:28:37 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:08:15 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int builtin_env(char **av, t_data *data) +int builtin_env(const char *path, char *const argv[], char *const envp[]) { - int i; - char **env; - - i = 1; - env = NULL; - if (!av[1]) - { - ft_sstrprint(data->env, '\n'); - ft_putchar('\n'); - } - else - { - while (av[i] && ft_strchr(av[i], '=')) - { - env = ft_sstradd(env, av[i]); - i++; - } - if (av[i]) - ft_cmd_process(av + i, data); - } + (void)argv; + (void)envp; + (void)path; return (0); } +/* int builtin_env(char **av, t_data *data) */ +/* { */ +/* int i; */ +/* char **env; */ + +/* i = 1; */ +/* env = NULL; */ +/* if (!av[1]) */ +/* { */ +/* ft_sstrprint(data->env, '\n'); */ +/* ft_putchar('\n'); */ +/* } */ +/* else */ +/* { */ +/* while (av[i] && ft_strchr(av[i], '=')) */ +/* { */ +/* env = ft_sstradd(env, av[i]); */ +/* i++; */ +/* } */ +/* if (av[i]) */ +/* ft_cmd_process(av + i); */ +/* } */ +/* return (0); */ +/* } */ diff --git a/42sh/src/builtin/builtin_exit.c b/42sh/src/builtin/builtin_exit.c index 25238b9f..80148cb8 100644 --- a/42sh/src/builtin/builtin_exit.c +++ b/42sh/src/builtin/builtin_exit.c @@ -6,20 +6,36 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:28:41 by jhalford #+# #+# */ -/* Updated: 2016/12/01 14:35:36 by jhalford ### ########.fr */ +/* Updated: 2017/01/09 16:25:06 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int builtin_exit(char **av, t_data *data) +int builtin_exit(const char *path, char *const av[], char *const envp[]) { - int status; + int status; + static int notified = 0; + t_jobc *jobc; + t_list *jlist; + (void)envp; + (void)path; + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + if (jlist && !notified) + { + notified = 1; + ft_dprintf(2, "{red}%s: you have live jobs (running or suspended).{eoc}\n", SHELL_NAME); + return (0); + } if (av[1]) status = ft_atoi(av[1]); else - status = ft_atoi(ft_getenv(data->env, "?")); + { + /* status = ft_atoi(ft_getenv(data_singleton()->env, "?")); */ + status = 0; + } exit(status); return (0); } diff --git a/42sh/src/builtin/builtin_setenv.c b/42sh/src/builtin/builtin_setenv.c index 0d547745..98f92890 100644 --- a/42sh/src/builtin/builtin_setenv.c +++ b/42sh/src/builtin/builtin_setenv.c @@ -6,40 +6,45 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ -/* Updated: 2016/12/07 16:29:11 by jhalford ### ########.fr */ +/* Updated: 2017/01/09 15:53:07 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #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; - DG("doing setenv now"); + (void)envp; + (void)path; + i = 0; + env = &data_singleton()->env; 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]) == '=') + /* DG("check 2: i=%i, (*env)[i]=%p",i, (*env)[i]); */ + /* DG("content=%s", (*env)[i]); */ + if (ft_strcmp((*env)[i], av[0]) == '=') { - ft_strdel(env); - *env = str; + ft_strdel(&(*env)[i]); + (*env)[i] = str; return (0); } - env++; + i++; } - data->env = ft_sstradd(data->env, str); + *env = ft_sstradd(*env, str); ft_strdel(&str); } return (0); diff --git a/42sh/src/builtin/builtin_unsetenv.c b/42sh/src/builtin/builtin_unsetenv.c index 93104cda..d684462a 100644 --- a/42sh/src/builtin/builtin_unsetenv.c +++ b/42sh/src/builtin/builtin_unsetenv.c @@ -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++; } diff --git a/42sh/src/builtin/builtin.c b/42sh/src/builtin/is_builtin.c similarity index 63% rename from 42sh/src/builtin/builtin.c rename to 42sh/src/builtin/is_builtin.c index 1966a63e..7dbdda0c 100644 --- a/42sh/src/builtin/builtin.c +++ b/42sh/src/builtin/is_builtin.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* builtin.c :+: :+: :+: */ +/* is_builtin.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/28 14:21:34 by jhalford #+# #+# */ -/* Updated: 2016/12/03 15:17:21 by jhalford ### ########.fr */ +/* Created: 2016/12/13 13:09:57 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:58:13 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,33 +19,19 @@ t_stof g_builtin[] = { {"unsetenv", &builtin_unsetenv}, {"env", &builtin_env}, {"exit", &builtin_exit}, + {"jobs", &builtin_jobs}, + {"fg", &builtin_fg}, + {"bg", &builtin_bg}, {NULL, NULL}, }; -int ft_builtin(char **av, t_data *data) +t_execf *is_builtin(t_process *p) { int i; - int ret; i = -1; while (g_builtin[++i].name) - if (ft_strcmp(g_builtin[i].name, *av) == 0) - { - if (data->exec.fdout != STDOUT) - { - if (fork() == 0) - { - fd_redirect(data); - ret = (g_builtin[i].f)(av, data); - exit(ret); - } - } - else - { - ret = (g_builtin[i].f)(av, data); - set_exitstatus(data, ret); - } - return (1); - } - return (0); + if (ft_strcmp(g_builtin[i].name, p->av[0]) == 0) + return (g_builtin[i].f); + return (NULL); } diff --git a/42sh/src/exec/ast_free.c b/42sh/src/exec/ast_free.c index f7b0943a..3a8b03a6 100644 --- a/42sh/src/exec/ast_free.c +++ b/42sh/src/exec/ast_free.c @@ -6,11 +6,11 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/05 11:50:51 by jhalford #+# #+# */ -/* Updated: 2016/12/09 21:28:29 by jhalford ### ########.fr */ +/* Updated: 2016/12/15 13:28:36 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "exec.h" void ast_free(void *data, size_t content_size) { @@ -18,17 +18,13 @@ void ast_free(void *data, size_t content_size) (void)content_size; node = data; - DG("gonna free a node"); if (node->type == TK_COMMAND) { - DG("ast_free TK_COMMAND"); if (node->data.sstr) ft_sstrfree(node->data.sstr); } else if (node->type == TK_LESS || node->type == TK_GREAT || node->type == TK_DGREAT) { - DG("ast_free TK_REDIR %p", node->data.redir.word.word); ft_strdel(&node->data.redir.word.word); } - DG("ast_free done"); } diff --git a/42sh/src/exec/exec_ampersand.c b/42sh/src/exec/exec_ampersand.c new file mode 100644 index 00000000..395785dd --- /dev/null +++ b/42sh/src/exec/exec_ampersand.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_ampersand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 16:01:30 by jhalford #+# #+# */ +/* Updated: 2016/12/15 13:40:11 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int exec_ampersand(t_btree **ast) +{ + data_singleton()->exec.job.attributes |= JOB_BG; + ft_exec(&(*ast)->left); + data_singleton()->exec.job.attributes &= ~JOB_BG; + ft_exec(&(*ast)->right); + btree_delone(ast, &ast_free); + return (0); +} diff --git a/42sh/src/exec/exec_and_if.c b/42sh/src/exec/exec_and_if.c index 4858321d..0728310d 100644 --- a/42sh/src/exec/exec_and_if.c +++ b/42sh/src/exec/exec_and_if.c @@ -6,27 +6,30 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/30 20:52:28 by jhalford #+# #+# */ -/* Updated: 2016/12/05 12:17:33 by jhalford ### ########.fr */ +/* Updated: 2016/12/12 18:01:06 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_and_if(t_btree **ast, t_data *data) +int exec_and_if(t_btree **ast) { + t_data *data; + + data = data_singleton(); if (data->exec.aol_status == NULL || (data->exec.aol_search == TK_AND_IF && *data->exec.aol_status == '0') || (data->exec.aol_search == TK_OR_IF && *data->exec.aol_status != '0')) { - ft_exec(&(*ast)->left, data); + ft_exec(&(*ast)->left); data->exec.aol_status = ft_getenv(data->env, "?"); } data->exec.aol_search = TK_AND_IF; if (*data->exec.aol_status == '0' || ((t_astnode*)(*ast)->right->item)->type != TK_COMMAND) - ft_exec(&(*ast)->right, data); + ft_exec(&(*ast)->right); data->exec.aol_status = NULL; data->exec.aol_search = 0; btree_delone(ast, &ast_free); diff --git a/42sh/src/exec/exec_command.c b/42sh/src/exec/exec_command.c index 82eb4e52..417a1a25 100644 --- a/42sh/src/exec/exec_command.c +++ b/42sh/src/exec/exec_command.c @@ -6,18 +6,37 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:28:14 by jhalford #+# #+# */ -/* Updated: 2016/12/05 14:06:34 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:16:51 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_command(t_btree **ast, t_data *data) +int exec_command(t_btree **ast) { t_astnode *node; + t_process *p; + t_job *job; node = (*ast)->item; - ft_cmd_process(node->data.sstr, data); + p = &data_singleton()->exec.process; + job = &data_singleton()->exec.job; + p->av = ft_sstrdup(node->data.sstr); + process_setexec(p); + if (!(launch_process(p))) + { + job_addprocess(p); + if (IS_PIPEEND(p->attributes)) + { + JOB_IS_FG(job->attributes) ? + put_job_in_foreground(job, 0): + put_job_in_background(job, 0); + job->pgid = 0; + } + } + p->av = NULL; + p->pid = 0; + p->attributes = PROCESS_PIPESTART | PROCESS_PIPEEND; btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_dgreat.c b/42sh/src/exec/exec_dgreat.c index a338c59d..9897f54d 100644 --- a/42sh/src/exec/exec_dgreat.c +++ b/42sh/src/exec/exec_dgreat.c @@ -6,22 +6,22 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 18:15:13 by jhalford #+# #+# */ -/* Updated: 2016/12/05 12:13:45 by jhalford ### ########.fr */ +/* Updated: 2016/12/13 17:13:58 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_dgreat(t_btree **ast, t_data *data) +int exec_dgreat(t_btree **ast) { t_astnode *node; int fd; node = (*ast)->item; fd = open(node->data.redir.word.word, O_WRONLY | O_APPEND | O_CREAT, 0644); - data->exec.fdout = fd; - ft_exec(&(*ast)->left, data); - data->exec.fdout = STDOUT; + data_singleton()->exec.process.fdout = fd; + ft_exec(&(*ast)->left); + data_singleton()->exec.process.fdout = STDOUT; btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_great.c b/42sh/src/exec/exec_great.c index 996283e3..6b410e7b 100644 --- a/42sh/src/exec/exec_great.c +++ b/42sh/src/exec/exec_great.c @@ -6,22 +6,22 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:27:51 by jhalford #+# #+# */ -/* Updated: 2016/12/05 12:13:28 by jhalford ### ########.fr */ +/* Updated: 2016/12/13 17:14:19 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_great(t_btree **ast, t_data *data) +int exec_great(t_btree **ast) { t_astnode *node; int fd; node = (*ast)->item; fd = open(node->data.redir.word.word, O_WRONLY | O_TRUNC | O_CREAT, 0644); - data->exec.fdout = fd; - ft_exec(&(*ast)->left, data); - data->exec.fdout = STDOUT; + data_singleton()->exec.process.fdout = fd; + ft_exec(&(*ast)->left); + data_singleton()->exec.process.fdout = STDOUT; btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_less.c b/42sh/src/exec/exec_less.c index 63dd4dbf..f27be538 100644 --- a/42sh/src/exec/exec_less.c +++ b/42sh/src/exec/exec_less.c @@ -6,22 +6,25 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/14 17:27:08 by jhalford #+# #+# */ -/* Updated: 2016/12/05 12:12:59 by jhalford ### ########.fr */ +/* Updated: 2016/12/13 17:14:46 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_less(t_btree **ast, t_data *data) +int exec_less(t_btree **ast) { t_astnode *node; int fd; node = (*ast)->item; fd = open(node->data.redir.word.word, O_RDONLY); - data->exec.fdin = fd; - ft_exec(&(*ast)->left, data); - data->exec.fdin = STDIN; + data_singleton()->exec.process.fdin = fd; + /* ft_strappend(&data->exec.process.command, "<"); */ + /* ft_strappend(&data->exec.process.command, node->data.redir.word.word); */ + ft_exec(&(*ast)->left); + data_singleton()->exec.process.fdin = STDIN; + /* data->exec.process.command = NULL; */ btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_or_if.c b/42sh/src/exec/exec_or_if.c index 1b60dbc3..6b18060c 100644 --- a/42sh/src/exec/exec_or_if.c +++ b/42sh/src/exec/exec_or_if.c @@ -6,27 +6,30 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/30 21:06:17 by jhalford #+# #+# */ -/* Updated: 2016/12/09 21:50:19 by jhalford ### ########.fr */ +/* Updated: 2017/01/02 18:10:21 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_or_if(t_btree **ast, t_data *data) +int exec_or_if(t_btree **ast) { + t_data *data; + + data = data_singleton(); if (data->exec.aol_status == NULL || (data->exec.aol_search == TK_AND_IF && *data->exec.aol_status == '0') || (data->exec.aol_search == TK_OR_IF && *data->exec.aol_status != '0')) { - ft_exec(&(*ast)->left, data); + ft_exec(&(*ast)->left); data->exec.aol_status = ft_getenv(data->env, "?"); } data->exec.aol_search = TK_OR_IF; if (*data->exec.aol_status != '0' || ((t_astnode*)(*ast)->right->item)->type != TK_COMMAND) - ft_exec(&(*ast)->right, data); + ft_exec(&(*ast)->right); data->exec.aol_status = NULL; data->exec.aol_search = 0; btree_delone(ast, &ast_free); diff --git a/42sh/src/exec/exec_pipe.c b/42sh/src/exec/exec_pipe.c index 0d0c65ae..8e777ae1 100644 --- a/42sh/src/exec/exec_pipe.c +++ b/42sh/src/exec/exec_pipe.c @@ -6,29 +6,41 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 21:13:23 by jhalford #+# #+# */ -/* Updated: 2016/12/06 20:26:55 by jhalford ### ########.fr */ +/* Updated: 2017/01/09 16:19:38 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_pipe(t_btree **ast, t_data *data) +int exec_pipe(t_btree **ast) { - int fds[2]; + int fds[2]; + int start; + t_data *data; + t_process *p; + data = data_singleton(); + p = &data_singleton()->exec.process; pipe(fds); DG("pipe %i->%i", fds[PIPE_WRITE], fds[PIPE_READ]); - data->exec.fdout = fds[PIPE_WRITE]; - ft_exec(&(*ast)->left, data); - if (data->exec.fdout != STDOUT) - close(data->exec.fdout); - data->exec.fdout = STDOUT; - data->exec.fdin = fds[PIPE_READ]; - ft_exec(&(*ast)->right, data); + p->fdout = fds[PIPE_WRITE]; + start = IS_PIPESTART(p->attributes); + + p->attributes &= ~PROCESS_PIPEEND; + ft_exec(&(*ast)->left); + p->attributes &= ~PROCESS_PIPESTART; + close(fds[PIPE_WRITE]); + p->fdout = STDOUT; + p->fdin = fds[PIPE_READ]; + + p->attributes |= PROCESS_PIPEEND; + ft_exec(&(*ast)->right); + if (start) + p->attributes |= PROCESS_PIPESTART; + close(fds[PIPE_READ]); - data->exec.fdin = STDIN; - data->exec.fdout = STDOUT; + p->fdin = STDIN; btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/exec_semi.c b/42sh/src/exec/exec_semi.c index 39b7d484..335ac2ac 100644 --- a/42sh/src/exec/exec_semi.c +++ b/42sh/src/exec/exec_semi.c @@ -6,16 +6,16 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/30 20:52:05 by jhalford #+# #+# */ -/* Updated: 2016/12/05 12:14:37 by jhalford ### ########.fr */ +/* Updated: 2016/12/12 18:00:21 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -int exec_semi(t_btree **ast, t_data *data) +int exec_semi(t_btree **ast) { - ft_exec(&(*ast)->left, data); - ft_exec(&(*ast)->right, data); + ft_exec(&(*ast)->left); + ft_exec(&(*ast)->right); btree_delone(ast, &ast_free); return (0); } diff --git a/42sh/src/exec/ft_cmd.c b/42sh/src/exec/ft_cmd.c deleted file mode 100644 index adb9d6db..00000000 --- a/42sh/src/exec/ft_cmd.c +++ /dev/null @@ -1,65 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ft_cmd.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/27 21:13:18 by jhalford #+# #+# */ -/* Updated: 2016/12/09 21:50:26 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -extern pid_t g_pid; - -int ft_cmd_process(char **argv, t_data *data) -{ - char *execpath; - - ft_expand_dollar(argv, data->env); - if (ft_builtin(argv, data)) - return (0); - else if (ft_strchr(argv[0], '/')) - execpath = argv[0]; - else if (!(execpath = ft_findexec(ft_getenv(data->env, "PATH"), argv[0]))) - { - ft_dprintf(2, "%s: command not found: %s\n", SHELL_NAME, argv[0]); - set_exitstatus(data, 127); - return (-1); - } - return (ft_cmd_exec(execpath, argv, data)); -} - -int ft_cmd_exec(char *execpath, char **argv, t_data *data) -{ - pid_t pid; - int status; - - if (access(execpath, X_OK) == -1) - { - ft_dprintf(2, "%s: permission denied: %s\n", SHELL_NAME, argv[0]); - ft_strdel(&execpath); - return (-1); - } - if ((pid = fork()) == -1) - return (-1); - else if (pid == 0) - { - fd_redirect(data); - execve(execpath, argv, data->env); - } - else - { - ft_strdel(&execpath); - g_pid = pid; - if (data->exec.fdout == STDOUT) - { - waitpid(pid, &status, 0); - set_exitstatus(data, status); - } - g_pid = 0; - } - return (0); -} diff --git a/42sh/src/exec/ft_exec.c b/42sh/src/exec/ft_exec.c index 0992b7aa..a553c73f 100644 --- a/42sh/src/exec/ft_exec.c +++ b/42sh/src/exec/ft_exec.c @@ -6,17 +6,18 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/27 20:30:32 by jhalford #+# #+# */ -/* Updated: 2016/12/05 13:37:46 by jhalford ### ########.fr */ +/* Updated: 2017/01/08 11:03:09 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "exec.h" -t_execfunc g_execfunc[] = +t_execmap g_execmap[] = { {TK_AND_IF, &exec_and_if}, {TK_OR_IF, &exec_or_if}, {TK_SEMI, &exec_semi}, + {TK_AMP, &exec_ampersand}, {TK_PIPE, &exec_pipe}, {TK_LESS, &exec_less}, {TK_GREAT, &exec_great}, @@ -25,19 +26,20 @@ t_execfunc g_execfunc[] = {0, 0}, }; -int ft_exec(t_btree **ast, t_data *data) +int ft_exec(t_btree **ast) { t_astnode *item; int i; i = 0; - item = (*ast)->item; if (!*ast) return (0); - while (g_execfunc[i].type) + item = (*ast)->item; + while (g_execmap[i].type) { - if (item->type == g_execfunc[i].type) - return ((*g_execfunc[i].f)(ast, data)); + if (item->type == g_execmap[i].type) + /* return ((*g_execmap[i].f)(ast)); */ + (*g_execmap[i].f)(ast); i++; } return (0); diff --git a/42sh/src/exec/ft_findexec.c b/42sh/src/exec/ft_findexec.c index 10f67a95..d2230456 100644 --- a/42sh/src/exec/ft_findexec.c +++ b/42sh/src/exec/ft_findexec.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 13:37:49 by jhalford #+# #+# */ -/* Updated: 2016/12/06 18:05:46 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:18:56 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/exec/launch_process.c b/42sh/src/exec/launch_process.c new file mode 100644 index 00000000..fd5c78c4 --- /dev/null +++ b/42sh/src/exec/launch_process.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* launch_process.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 14:20:45 by jhalford #+# #+# */ +/* Updated: 2017/01/10 13:16:45 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int launch_process(t_process *p) +{ + t_exec *exec; + int pid; + + exec = &data_singleton()->exec; + 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); + } + else if (p->attributes & PROCESS_BUILTIN && p->fdout == STDOUT) + set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env)); + else + { + /* DG("process is to be forked, %i->[]->%i, attr=%b", p->fdin, p->fdout, p->attributes); */ + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes |= PROCESS_RUNNING; + if (p->attributes & (PROCESS_BINARY | PROCESS_SCRIPT) + && access(p->path, X_OK) == -1) + { + ft_dprintf(2, "{red}%s: permission denied: %s{eoc}\n", SHELL_NAME, p->av[0]); + return (-1); + } + pid = fork(); + if (pid == 0) + { + process_setgroup(p); + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTSTP, sigtstp_handler); + signal(SIGTTIN, sigttin_handler); + signal(SIGTTOU, sigttou_handler); + signal(SIGCHLD, SIG_DFL); + process_redirect(p); + (*p->execf)(p->path, p->av, data_singleton()->env); + exit(42); + } + else if (pid > 0) + p->pid = pid; + else if (pid == -1) + perror("fork"); + } + return (0); +} diff --git a/42sh/src/exec/fd_redirect.c b/42sh/src/exec/process_redirect.c similarity index 65% rename from 42sh/src/exec/fd_redirect.c rename to 42sh/src/exec/process_redirect.c index 6c1d8c47..91357682 100644 --- a/42sh/src/exec/fd_redirect.c +++ b/42sh/src/exec/process_redirect.c @@ -1,27 +1,30 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_redirect.c :+: :+: :+: */ +/* process_redirect.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/29 16:04:18 by jhalford #+# #+# */ -/* Updated: 2016/12/03 15:24:08 by jhalford ### ########.fr */ +/* Updated: 2017/01/09 15:35:39 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minishell.h" +#include "exec.h" -void fd_redirect(t_data *data) +int process_redirect(t_process *p) { - if (data->exec.fdin != STDIN) + if (p->fdin != STDIN) { - dup2(data->exec.fdin, STDIN); - close(data->exec.fdin); + DG("redirect STDIN to %i", p->fdin); + dup2(p->fdin, STDIN); + close(p->fdin); } - if (data->exec.fdout != STDOUT) + if (p->fdout != STDOUT) { - dup2(data->exec.fdout, STDOUT); - close(data->exec.fdout); + DG("redirect STDOUT to %i", p->fdout); + dup2(p->fdout, STDOUT); + close(p->fdout); } + return (0); } diff --git a/42sh/src/exec/process_reset.c b/42sh/src/exec/process_reset.c new file mode 100644 index 00000000..4b3c02a9 --- /dev/null +++ b/42sh/src/exec/process_reset.c @@ -0,0 +1,8 @@ +#include "exec.h" + +void process_reset(void) +{ + t_data *data; + + data = data_singleton(); +} diff --git a/42sh/src/exec/process_setexec.c b/42sh/src/exec/process_setexec.c new file mode 100644 index 00000000..0baefd94 --- /dev/null +++ b/42sh/src/exec/process_setexec.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_setexec.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:07:10 by jhalford #+# #+# */ +/* Updated: 2017/01/10 13:17:23 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int process_setexec(t_process *p) +{ + if ((p->execf = is_builtin(p))) + { + p->attributes |= PROCESS_BUILTIN; + } + else if (ft_strchr(p->av[0], '/')) + { + p->execf = &execve; + p->attributes |= PROCESS_SCRIPT; + p->path = ft_strdup(p->av[0]); + } + else if ((p->path = ft_findexec(ft_getenv( + data_singleton()->env, "PATH"), p->av[0]))) + { + p->execf = &execve; + p->attributes |= PROCESS_BINARY; + } + else + { + p->execf = NULL; + p->attributes |= PROCESS_UNKNOWN; + return (1); + } + return (0); +} diff --git a/42sh/src/exec/process_setgroup.c b/42sh/src/exec/process_setgroup.c new file mode 100644 index 00000000..4dcdeda3 --- /dev/null +++ b/42sh/src/exec/process_setgroup.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_setgroup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 17:48:10 by jhalford #+# #+# */ +/* Updated: 2017/01/09 15:58:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" +#include "exec.h" + +int process_setgroup(t_process *p) +{ + t_job *job; + int pid; + + (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); + } + return (0); +} diff --git a/42sh/src/exec/set_exitstatus.c b/42sh/src/exec/set_exitstatus.c index 3a7dfd13..584abdcc 100644 --- a/42sh/src/exec/set_exitstatus.c +++ b/42sh/src/exec/set_exitstatus.c @@ -6,17 +6,17 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 14:25:17 by jhalford #+# #+# */ -/* Updated: 2016/12/07 16:29:11 by jhalford ### ########.fr */ +/* Updated: 2017/01/08 15:58:20 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void set_exitstatus(t_data *data, int status) +void set_exitstatus(int status) { char *astatus; astatus = ft_itoa(status); - builtin_setenv((char*[3]){"?", astatus}, data); + builtin_setenv("setenv", (char*[3]){"?", astatus}, data_singleton()->env); ft_strdel(&astatus); } diff --git a/42sh/src/job-control/builtin_bg.c b/42sh/src/job-control/builtin_bg.c new file mode 100644 index 00000000..9e98b5e6 --- /dev/null +++ b/42sh/src/job-control/builtin_bg.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_bg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 16:54:18 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:11:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + + +#include "job_control.h" + +int builtin_bg(const char *path, char *const av[], char *const envp[]) +{ + t_jobc *jobc; + t_job *job; + t_list *jlist; + int rank[2]; + int id; + + (void)path; + (void)envp; + (void)av; + jobc = &data_singleton()->jobc; + job_getrank(&rank); + id = av[1] ? ft_atoi(av[1]) : rank[0]; + if (id == 0 && !av[1]) + return (0); + jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id); + if (jlist) + { + job = jlist->content; + mark_job_as_running(job); + job_format(job, rank, JOBS_OPTS_L); + put_job_in_background(job, 1); + } + else + ft_dprintf(2, "{red}bg: job not found: %i{eoc}\n", id); + return (0); +} diff --git a/42sh/src/job-control/builtin_fg.c b/42sh/src/job-control/builtin_fg.c new file mode 100644 index 00000000..c594df80 --- /dev/null +++ b/42sh/src/job-control/builtin_fg.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_fg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 14:30:07 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:16:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int builtin_fg(const char *path, char *const av[], char *const envp[]) +{ + t_jobc *jobc; + t_job *job; + t_list *jlist; + int rank[2]; + int id; + + (void)path; + (void)envp; + (void)av; + jobc = &data_singleton()->jobc; + job_getrank(&rank); + id = av[1] ? ft_atoi(av[1]) : rank[0]; + if (id == 0 && !av[1]) + return (0); + jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id); + if (jlist) + { + job = jlist->content; + mark_job_as_running(job); + put_job_in_foreground(job, 1); + } + else + ft_dprintf(2, "{red}fg: job not found: [%i]{eoc}\n", id); + return (0); +} diff --git a/42sh/src/job-control/builtin_jobs.c b/42sh/src/job-control/builtin_jobs.c new file mode 100644 index 00000000..46b73513 --- /dev/null +++ b/42sh/src/job-control/builtin_jobs.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_jobs.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 17:43:01 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:16:16 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + + +int builtin_jobs(const char *path, char *const av[], char *const envp[]) +{ + t_jobc *jobc; + t_list *jlist; + t_list *tmplist; + int rank[2]; + int opts; + + (void)path; + (void)envp; + (void)av; + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + job_getrank(&rank); + opts = 0; + if (ft_strcmp(av[1], "-l") == 0) + opts |= JOBS_OPTS_L; + tmplist = ft_lst_filter(jlist, NULL, NULL); + ft_lstsort(&tmplist, job_cmp_id); + jlist = tmplist; + while (jlist) + { + job_format(jlist->content, rank, opts); + jlist = jlist->next; + } + ft_lstdel(&tmplist, ft_lst_cfree); + return (0); +} diff --git a/42sh/src/job-control/do_job_notification.c b/42sh/src/job-control/do_job_notification.c new file mode 100644 index 00000000..98db5d4d --- /dev/null +++ b/42sh/src/job-control/do_job_notification.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_job_notification.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 13:01:19 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:24:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int do_job_notification(void) +{ + t_job *j; + t_list *jlist; + t_jobc *jobc; + int ret; + + ret = 0; + job_update_status(); + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + j = jlist->content; + DG("checking [%i]", j->id); + if (job_is_completed(j->id)) + { + ret = 1; + job_notify_change(j->id); + job_remove(j->id); + } + else if (job_is_stopped(j->id) && !(j->attributes & JOB_NOTIFIED)) + { + ret = 1; + job_notify_change(j->id); + j->attributes |= JOB_NOTIFIED; + } + jlist = jlist->next; + } + return (ret); +} diff --git a/42sh/src/job-control/job_addprocess.c b/42sh/src/job-control/job_addprocess.c new file mode 100644 index 00000000..0215844a --- /dev/null +++ b/42sh/src/job-control/job_addprocess.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_addprocess.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 13:54:51 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:30:12 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int job_addprocess(t_process *p) +{ + t_jobc *jobc; + t_job *job; + + jobc = &data_singleton()->jobc; + job = &data_singleton()->exec.job; + if (IS_PIPESTART(p->attributes)) + { + job_update_id(); + job->id = jobc->current_id; + job->pgid = p->pid; + ft_lstadd(&jobc->first_job, ft_lstnew(job, sizeof(*job))); + /* DG("added new job [%i]", job->id); */ + } + job = jobc->first_job->content; + if (p->pid > 0) + { + ft_lsteadd(&job->first_process, ft_lstnew(p, sizeof(*p))); + /* DG("added pid=%i to [%i]", p->pid, job->id); */ + } + if (JOB_IS_BG(job->attributes) && IS_PIPEEND(p->attributes)) + job_notify_new(job); + return(0); +} diff --git a/42sh/src/main/lib_expansion.c b/42sh/src/job-control/job_cmp_id.c similarity index 64% rename from 42sh/src/main/lib_expansion.c rename to 42sh/src/job-control/job_cmp_id.c index 8905c284..cc9614d2 100644 --- a/42sh/src/main/lib_expansion.c +++ b/42sh/src/job-control/job_cmp_id.c @@ -1,28 +1,19 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* lib_expansion.c :+: :+: :+: */ +/* job_cmp_id.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/12/03 13:37:41 by jhalford #+# #+# */ -/* Updated: 2016/12/03 13:37:41 by jhalford ### ########.fr */ +/* Created: 2016/12/12 13:38:13 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:08:46 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void ft_expand_dollar(char **av, char **env) +int job_cmp_id(t_job *job, int *id) { - char *dollar; - - while (*av) - { - if ((dollar = ft_strchr(*av, '$'))) - { - *dollar = '\0'; - *av = ft_strjoin(*av, ft_getenv(env, dollar + 1)); - } - av++; - } + return (job->id - *id); } + diff --git a/42sh/src/job-control/job_format.c b/42sh/src/job-control/job_format.c new file mode 100644 index 00000000..1c8f3dd1 --- /dev/null +++ b/42sh/src/job-control/job_format.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_format.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 12:47:17 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:16:50 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_format(t_job *j, int rank[2], int opts) +{ + t_list *plist; + int firstp; + + job_format_head(j, rank); + plist = j->first_process; + firstp = 1; + while (plist) + { + process_format(&plist, firstp, opts); + firstp = 0; + } +} diff --git a/42sh/src/job-control/job_format_head.c b/42sh/src/job-control/job_format_head.c new file mode 100644 index 00000000..0dfcaaf9 --- /dev/null +++ b/42sh/src/job-control/job_format_head.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_format_head.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:10:38 by jhalford #+# #+# */ +/* Updated: 2017/01/09 13:53:48 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_format_head(t_job *j, int rank[2]) +{ + char crank; + + if (j->id == rank[0]) + crank = '+'; + else if (j->id == rank[1]) + crank = '-'; + else + crank = ' '; + ft_printf("{mag}[%i] %c ", j->id, crank); + ft_printf("{eoc}"); +} diff --git a/42sh/src/job-control/job_free.c b/42sh/src/job-control/job_free.c new file mode 100644 index 00000000..db63e7f2 --- /dev/null +++ b/42sh/src/job-control/job_free.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/01/09 13:22:16 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_free(void *content, size_t content_size) +{ + t_job *job; + + (void)content_size; + job = content; + ft_lstdel(&job->first_process, &process_free); + free(job); +} diff --git a/42sh/src/job-control/job_getprocess.c b/42sh/src/job-control/job_getprocess.c new file mode 100644 index 00000000..a4fa75ba --- /dev/null +++ b/42sh/src/job-control/job_getprocess.c @@ -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); +} diff --git a/42sh/src/job-control/job_getrank.c b/42sh/src/job-control/job_getrank.c new file mode 100644 index 00000000..8c7b6996 --- /dev/null +++ b/42sh/src/job-control/job_getrank.c @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_getrank.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 12:38:31 by jhalford #+# #+# */ +/* Updated: 2017/01/10 10:30:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_getrank(int (*rank)[2]) +{ + t_job *job; + t_jobc *jobc; + t_list *jlist; + int i; + + i = 0; + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + (*rank)[0] = 0; + (*rank)[1] = 0; + while (jlist && i < 2) + { + job = jlist->content; + if (job_is_stopped(job->id)) + (*rank)[i++] = job->id; + jlist = jlist->next; + } +} diff --git a/42sh/src/job-control/job_is_completed.c b/42sh/src/job-control/job_is_completed.c new file mode 100644 index 00000000..11ce8b55 --- /dev/null +++ b/42sh/src/job-control/job_is_completed.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_is_completed.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:10:20 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:30:33 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int job_is_completed(int id) +{ + t_list *lst; + t_job *job; + t_jobc *jobc; + t_process *p; + + jobc = &data_singleton()->jobc; + job = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content; + lst = job->first_process; + while (lst) + { + p = lst->content; + /* DG("checking pid=%i", p->pid); */ + if (!(p->attributes & PROCESS_COMPLETED)) + { + /* DG("process %i is not completed", p->pid); */ + return (0); + } + lst = lst->next; + } + return (1); +} diff --git a/42sh/src/job-control/job_is_stopped.c b/42sh/src/job-control/job_is_stopped.c new file mode 100644 index 00000000..7b4b5b85 --- /dev/null +++ b/42sh/src/job-control/job_is_stopped.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_is_stopped.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:06:45 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:30:05 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int job_is_stopped(int id) +{ + t_list *lst; + t_job *job; + t_jobc *jobc; + t_process *p; + + jobc = &data_singleton()->jobc; + job = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content; + lst = job->first_process; + while (lst) + { + p = lst->content; + if (!(p->attributes & (PROCESS_COMPLETED | PROCESS_SUSPENDED))) + return (0); + lst = lst->next; + } + return (1); +} diff --git a/42sh/src/job-control/job_kill_all.c b/42sh/src/job-control/job_kill_all.c new file mode 100644 index 00000000..1d36a8a6 --- /dev/null +++ b/42sh/src/job-control/job_kill_all.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_kill_all.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 15:36:56 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:35:51 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_kill_all(void) +{ + t_jobc *jobc; + t_list *jlist; + t_job *job; + + jobc = &data_singleton()->jobc; + jlist = jobc->first_job; + while (jlist) + { + job = jlist->content; + kill(-job->pgid, SIGKILL); + jlist = jlist->next; + } +} diff --git a/42sh/src/job-control/job_notify_change.c b/42sh/src/job-control/job_notify_change.c new file mode 100644 index 00000000..73f0a594 --- /dev/null +++ b/42sh/src/job-control/job_notify_change.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_notify_change.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 15:04:03 by jhalford #+# #+# */ +/* Updated: 2017/01/10 11:16:17 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_notify_change(int id) +{ + t_job *job; + t_jobc *jobc; + int rank[2]; + + jobc = &data_singleton()->jobc; + job = ft_lst_find(jobc->first_job, &id, job_cmp_id)->content; + job_getrank(&rank); + job_format(job, rank, JOBS_OPTS_L); +} diff --git a/42sh/src/job-control/job_notify_new.c b/42sh/src/job-control/job_notify_new.c new file mode 100644 index 00000000..1b39f0ea --- /dev/null +++ b/42sh/src/job-control/job_notify_new.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_notify_new.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 14:27:01 by jhalford #+# #+# */ +/* Updated: 2016/12/15 17:15:54 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_notify_new(t_job *job) +{ + t_list *plist; + t_process *p; + + ft_printf("{mag}[%i]", job->id); + plist = job->first_process; + while (plist) + { + p = plist->content; + ft_printf(" %i", p->pid); + plist = plist->next; + } + ft_printf("{eoc}\n"); +} diff --git a/42sh/src/job-control/job_remove.c b/42sh/src/job-control/job_remove.c new file mode 100644 index 00000000..ffeb3933 --- /dev/null +++ b/42sh/src/job-control/job_remove.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_remove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 12:51:08 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:31:00 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_remove(int id) +{ + t_jobc *jobc; + + jobc = &data_singleton()->jobc; + if (job_is_completed(id)) + { + /* DG("job_remove"); */ + 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); + } + /* else */ + /* DG("job_remove failed (not completed)"); */ +} diff --git a/42sh/src/job-control/job_update_id.c b/42sh/src/job-control/job_update_id.c new file mode 100644 index 00000000..08ac73d2 --- /dev/null +++ b/42sh/src/job-control/job_update_id.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_update_id.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 13:33:08 by jhalford #+# #+# */ +/* Updated: 2017/01/10 13:22:11 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void job_update_id(void) +{ + int *id; + t_jobc *jobc; + t_list *start; + + jobc = &data_singleton()->jobc; + id = &jobc->current_id; + start = jobc->first_job; + while (ft_lst_find(start, id, job_cmp_id)) + *id += 1; +} diff --git a/42sh/src/job-control/job_update_status.c b/42sh/src/job-control/job_update_status.c new file mode 100644 index 00000000..5426c5fc --- /dev/null +++ b/42sh/src/job-control/job_update_status.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_update_status.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 12:56:11 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:33:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void job_update_status(void) +{ + int status; + pid_t pid; + + pid = waitpid (WAIT_ANY, &status, WUNTRACED | WNOHANG); + while (!process_mark_status(pid, status)) + pid = waitpid (WAIT_ANY, &status, WUNTRACED | WNOHANG); +} diff --git a/42sh/src/job-control/job_wait.c b/42sh/src/job-control/job_wait.c new file mode 100644 index 00000000..9a892b03 --- /dev/null +++ b/42sh/src/job-control/job_wait.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* job_wait.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/15 11:49:05 by jhalford #+# #+# */ +/* Updated: 2017/01/08 16:00:23 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int job_wait(int id) +{ + pid_t pid; + int status; + + if (job_is_stopped(id) || job_is_completed(id)) + return (0); + pid = waitpid(WAIT_ANY, &status, WUNTRACED); + while (!process_mark_status(pid, status) + && !job_is_stopped(id) + && !job_is_completed(id)) + { + DG("waitpid now"); + pid = waitpid(WAIT_ANY, &status, WUNTRACED); + DG("waitpid done"); + } + return (0); +} diff --git a/42sh/src/job-control/mark_job_as_running.c b/42sh/src/job-control/mark_job_as_running.c new file mode 100644 index 00000000..0854b8d9 --- /dev/null +++ b/42sh/src/job-control/mark_job_as_running.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* mark_job_as_running.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/08 14:40:40 by jhalford #+# #+# */ +/* Updated: 2017/01/10 10:52:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void mark_job_as_running (t_job *j) +{ + t_list *plist; + t_process *p; + + plist = j->first_process; + while (plist) + { + p = plist->content; + if (p->attributes & PROCESS_SUSPENDED) + { + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes |= PROCESS_CONTINUED; + } + plist = plist->next; + } + j->attributes &= ~JOB_NOTIFIED; +} diff --git a/42sh/src/job-control/process_cmp_pid.c b/42sh/src/job-control/process_cmp_pid.c new file mode 100644 index 00000000..d0b3b09c --- /dev/null +++ b/42sh/src/job-control/process_cmp_pid.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_cmp_pid.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 13:00:21 by jhalford #+# #+# */ +/* Updated: 2016/12/12 13:40:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int process_cmp_pid(t_process *p, pid_t *pid) +{ + return (p->pid - *pid); +} diff --git a/42sh/src/job-control/process_format.c b/42sh/src/job-control/process_format.c new file mode 100644 index 00000000..92ad7d88 --- /dev/null +++ b/42sh/src/job-control/process_format.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_format.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/01/09 13:05:55 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:27:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +void process_format(t_list **plist, int firstp, int opts) +{ + t_process *p; + int state; + + p = (*plist)->content; + if (!firstp) + ft_printf(" "); + if (opts & JOBS_OPTS_L) + ft_printf("%i ", p->pid); + state = p->attributes & PROCESS_STATE_MASK; + if (state == PROCESS_RUNNING) + ft_putstr("running "); + else if (state == PROCESS_SUSPENDED) + ft_putstr("suspended"); + else if (state == PROCESS_CONTINUED) + { + ft_putstr("continued"); + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes |= PROCESS_RUNNING; + } + else if (state == PROCESS_COMPLETED) + { + if (p->status == 0) + ft_putstr("done "); + else + ft_printf("exit %i ", p->status); + } + ft_putchar('\t'); + if (opts & JOBS_OPTS_L) + { + ft_sstrprint(p->av, ' '); + if ((*plist)->next) + ft_putstr(" |"); + (*plist) = (*plist)->next; + } + else + { + while (*plist) + { + p = (*plist)->content; + if (!(p->attributes & state) || + (state == PROCESS_COMPLETED && p->status != 0)) + break; + if (p->attributes & PROCESS_CONTINUED) + { + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes &= ~PROCESS_RUNNING; + } + ft_sstrprint(p->av, ' '); + if ((*plist)->next) + ft_putstr(" | "); + (*plist) = (*plist)->next; + } + } + ft_putchar('\n'); +} diff --git a/42sh/src/job-control/process_free.c b/42sh/src/job-control/process_free.c new file mode 100644 index 00000000..ee4824e4 --- /dev/null +++ b/42sh/src/job-control/process_free.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/01/02 19:11:34 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->av); + free(p); +} diff --git a/42sh/src/job-control/process_mark_status.c b/42sh/src/job-control/process_mark_status.c new file mode 100644 index 00000000..49784124 --- /dev/null +++ b/42sh/src/job-control/process_mark_status.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* process_mark_status.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:28:22 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int process_mark_status(pid_t pid, int status) +{ + t_process *p; + + if (pid > 1) + { + if ((p = job_getprocess(pid))) + { + p->status = status; + if (WIFSTOPPED(status)) + { + /* DG("marking: pid=%i, status=%i (stopped sig %i)", pid, status, WTERMSIG(status)); */ + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes |= PROCESS_SUSPENDED; + } + else + { + /* DG("marking: pid=%i, status=%i (completed sig %i)", pid, status, WTERMSIG(status)); */ + p->attributes &= ~PROCESS_STATE_MASK; + p->attributes |= PROCESS_COMPLETED; + if (WIFSIGNALED(status)) + ft_printf("{mag}%d: Terminated by signal %d.\n{eoc}", + (int) pid, WTERMSIG(p->status)); + } + return(0); + } + ft_dprintf(2, "No child process %d.\n", pid); + return(-1); + } + return(-1); +} diff --git a/42sh/src/job-control/put_job_in_background.c b/42sh/src/job-control/put_job_in_background.c new file mode 100644 index 00000000..a23dee5e --- /dev/null +++ b/42sh/src/job-control/put_job_in_background.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* put_job_in_background.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 15:03:29 by jhalford #+# #+# */ +/* Updated: 2017/01/08 13:24:53 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int put_job_in_background(t_job *job, int cont) +{ + /* Send the job a continue signal, if necessary. */ + if (cont) + if (kill (-job->pgid, SIGCONT) < 0) + perror ("kill (SIGCONT)"); + return (0); +} diff --git a/42sh/src/job-control/put_job_in_foreground.c b/42sh/src/job-control/put_job_in_foreground.c new file mode 100644 index 00000000..59e265fc --- /dev/null +++ b/42sh/src/job-control/put_job_in_foreground.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* put_job_in_foreground.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/13 14:58:36 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:32:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "job_control.h" + +int put_job_in_foreground(t_job *job, int cont) +{ + t_jobc *jobc; + + jobc = &data_singleton()->jobc; + /* Send the job a continue signal, if necessary. */ + if (cont) + { + /* Put the job into the foreground. */ + signal(SIGTTOU, SIG_IGN); + if (tcsetpgrp(STDIN, job->pgid) == -1) + DG("couldn't put process in control. errno=%i, pgid=%i", errno, job->pgid); + signal(SIGTTOU, sigttou_handler); + tcsetattr (STDIN, TCSANOW, &job->tmodes); + if (kill(-job->pgid, SIGCONT) < 0) + perror("kill (SIGCONT)"); + } + /* Wait for it to report. */ + /* DG("gonna wait for job id=%i", job->id); */ + job_wait(job->id); + job_remove(job->id); + + /* Put the shell back in the foreground. */ + signal(SIGTTOU, SIG_IGN); + tcsetpgrp(STDIN, jobc->shell_pgid); + signal(SIGTTOU, sigttou_handler); + + /* Restore the shell’s terminal modes. */ + tcgetattr(STDIN, &job->tmodes); + tcsetattr(STDIN, TCSADRAIN, &jobc->shell_tmodes); + return (0); +} diff --git a/42sh/src/job-control/sigchld_handler.c b/42sh/src/job-control/sigchld_handler.c new file mode 100644 index 00000000..210f52a2 --- /dev/null +++ b/42sh/src/job-control/sigchld_handler.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigchld_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 17:37:56 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:33:18 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigchld_handler(int signo) +{ + t_data *data; + + (void)signo; + data = data_singleton(); + /* DG("got SIGCHLD"); */ + /* if (do_job_notification()) */ + /* ft_putstr(SHELL_PROMPT); */ + if (data_singleton()->mode != MODE_EXEC) + job_update_status(); +} diff --git a/42sh/src/main/sig_handler.c b/42sh/src/job-control/sigint_handler.c similarity index 68% rename from 42sh/src/main/sig_handler.c rename to 42sh/src/job-control/sigint_handler.c index d56b03ee..f15da9d3 100644 --- a/42sh/src/main/sig_handler.c +++ b/42sh/src/job-control/sigint_handler.c @@ -1,27 +1,19 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* sig_handler.c :+: :+: :+: */ +/* sigint_handler.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/12/01 12:43:22 by jhalford #+# #+# */ -/* Updated: 2016/12/03 13:31:33 by jhalford ### ########.fr */ +/* Created: 2016/12/10 15:14:47 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:16:20 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -pid_t g_pid; - -void sig_handler(int signo) +void sigint_handler(int signo) { (void)signo; - if (signo == SIGINT) - { - if (g_pid) - kill(g_pid, SIGINT); - if (kill(g_pid, 0) == 0) - ft_putendl(""); - } + DG("got SIGINT"); } diff --git a/42sh/src/job-control/sigtstp_handler.c b/42sh/src/job-control/sigtstp_handler.c new file mode 100644 index 00000000..aa138934 --- /dev/null +++ b/42sh/src/job-control/sigtstp_handler.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigtstp_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/01/10 10:30:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigtstp_handler(int signo) +{ + (void)signo; + DG("got SIGTSTP"); +} diff --git a/42sh/src/job-control/sigttin_handler.c b/42sh/src/job-control/sigttin_handler.c new file mode 100644 index 00000000..1b424bf5 --- /dev/null +++ b/42sh/src/job-control/sigttin_handler.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigttin_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/01/09 16:37:32 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigttin_handler(int signo) +{ + (void)signo; + DG("got SIGTTIN"); +} diff --git a/42sh/src/job-control/sigttou_handler.c b/42sh/src/job-control/sigttou_handler.c new file mode 100644 index 00000000..a999d1e1 --- /dev/null +++ b/42sh/src/job-control/sigttou_handler.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sigttou_handler.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */ +/* Updated: 2017/01/08 13:24:21 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigttou_handler(int signo) +{ + (void)signo; + DG("got SIGTTOU"); +} diff --git a/42sh/src/line-editing/rl_stack_line.c b/42sh/src/line-editing/rl_stack_line.c index 5c40ccb0..3e1a538b 100644 --- a/42sh/src/line-editing/rl_stack_line.c +++ b/42sh/src/line-editing/rl_stack_line.c @@ -6,7 +6,7 @@ /* By: sbenning +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/09 01:06:54 by sbenning #+# #+# */ -/* Updated: 2016/12/12 11:33:28 by sbenning ### ########.fr */ +/* Updated: 2017/01/10 13:07:37 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/42sh/src/main/data_exit.c b/42sh/src/main/data_exit.c index cd912115..e22c741d 100644 --- a/42sh/src/main/data_exit.c +++ b/42sh/src/main/data_exit.c @@ -6,16 +6,17 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/07 18:07:50 by jhalford #+# #+# */ -/* Updated: 2016/12/07 18:12:34 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:16:38 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void data_exit(t_data *data) +void data_exit(void) { - ft_strdel(&data->line.input); - ft_dlstdel(&data->line.history, &ft_lst_bfree); - ft_lstdel(&data->line.qstack, &ft_lst_cfree); + t_data *data; + + data = data_singleton(); + /* ft_strdel(&data->line.input); */ ft_sstrfree(data->env); } diff --git a/42sh/src/main/data_init.c b/42sh/src/main/data_init.c index 1a4fb1bb..1e09464b 100644 --- a/42sh/src/main/data_init.c +++ b/42sh/src/main/data_init.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/28 19:26:32 by jhalford #+# #+# */ -/* Updated: 2017/01/10 11:55:36 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:16:23 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,20 +14,30 @@ extern char **environ; -int data_init(t_data *data) +int data_init(void) { - char *term_name; + char *term_name; + t_data *data; - atexit(&ft_cleanup); + data = data_singleton(); data->line.input = NULL; data->env = ft_sstrdup(environ); - data->line.history = NULL; - data->exec.fdin = STDIN; - data->exec.fdout = STDOUT; + + data->exec.process.path = NULL; + data->exec.process.av = NULL; + data->exec.process.fdin = STDIN; + data->exec.process.fdout = STDOUT; + data->exec.process.pid = 0; + data->exec.process.attributes = PROCESS_PIPESTART | PROCESS_PIPEEND; + data->exec.aol_status = NULL; data->exec.aol_search = 0; - if (!(data->line.history = ft_dlstnew(NULL, 0))) - return (-1); + 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; if ((term_name = ft_getenv(data->env, "TERM")) == NULL) return (-1); if (tgetent(NULL, term_name) != 1) diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index 4103255e..ef64df79 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/06 18:40:58 by jhalford #+# #+# */ -/* Updated: 2017/01/10 11:56:39 by jhalford ### ########.fr */ +/* Updated: 2017/01/10 13:08:14 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,35 +14,30 @@ int main(void) { - t_data *data; t_list *token; t_btree *ast; token = NULL; ast = NULL; - data = data_singleton(); - if (data_init(data)) - return (1); - if (signal(SIGINT, sig_handler) == SIG_ERR) - ft_dprintf(STDERR, "\ncan't catch SIGINT\n"); + shell_init(); DG("{inv}{bol}{gre}start of shell"); while (1) { - if (ft_readline(&data->line)) + if (ft_readline(&data_singleton()->line)) return (1); - DG("{inv}{mag}got command '%s'", data->line.input); + DG("{inv}{mag}got command '%s'", data_singleton()->line.input); token = NULL; - if (ft_tokenize(&token, data->line.input, DEFAULT)) + if (ft_tokenize(&token, data_singleton()->line.input, DEFAULT)) return (1); if (!token) continue ; - token_print(token); + /* token_print(token); */ if (ft_parse(&ast, &token)) return (1); - btree_print(STDERR, ast, &ft_putast); - /* ft_dprintf(STDERR, "\n--- INFIX BREAKDOWN ---\n"); */ + btree_print(STDBUG, ast, &ft_putast); + /* ft_dprintf(STDBUG, "\n--- INFIX BREAKDOWN ---\n"); */ /* btree_apply_infix(ast, &ft_putast2); */ - if (ft_exec(&ast, data)) + if (ft_exec(&ast)) return (1); } return (0); diff --git a/42sh/src/main/ft_cleanup.c b/42sh/src/main/shell_exit.c similarity index 64% rename from 42sh/src/main/ft_cleanup.c rename to 42sh/src/main/shell_exit.c index 7cf6aa3b..a662e530 100644 --- a/42sh/src/main/ft_cleanup.c +++ b/42sh/src/main/shell_exit.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ft_cleanup.c :+: :+: :+: */ +/* shell_exit.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2016/12/01 14:42:42 by jhalford #+# #+# */ -/* Updated: 2016/12/09 21:50:38 by jhalford ### ########.fr */ +/* Created: 2016/12/12 17:37:04 by jhalford #+# #+# */ +/* Updated: 2017/01/10 13:13:51 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,15 +17,11 @@ extern char PC; extern char *UP; extern char *BC; -void ft_cleanup(void) +void shell_exit(void) { - struct termios term; - - DG("cleanup. char * UP at %p", UP); - DG("cleanup. char * BC at %p", BC); - if (tcgetattr(0, &term) == -1) - return ; - term.c_lflag |= ICANON | ISIG | ECHO; - if (tcsetattr(0, TCSANOW, &term) == -1) - return ; + /* DG("cleanup. char * UP at %p", UP); */ + /* DG("cleanup. char * BC at %p", BC); */ + data_exit(); + job_kill_all(); + tcsetattr(0, TCSANOW, &data_singleton()->jobc.shell_tmodes); } diff --git a/42sh/src/main/shell_init.c b/42sh/src/main/shell_init.c new file mode 100644 index 00000000..489dc44e --- /dev/null +++ b/42sh/src/main/shell_init.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/12/12 17:23:59 by jhalford #+# #+# */ +/* Updated: 2017/01/10 12:37:46 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_init(void) +{ + int *shell_pgid; + + shell_pgid = &data_singleton()->jobc.shell_pgid; + data_init(); + atexit(&shell_exit); + if (isatty(STDIN)) + { + while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp())) + kill(-*shell_pgid, SIGTTIN); + signal(SIGINT, sigint_handler); + signal(SIGQUIT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTIN, sigttin_handler); + signal(SIGTTOU, sigttou_handler); + signal(SIGCHLD, sigchld_handler); + *shell_pgid = getpid(); + if (setpgid(*shell_pgid, *shell_pgid)) + { + ft_dprintf(2, "Couldnt put the shell in it's own process group"); + exit (1); + } + tcsetpgrp(STDIN, *shell_pgid); + tcgetattr(STDIN, &data_singleton()->jobc.shell_tmodes); + } +} diff --git a/42sh/src/parser/ft_parse.c b/42sh/src/parser/ft_parse.c index 99565769..cd669aa6 100644 --- a/42sh/src/parser/ft_parse.c +++ b/42sh/src/parser/ft_parse.c @@ -14,8 +14,9 @@ t_parser g_parser[] = { - {TK_SEMI | TK_AMP, &parse_separator}, + {TK_SEMI, &parse_separator}, {TK_AND_IF | TK_OR_IF, &parse_separator}, + {TK_AMP, &parse_separator}, {TK_PIPE, &parse_separator}, {TK_LESS, &parse_less}, {TK_GREAT, &parse_great},