diff --git a/.gitignore b/.gitignore index af1dd7b..a290654 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .DS_Store* ._.DS_Store* *.swp +*.swo # Prerequisites *.d diff --git a/Makefile b/Makefile index ebafcbb..ff6135d 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,17 @@ NAME = minishell -SRCFILES = ast.c \ +SRCFILES = 42sh_header.c \ + ast.c \ ast_free.c \ ast_get.c \ ast_helper.c \ - ast_main.c \ ast_parse.c \ ast_print.c \ ast_validate.c \ autocomplete.c \ builtin_cd.c \ builtins.c \ + builtin_bg.c \ + builtin_jobs.c \ builtins_env.c \ char_array.c \ child_argv.c \ @@ -37,14 +39,13 @@ SRC = $(addprefix src/,$(SRCFILES)) OBJ = $(addprefix obj/,$(OBJFILES)) CC = gcc FLAGS = -g -Wextra -Wall -Werror -INC = -I libft/ -I libft/ft_printf/ -I inc/ +INC = -I libft/inc -I inc/ LIB = -L libft/ -lft -ltermcap all:$(NAME) $(NAME): $(OBJ) make -C libft/ -# make -C libft/ft_printf/ $(CC) $(FLAGS) -o $@ $^ $(LIB) objdir: @@ -58,15 +59,18 @@ rmobj: rmbin: rm -rf $(NAME) + rm -rf ASTDEMO again: rmobj rmbin all +ast: + make -C libft/ + gcc -o ASTDEMO src/ast*.c -L libft/ -l ft -I libft/inc + clean: rmobj make clean -C libft/ -# make clean -C libft/ft_printf/ fclean: clean rmbin make fclean -C libft/ -# make fclean -C libft/ft_printf/ re: fclean all diff --git a/inc/minishell.h b/inc/minishell.h index abb3749..ea0f489 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -6,7 +6,7 @@ /* By: asarandi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/03/30 19:50:54 by asarandi #+# #+# */ -/* Updated: 2018/04/11 18:15:27 by asarandi ### ########.fr */ +/* Updated: 2018/04/16 00:32:30 by ztisnes ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,9 +36,16 @@ typedef struct s_av char **argv; } t_av; +typedef struct s_io +{ + int stdin; + int stdout; + int stderr; +} t_io; typedef struct s_process { + char *fullpath; char **argv; char **envp; pid_t pid; @@ -47,6 +54,11 @@ typedef struct s_process int fd[2]; } t_process; +typedef struct s_group +{ + t_process **p; +} t_group; + typedef struct s_exec { char *cmd; @@ -84,7 +96,6 @@ typedef struct s_shell int state; t_exec *exec; t_exec *last_exec; - } t_shell; t_shell *g_sh; diff --git a/job_control/builtin_bg.c b/job_control/builtin_bg.c new file mode 100644 index 0000000..d9c9437 --- /dev/null +++ b/job_control/builtin_bg.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_bg.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/16 01:27:04 by ztisnes #+# #+# */ +/* Updated: 2018/04/16 03:00:51 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell" +#include + +// int getnum(char *str) +// { +// int num; +// int sign; +// +// num = 0; +// if (str == NULL) +// return (num); +// str = getsign() +// } + +int ft_atoi(char *str) +{ + int i; + int flag; + long number; + + i = 0; + flag = 1; + number = 0; + while ((str[i] == ' ') || (str[i] == '\t') || (str[i] == '\n') \ + || (str[i] == '\v') || (str[i] == '\r') || (str[i] == '\f')) + i++; + if (str[i] == '-') + flag = -1; + if ((str[i] == '-') || (str[i] == '+')) + i++; + while ((str[i] >= '0') && (str[i] <= '9')) + { + number *= 10; + number += ((int)str[i] - '0'); + i++; + } + return (number * flag); +} + +void builtin_bg(t_process *cmd, t_group *sh) +{ + int num; + int i; + int pgid; + + i = 0; + num = 0; + if (!sh->p) + return ; + if (cmd->argv[1]) + num = ft_atoi((cmd->argv[1]) - 1); + while ((sh->p[i] != NULL) && (i < num)) + i++; + if (sh->p[i] != NULL) + { + pgid = sh->p[i]->pid.pgid; + printf("%d\n", pgid); + kill(-pgid, SIGCONT); + } +} diff --git a/job_control/builtin_jobs.c b/job_control/builtin_jobs.c new file mode 100644 index 0000000..19e259f --- /dev/null +++ b/job_control/builtin_jobs.c @@ -0,0 +1,101 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtin_jobs.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/13 23:50:39 by ztisnes #+# #+# */ +/* Updated: 2018/04/16 01:49:14 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +// #include "minishell.h" + +#define _POSIX_SOURCE +#include +#include +#include +#include + +/* +** //TODO: +** jobs: Display the current program that is executed from the list +** job control functions that returns true or/and false when program is successful +** Create a signal with the PID once it is suspended after command is running (bg, fg) +** Ctrl Z for suspend -> kill(pid, SIGSTOP) +** Ctrl C kills the process -> kill(pid, SIGINT) +** fg: foreground +** bg: background +** &: echos the process +*/ + +// void builtin_fg(t_exec *cmd, t_shell *sh) +// { +// +// } + +// void builtin_ampersand() +// { +// +// } +void builtin_jobs(t_io *fd, t_process *sh) +{ + int i; + char *tmp; + t_queue *node; + t_process *pipeline; + + i = -1; + node = init_queue(); + if (sh->p != NULL) + { + while (pipeline = sh->p[++i] != NULL) + { + //Maybe use queue or printf here? + tmp = ft_base64encode("0123456789", (i + 1)); + ft_putstr_fd("[", fd->stdout); + ft_putstr_fd(tmp, fd->stdout); + ft_putstr_fd("]", fd->stdout); + ft_putstr_fd(pipeline->fullpath, fd->stdout); + ft_putstr_fd("\n", fd->stdout); + free(tmp); + } + } + free(fd); +} + +int main(void) +{ + pid_t pid; + int p1[2], p2[2]; + char c = '?'; + + if (pipe(p1) != 0) + perror("pipe() #1 error"); + else if (pipe(p2) != 0) + perror("pipe() #2 error"); + else + { + if ((pid = fork()) == 0) + { + printf("child's process group id is %d\n", (int)getpgrp()); + write(p2[1], &c, 1); + puts("child is waiting for parent to complete task"); + read(p1[0], &c, 1); + printf("child's process group id is now %d\n", (int)getpgrp()); + exit(0); + } + else + { + printf("parent's process group id is %d\n", (int)getpgrp()); + read(p2[0], &c, 1); + printf("parent is performing setpgid() on pid %d\n",(int)pid); + if (setpgid(pid, 0) != 0) + perror("setpgid() error"); + write(p1[1], &c, 1); + printf("parent's process group id is now %d\n", (int)getpgrp()); + sleep(5); + } + } +} diff --git a/job_control/test.c b/job_control/test.c new file mode 100644 index 0000000..e071232 --- /dev/null +++ b/job_control/test.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/15 18:25:40 by ztisnes #+# #+# */ +/* Updated: 2018/04/15 18:33:47 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include +int main() { + + Queue* q = init_queue(); + + printf("Empty? %d\n", isEmpty(q)); + printf("Enqueueing 'Hello'\n"); + ft_enqueue(q, "Hello"); + printf("Empty? %d\n", isEmpty(q)); + printf("Peeking: %s\n", peek_queue(q)); + printf("Enqueueing 'World'\n"); + ft_enqueue(q, "World"); + printf("Empty? %d\n", isEmpty(q)); + printf("Peeking: %s\n", peek_queue(q)); + printf("Enqueueing ':)'\n"); + ft_enqueue(q, ":)"); + printf("Empty? %d\n", isEmpty(q)); + printf("Peeking: %s\n", peek_queue(q)); + printf("Dequeue: %s\n", ft_dequeue(q)); + printf("Dequeue: %s\n", ft_dequeue(q)); + printf("Dequeue: %s\n", ft_dequeue(q)); + printf("Dequeue: %s\n", ft_dequeue(q)); + printf("Empty? %d\n", isEmpty(q)); + + return 0; +} diff --git a/libft/Makefile b/libft/Makefile index 15b1051..46d8cd0 100644 --- a/libft/Makefile +++ b/libft/Makefile @@ -6,7 +6,7 @@ # By: asarandi +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2017/09/20 17:41:00 by asarandi #+# #+# # -# Updated: 2018/04/10 21:56:26 by asarandi ### ########.fr # +# Updated: 2018/04/14 18:02:29 by ztisnes ### ########.fr # # # # **************************************************************************** # @@ -80,6 +80,7 @@ FILES = ft_str_append.c \ ft_tolower.c \ ft_toupper.c \ ft_uriencode.c \ + queue.c \ get_next_line.c OBJ = $(FILES:%.c=%.o) diff --git a/libft/libft.h b/libft/libft.h index 581c9bf..bbc8304 100644 --- a/libft/libft.h +++ b/libft/libft.h @@ -6,7 +6,7 @@ /* By: asarandi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/09/20 17:51:15 by asarandi #+# #+# */ -/* Updated: 2018/04/10 21:55:43 by asarandi ### ########.fr */ +/* Updated: 2018/04/15 01:48:45 by ztisnes ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,12 @@ # include # define BUFF_SIZE 1 +typedef struct s_queue +{ + t_node *first; + t_node *last; +} t_queue; + typedef struct s_list { void *content; diff --git a/libft/queue.c b/libft/queue.c new file mode 100644 index 0000000..ea84d1c --- /dev/null +++ b/libft/queue.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* queue.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/14 17:59:27 by ztisnes #+# #+# */ +/* Updated: 2018/04/15 18:54:34 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "libft.h" + +t_queue *init_queue(void) +{ + t_queue *node; + node = (t_queue *)ft_memalloc(sizeof(t_queue)); + node->first = NULL; + node->last = NULL; + return (node); +} + +void ft_enqueue(t_queue *queue, void *content) +{ + t_list *node; + node = (t_list *)ft_memalloc(sizeof(t_list)); + node->content = content; + node->next = NULL; + if (!queue->last) + { + queue->last = node; + queue->first = node; + } + else + { + queue->last->next = node; + queue->last = queue->last->next; + } + return ; +} + +void *ft_dequeue(t_queue *queue) +{ + t_list *tmp; + + tmp = queue->first; + if (tmp) + { + queue->first = tmp->next; + return (tmp->content); + } + return (NULL); +} + +void *peek_queue(t_queue *queue) +{ + if (queue->first == NULL) + return (NULL); + return (queue->first->content); +} + +int isEmpty(t_queue *queue) +{ + return (queue->first == NULL); +} diff --git a/src/42sh_header.c b/src/42sh_header.c new file mode 100644 index 0000000..180d4d1 --- /dev/null +++ b/src/42sh_header.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* 42sh_header.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/13 17:24:17 by ztisnes #+# #+# */ +/* Updated: 2018/04/14 10:41:20 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include + +void cmd_title(void) +{ + ft_printf(STDOUT_FILENO, "******************"); + ft_printf(STDOUT_FILENO, "* *"); + ft_printf(STDOUT_FILENO, "* Help menu *"); + ft_printf(STDOUT_FILENO, "* *"); + ft_printf(STDOUT_FILENO, "******************"); +} + +void header_sh(void) +{ + ft_printf(STDOUT_FILENO, " @@@@@@@@ @@\n"); + ft_printf(STDOUT_FILENO, " @@@ @@\n"); + ft_printf(STDOUT_FILENO, " @@ @\n"); + ft_printf(STDOUT_FILENO, " @@ @\n"); + ft_printf(STDOUT_FILENO, " @ @\n"); + ft_printf(STDOUT_FILENO, " @ @\n"); + ft_printf(STDOUT_FILENO, " #@@ @@@@ .@\n"); + ft_printf(STDOUT_FILENO, " @@@ @ @@@@@\n"); + ft_printf(STDOUT_FILENO, " @ @@ @\'\n"); + ft_printf(STDOUT_FILENO, " @ @@ @\n"); + ft_printf(STDOUT_FILENO, " @ @@ @\n"); + ft_printf(STDOUT_FILENO, " @ @@ @\n"); + ft_printf(STDOUT_FILENO, "@ @ @@ @\n"); + ft_printf(STDOUT_FILENO, " @@ @ @ @ /\n"); + ft_printf(STDOUT_FILENO, " @@@ @@@@@ /' /' @@\n"); + ft_printf(STDOUT_FILENO, " @@@ @ @@@@\n"); +} + +void header_42(void) +{ + ft_printf(1, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@/ @@@@& @ @\n"); + ft_printf(1, "@@@@@@@@@@@@@/ @@@@@@& @@@ @\n"); + ft_printf(1, "@@@@@@@@@@@/ @@@@@@@@& @@@@@ @\n"); + ft_printf(1, "@@@@@@@@@/ @@@@@@@@@@& @@@@@@@ @\n"); + ft_printf(1, "@@@@@@@/ @@@@@@@@@@@@@@@@@@@@( @@\n"); + ft_printf(1, "@@@@@/ @@@@@@@@@@@@@@@@@@@@( @@@@\n"); + ft_printf(1, "@@@/ @@@@@@@@@@@@@@@@@@@@( @@@@@@\n"); + ft_printf(1, "@/ @@@@@@@@@@@@@@@@@@@@( @@@@@@@@\n"); + ft_printf(1, "@ ,,,,,,,,,,,,,,,,,@@@& @@@@@@@@@@\n"); + ft_printf(1, "@ @@@& @@@@@@/ @@\n"); + ft_printf(1, "@ @@@& @@@@* @@\n"); + ft_printf(1, "@ @@@& @@. @@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@@, @@@& / @@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@\n"); + ft_printf(1, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); +} diff --git a/src/builtins.c b/src/builtins.c index 6ee4375..afba3ea 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -6,15 +6,27 @@ /* By: asarandi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/04/06 05:06:58 by asarandi #+# #+# */ -/* Updated: 2018/04/11 23:27:00 by asarandi ### ########.fr */ +/* Updated: 2018/04/14 10:40:18 by ztisnes ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" +char *g_builtin_list[] = { + "cd", "echo", "env", + "exit", "setenv", "unsetenv"}; +char *g_punani_list[] = { + "Compact disc; access to other folders or directories", + "Display given string", "Set environment and execute command, or print\ + environment", "Terminate program", "function inserts or resets the\ + environment variable name in the current environment list", + "function deletes all instances of the variable name pointed to\ + by name from the list" + }; + int builtin_cmd_index(char *cmd) { - int i; + int i; const char *builtin_list[] = { "echo", "cd", "setenv", "unsetenv", "env", "exit", "help"}; @@ -52,7 +64,7 @@ int builtin_echo(t_shell *sh, char **argv) return (0); } -char *builtin_cd_get_kv(t_shell *sh, char *variable) +char *builtin_cd_get_kv(t_shell *sh, char *variable) { char *result; @@ -63,15 +75,15 @@ char *builtin_cd_get_kv(t_shell *sh, char *variable) return (result); } -int builtin_exit(t_shell *sh, char **argv) +int builtin_exit(t_shell *sh, char **argv) { int exit_code; - if ((argv[1] != NULL) && - ((is_numeric_string(argv[1])) || - ((argv[1][0] == '-') && - (is_numeric_string(&argv[1][1]))))) - exit_code = ft_atoi(argv[1]); + if ((argv[1] != NULL) && \ + ((is_numeric_string(argv[1])) || \ + ((argv[1][0] == '-') && \ + is_numeric_string(&argv[1][1])))) + exit_code = ft_atoi(argv[1]); else exit_code = sh->exit_code; ft_printf(STDERR_FILENO, "exit\n"); @@ -80,25 +92,53 @@ int builtin_exit(t_shell *sh, char **argv) return (exit_code); } +void help_selection(char *cmd) +{ + int i; + + i = 0; + while (g_builtin_list[i] != '\0') + { + if (g_builtin_list[i] && (i >= 0)) + { + if (ft_strcmp(cmd ,g_builtin_list[i]) == 0) + return (void)printf("\n\033[37;1m\t%s\033[0m -> %s\n\n", \ + g_builtin_list[i], g_punani_list[i]); + i++; + } + } +} -void builtin_help_cd(void) +void help_list(void) { - ft_printf(1, "cd means compact disc\n"); + int i; + int j; + + i = 0; + j = 0; + cmd_title(); + while (g_builtin_list[i] != '\0') + { + j++; + if (i >= 0 && i < 6) + printf("\n(%d) Only if I'm \033[37;1m%s\033[0m\n\n", \ + j, g_builtin_list[i]); + i++; + } } int builtin_help(t_shell *sh, char **argv) { sh->argc += 0; argv[0] += 0; - if ((argv[1] != NULL) && (ft_strcmp(argv[1], "cd") == 0)) - builtin_help_cd(); - - ft_printf(STDOUT_FILENO, "this is a help message for %s\n", SHELL_NAME); - ft_printf(STDOUT_FILENO, "\t\tcd\t\tthis is a help message\n"); - ft_printf(STDOUT_FILENO, "\t\techo\t\tthis is a help message\n"); - ft_printf(STDOUT_FILENO, "\t\texit\t\tthis is a help message\n"); - ft_printf(STDOUT_FILENO, "\t\tenv\t\tthis is a help message\n"); - ft_printf(STDOUT_FILENO, "\t\tsetenv\t\tthis is a help message\n"); - ft_printf(STDOUT_FILENO, "\t\tunsetenv\t\tthis is a help message\n"); + if (argv[1] != NULL) + { + if (argv[2]) + ft_printf(1, "No more than 1 help command. Do `help [cmd]`\n"); + else + help_selection(argv[1]); + } + else + help_list(); return (0); } diff --git a/src/help_builtin.c b/src/help_builtin.c new file mode 100644 index 0000000..f8f988e --- /dev/null +++ b/src/help_builtin.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* help_builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ztisnes +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2018/04/12 01:49:49 by ztisnes #+# #+# */ +/* Updated: 2018/04/12 01:52:40 by ztisnes ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *g_builtin_list[] = { + "cd", "echo", "env", + "exit", "setenv", "unsetenv"}; + +char *g_punani_list[] = { + "Compact disc; access to other folders or directories", + "Display given string", "Set environment and execute command, or print\ + environment", "Terminate program", "function inserts or resets the\ + environment variable name in the current environment list", + "function deletes all instances of the variable name pointed to\ + by name from the list" + }; + +void help_selection(char *cmd) +{ + int i; + + i = 0; + while (g_builtin_list[i] != '\0') + { + if (g_builtin_list[i] && (i >= 0)) + { + if (ft_strcmp(cmd ,g_builtin_list[i]) == 0) + return (void)printf("Only if I'm %s -> %s\n", \ + g_builtin_list[i], g_punani_list[i]); + i++; + } + } +} + +void help_list(void) +{ + int i; + + i = 0; + while (g_builtin_list[i] != '\0') + { + if (g_builtin_list[i] && (i >= 0)) + { + printf("Only if im %s -> ", g_builtin_list[i]); + if (i == 0) + printf("\taccess directories/folder\n"); + else if (i == 1) + printf("\tprint stuff\n"); + else if (i == 2) + printf("\tenv stuff\n"); + else if (i == 3) + printf("\texit stuff\n"); + else if (i == 4) + printf("\tsetenv stuff\n"); + else if (i == 5) + printf("\tunsetenv stuff\n"); + else + break ; + i++; + } + } +}