diff --git a/Makefile.am b/Makefile.am index 22315e6417fcc5b10293dbd97e367ee1fe4892eb..4059eac165550c37e1c50c1a40e99d392101511f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS=42sh +bin_PROGRAMS= 42sh 42sh_SOURCES= src/ast/ast.h \ src/ast/ast_and.c \ @@ -22,8 +22,12 @@ bin_PROGRAMS=42sh src/builtin/builtin_alias.c \ src/builtin/builtin_cd.c \ src/builtin/builtin_echo.c \ + src/builtin/builtin_exec.c \ src/builtin/builtin_exit.c \ + src/builtin/builtin_export.c \ src/builtin/builtin_unalias.c \ + src/builtin/builtin_unset.c \ + src/builtin/builtin_set.c \ src/builtin/builtin_shopt.c \ src/common/basename.c \ src/common/constant.h \ @@ -39,14 +43,18 @@ bin_PROGRAMS=42sh src/exec/exec.h \ src/exec/exec_and.c \ src/exec/exec_bang.c \ + src/exec/exec_case.c \ src/exec/exec_cmd.c \ + src/exec/exec_for.c \ src/exec/exec_funcdec.c \ src/exec/exec_node.c \ src/exec/exec_or.c \ src/exec/exec_if.c \ + src/exec/exec_pipe.c \ src/exec/exec_red.c \ src/exec/exec_sep.c \ src/exec/exec_sepand.c \ + src/exec/exec_subshell.c \ src/exec/exec_while.c \ src/parser/getline.c \ src/parser/getline.h \ diff --git a/configure.ac b/configure.ac index 3f77a485a8d9608555bafd4f047312580ea94f49..5f7fdf9f160ea61b66cd72742169a0a5cfd59fde 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,6 @@ AC_FUNC_CLOSEDIR_VOID AC_FUNC_REALLOC AC_FUNC_FORK AC_FUNC_STAT -AC_FUNC_ALLOCA AC_HEADER_DIRENT AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([malloc.h]) @@ -69,13 +68,13 @@ AC_CHECK_FUNCS([strstr]) AC_CHECK_FUNCS([atexit]) AC_CHECK_FUNCS([putenv]) AC_CHECK_FUNCS([strtoul]) +AC_CHECK_FUNCS([strerror]) AC_TYPE_PID_T AC_TYPE_SIZE_T # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST - AC_HEADER_STDBOOL AC_STRUCT_TM @@ -120,7 +119,6 @@ AC_ARG_WITH([efence], ] ) - AC_SUBST([CFLAGS]) AC_SUBST([LDFLAGS]) diff --git a/src/ast/ast.h b/src/ast/ast.h index 7fdba85d6775fca92c448ce0fc786543808573e6..158e640f864b1c63845213e3d26fbba6357da807 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:40:03 2006 Seblu -** Last update Thu Nov 16 17:01:11 2006 seblu +** Last update Fri Nov 17 14:17:02 2006 seblu */ #ifndef AST_H_ @@ -104,9 +104,9 @@ typedef struct cmd_node /* ** Binary ast node -** Generic node, it's a contener ! -** T_PIPE, T_SEP* , T_AND, T_OR : binary operator -** T_BANG : unary operator +** Generic node, it's a contener for: +** T_PIPE, T_SEP, T_SEPAND , T_AND, T_OR : binary operator +** T_BANG, T_SUBSHELL : unary operator */ typedef struct bin_node { diff --git a/src/builtin/builtin.c b/src/builtin/builtin.c index 85f37082984e07752b0e6e6dd2f18f6cb94fa304..e974fd2c4bd0e99f80dbfb218f14d5914be42cb6 100644 --- a/src/builtin/builtin.c +++ b/src/builtin/builtin.c @@ -5,14 +5,14 @@ ** Login ** ** Started on Tue Apr 11 00:22:44 2006 Seblu -** Last update Thu Nov 16 18:59:29 2006 seblu +** Last update Fri Nov 17 13:12:22 2006 seblu */ #include #include #include "builtin.h" -enum { BUILTIN_COUNT = 10 }; +enum { BUILTIN_COUNT = 12 }; struct builtin_table { @@ -29,9 +29,11 @@ static struct builtin_table builtin_table[BUILTIN_COUNT] = {"alias", builtin_alias}, {"unalias", builtin_unalias}, {"source", NULL}, //builtin_source}, - {"set", NULL}, //builtin_set}, - {"unset", NULL}, //builtin_unset}, - {"export", NULL}, //builtin_export} + {".", NULL}, //builtin_source}, + {"set", builtin_set}, + {"unset", builtin_unset}, + {"export", builtin_export}, + {"exec", builtin_exec} }; int is_a_builtin(const char *name) diff --git a/src/builtin/builtin.h b/src/builtin/builtin.h index aac80ad8264f710174fc27546f1f2dc0c9bcef88..55498dc1e496e7ec97c046a1f0b277a0350d53b9 100644 --- a/src/builtin/builtin.h +++ b/src/builtin/builtin.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Nov 12 16:46:24 2006 Seblu -** Last update Thu Nov 16 17:49:13 2006 seblu +** Last update Fri Nov 17 13:01:45 2006 seblu */ #ifndef BUILTIN_H_ @@ -67,12 +67,31 @@ int builtin_shopt(char *argv[]); */ int builtin_exit(char *argv[]); +/*! +** Set or show aliases. +** +** @param argv argument vector +** +** @return 0 on succes, or 1 if no alias found +*/ +int builtin_alias(char *argv[]); + +/*! +** Unset one or more aliases +** +** @param argv argument vector +** +** @return 0 on success, or 1 if no alias found +*/ +int builtin_unalias(char *argv[]); + + int builtin_source(char *argv[]); +int builtin_set(char *argv[]); int builtin_unset(char *argv[]); +int builtin_exec(char *argv[]); int builtin_export(char *argv[]); -int builtin_alias(char *argv[]); -int builtin_unalias(char *argv[]); /* diff --git a/src/builtin/builtin_alias.c b/src/builtin/builtin_alias.c index 07aa11938ef85f8b56805ed1823b2615ca969fe3..da282f220c530a64e49bc04bcbaa4af4588925a2 100644 --- a/src/builtin/builtin_alias.c +++ b/src/builtin/builtin_alias.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Nov 16 17:18:24 2006 seblu -** Last update Thu Nov 16 19:27:01 2006 seblu +** Last update Fri Nov 17 12:43:05 2006 seblu */ #include @@ -14,7 +14,6 @@ #include "builtin.h" #include "../shell/shell.h" -static int show_all_alias(void); static int show_alias(const char *name); static int getoption(char *argv[], int *argp, int *p); @@ -23,23 +22,26 @@ int builtin_alias(char *argv[]) int argp; char *carg; char *equal; - int show = 0; + int all = 0; + int ret = 0; assert(argv && argv[0]); - if (!getoption(argv, &argp, &show)) + if (!getoption(argv, &argp, &all)) return 2; - if (argv[1] == NULL || show) - return show_all_alias(); + if (argv[1] == NULL || all) + for (size_t i = 0; i < shell->alias->count; ++i) + printf("alias %s='%s'\n", shell->alias->table[i].name, + shell->alias->table[i].value); for (; (carg = argv[argp]); ++argp) { if (!(equal = strchr(carg, '='))) - show_alias(carg); + ret = show_alias(carg) || ret; else { *equal = 0; alias_add(shell->alias, strdup(carg), strdup(equal + 1)); *equal = '='; } } - return 0; + return ret; } static int getoption(char *argv[], int *argp, int *p) @@ -57,6 +59,8 @@ static int getoption(char *argv[], int *argp, int *p) fprintf(stderr, "alias: usage: alias [-p] [name[=value]] ... ]\n"); return 0; } + else + break; return 1; } @@ -64,18 +68,10 @@ static int show_alias(const char *name) { for (size_t i = 0; i < shell->alias->count; ++i) if (!strcmp(shell->alias->table[i].name, name)) { - printf("alias %s=%s\n", shell->alias->table[i].name, + printf("alias %s='%s'\n", shell->alias->table[i].name, shell->alias->table[i].value); - return 1; + return 0; } printf("%s: alias: %s: not found.\n", shell->name, name); - return 0; -} - -static int show_all_alias(void) -{ - for (size_t i = 0; i < shell->alias->count; ++i) - printf("alias %s=%s\n", shell->alias->table[i].name, - shell->alias->table[i].value); - return 0; + return 1; } diff --git a/src/builtin/builtin_doubledot.c b/src/builtin/builtin_doubledot.c deleted file mode 100644 index b340b8f34545563191c4ab663b76f1a399d1f899..0000000000000000000000000000000000000000 --- a/src/builtin/builtin_doubledot.c +++ /dev/null @@ -1,33 +0,0 @@ -/* -** builtin_doubledot.c for 42sh in /home/seblu/devel/c/towork/42sh -** -** Made by Seblu -** Login -** -** Started on Sat Apr 8 18:02:31 2006 Seblu -** Last update Sun Apr 9 12:38:38 2006 SIGOURE Benoit -*/ - -#include -#include "builtin.h" - -#include "mem.h" - -/*! -** Builtin double dot, allow you to cdup -** -** @param argv argv vector -** @param sh sh data -** -** @return builtin return success -*/ -int builtin_doubledot(char *argv[], struct s_42sh *sh) -{ - char *argv2[3]; - - argv2[0] = "cd"; - argv2[1] = ".."; - argv2[2] = NULL; - return builtin_cd(argv2, sh); - argv = argv; -} diff --git a/src/builtin/builtin_exec.c b/src/builtin/builtin_exec.c index a2dd6bf5788a9333b0234fdce523cb6eb0c9c077..caf2a64648acc3e807aa5280daf01420c9ef681a 100644 --- a/src/builtin/builtin_exec.c +++ b/src/builtin/builtin_exec.c @@ -5,34 +5,24 @@ ** Login ** ** Started on Thu May 11 10:00:36 2006 Seblu -** Last update Sun May 21 18:42:29 2006 Seblu +** Last update Fri Nov 17 13:01:59 2006 seblu */ #include #include +#include +#include #include -#include "builtin.h" -#include "../main/42sh.h" +#include "../shell/shell.h" -/*! -** Replace current process by which is given in arg -** -** @param argv arg vector -** @param sh shell struct -** -** @return success status -*/ -int builtin_exec(char *argv[], struct s_42sh *sh) +int builtin_exec(char *argv[]) { - assert(sh && argv); - if (!argv[1]) - return 0; - if (execvp(argv[1], argv + 1) == -1) - { - perror("42sh: exec"); - return 127; - } - return 0; - argv = argv; - sh = sh; + assert(argv); + if (!argv[1]) + return 0; + if (execvp(argv[1], argv + 1) == -1) { + fprintf(stderr, "%s: exec: %s.\n", shell->name, strerror(errno)); + return 127; + } + return 0; } diff --git a/src/builtin/builtin_export.c b/src/builtin/builtin_export.c index 85f9711f529a0be9952c43316c12718445cb08ad..fd9b1347b2e108d9d4968974e6b2b94b68f8e3f0 100644 --- a/src/builtin/builtin_export.c +++ b/src/builtin/builtin_export.c @@ -1,20 +1,21 @@ /* -** builtin_export.c for 42sh in /goinfre/seblu/42sh/src/builtin +** builtin_export.c for 42sh ** ** Made by Seblu -** Login +** Login ** ** Started on Thu May 11 09:32:30 2006 Seblu -** Last update Thu May 11 09:41:01 2006 Seblu +** Last update Fri Nov 17 12:57:12 2006 seblu */ #include -#include "builtin.h" +#include +#include "../shell/shell.h" -int builtin_export(char *argv[], struct s_42sh *sh) +int builtin_export(char *argv[]) { - printf("export: not yet implemeted\n"); - sh = sh; - argv = argv; - return 1; + assert(argv); + fprintf(stderr, "%s: export: not yet implemeted.\n", shell->name); + argv = argv; + return 1; } diff --git a/src/builtin/builtin_funclist.c b/src/builtin/builtin_funclist.c deleted file mode 100644 index b2aee84fcfaf4f7f806ddd7dabe57579160ce54f..0000000000000000000000000000000000000000 --- a/src/builtin/builtin_funclist.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -** builtin_funclist.c for 42sh in /goinfre/seblu/42sh/src/builtin -** -** Made by Seblu -** Login -** -** Started on Thu May 11 10:00:36 2006 Seblu -** Last update Sun May 21 18:40:33 2006 Seblu -*/ - -#include -#include -#include "builtin.h" -#include "../func/function.h" -#include "../main/42sh.h" - -int builtin_funclist(char *argv[], struct s_42sh *sh) -{ - assert(sh); - /* FIXME - func_print(sh->funcs); - */ - printf("Not yet implemented !\n"); - return 0; - argv = argv; - sh = sh; -} diff --git a/src/builtin/builtin_history.c b/src/builtin/builtin_history.c deleted file mode 100644 index 1d8363256ac2fd931a2a72c194b6b0b5ecf76f30..0000000000000000000000000000000000000000 --- a/src/builtin/builtin_history.c +++ /dev/null @@ -1,38 +0,0 @@ -/* -** builtin_history.c for in /home/joel/42sh -** -** Made by joel -** Login -** -** Started on Wed May 17 12:28:30 2006 joel -** Last update Sun May 21 18:44:31 2006 Seblu -*/ - -#include -#include -#include "../main/42sh.h" -#include "../history/history.h" -#include "builtin.h" - - -/*! -** Builtin history. -** @param argv The tab of args: terminated by NULL, argv[0] = "cd" -** @param sh The 42sh structure -*/ -int builtin_history(char **argv, struct s_42sh *sh) -{ - struct s_my_dlist *list; - char *elem; - int count = 1; - - assert(sh && argv && argv[0]); - if (!sh->history->list) - return 0; - for (list = sh->history->list; list->next != NULL; list = list->next) - ; - for (; list; list = list->prev, ++count) - fprintf(stdout, " %i %s\n", count, elem = list->elem); - return 0; - argv = argv; -} diff --git a/src/builtin/builtin_set.c b/src/builtin/builtin_set.c index 464c50372dc1df0c363df8b822204357dea27b5f..d4f76c619ee79552c7e305af21a3a843e15c154a 100644 --- a/src/builtin/builtin_set.c +++ b/src/builtin/builtin_set.c @@ -1,20 +1,21 @@ /* -** builtin_set.c for 42sh in /goinfre/seblu/42sh/src/builtin +** builtin_set.c for 42sh ** ** Made by Seblu -** Login +** Login ** ** Started on Thu May 11 09:32:30 2006 Seblu -** Last update Thu May 11 09:38:54 2006 Seblu +** Last update Fri Nov 17 12:57:32 2006 seblu */ #include -#include "builtin.h" +#include +#include "../shell/shell.h" -int builtin_set(char *argv[], struct s_42sh *sh) +int builtin_set(char *argv[]) { - printf("set: not yet implemeted\n"); - sh = sh; - argv = argv; - return 1; + assert(argv); + fprintf(stderr, "%s: set: not yet implemeted.\n", shell->name); + argv = argv; + return 1; } diff --git a/src/builtin/builtin_simpledot.c b/src/builtin/builtin_simpledot.c deleted file mode 100644 index 418db4404aa7ad5293c51eed428e62def890839a..0000000000000000000000000000000000000000 --- a/src/builtin/builtin_simpledot.c +++ /dev/null @@ -1,33 +0,0 @@ -/* -** builtin_simpledot.c for 42sh in /home/seblu/devel/c/42sh -** -** Made by Seblu -** Login -** -** Started on Tue May 16 19:59:03 2006 Seblu -** Last update Tue May 16 20:10:11 2006 Seblu -*/ - -#include -#include -#include -#include -#include "builtin.h" - -#include "mem.h" - -/*! -** Builtin simple dot, equivalent to source -** -** @param argv argv vector -** @param sh sh data -** -** @return builtin return success -*/ -int builtin_simpledot(char *argv[], struct s_42sh *sh) -{ - assert(argv && sh); - free(argv[0]); - argv[0] = strdup("source"); - return builtin_source(argv, sh); -} diff --git a/src/builtin/builtin_source.c b/src/builtin/builtin_source.c index 6a430c04fbd2dc74d9d4cdc6a7a48595696ef0be..3911361e5b3fe5c95a6f9c64694c2e7a66254c74 100644 --- a/src/builtin/builtin_source.c +++ b/src/builtin/builtin_source.c @@ -1,11 +1,11 @@ /* -** builtin_source.c for 42sh in /goinfre/42sh/src +** builtin_source.c for 42sh ** ** Made by Seblu -** Login +** Login ** ** Started on Sun Apr 9 04:40:11 2006 Seblu -** Last update Sun May 21 18:35:59 2006 Seblu +** Last update Fri Nov 17 13:03:34 2006 seblu */ #include @@ -14,11 +14,9 @@ #include "../main/42sh.h" #include "../execution/execution.h" -#include "mem.h" - static int builtin_source_error(int err); -int builtin_source(char *argv[], struct s_42sh *sh) +int builtin_source(char *argv[]) { FILE *fd; int yyparse(); diff --git a/src/builtin/builtin_unalias.c b/src/builtin/builtin_unalias.c index 65c073c4138526522dc1737dc8fee91a038cee00..bfe1e24e811dc909a03051bfef70c20d1396c42a 100644 --- a/src/builtin/builtin_unalias.c +++ b/src/builtin/builtin_unalias.c @@ -5,16 +5,58 @@ ** Login ** ** Started on Thu Nov 16 17:18:24 2006 seblu -** Last update Thu Nov 16 17:49:49 2006 seblu +** Last update Fri Nov 17 12:41:53 2006 seblu */ #include #include "builtin.h" +#include +#include +#include +#include "builtin.h" +#include "../shell/shell.h" + +static int getoption(char *argv[], int *argp, int *p); + int builtin_unalias(char *argv[]) { + int argp; + char *carg; + int all = 0; + int ret = 0; + assert(argv && argv[0]); - assert(0); - argv = argv; - return 0; + if (!getoption(argv, &argp, &all)) + return 2; + if (argv[1] == NULL || all) + for (size_t i = 0; i < shell->alias->count; ++i) + alias_del(shell->alias, shell->alias->table[i].name); + for (; (carg = argv[argp]); ++argp) { + if (!alias_del(shell->alias, argv[argp])) { + printf("%s: unalias: %s: not found.\n", shell->name, argv[argp]); + ret = 1; + } + } + return ret; +} + +static int getoption(char *argv[], int *argp, int *p) +{ + char *carg; + + for (*argp = 1; (carg = argv[*argp]); ++*argp) + if (*carg == '-') + for (++carg; *carg; ++carg) + if (*carg == 'a') + *p = 1; + else { + fprintf(stderr, "%s: unalias: -%c: invalid option.\n", + shell->name, *carg); + fprintf(stderr, "unalias: usage: unalias [-a] name [name ...]\n"); + return 0; + } + else + break; + return 1; } diff --git a/src/builtin/builtin_unset.c b/src/builtin/builtin_unset.c index b1b3f32f8b9dbd5add41de5ebc5af176a1020817..601701db3bee4c43385dfa6e2ae7c6751739a91d 100644 --- a/src/builtin/builtin_unset.c +++ b/src/builtin/builtin_unset.c @@ -1,42 +1,37 @@ /* -** builtin_unset.c for 42sh in /goinfre/seblu/42sh/src/builtin +** builtin_unset.c for 42sh ** ** Made by Seblu -** Login +** Login ** ** Started on Thu May 11 09:36:06 2006 Seblu -** Last update Thu May 11 10:19:36 2006 Seblu +** Last update Fri Nov 17 13:09:29 2006 seblu */ #include #include #include -#include "builtin.h" -#include "../var/var.h" -#include "../func/function.h" -#include "../main/42sh.h" +#include "../shell/var.h" +#include "../shell/func.h" +#include "../shell/shell.h" -int builtin_unset(char *argv[], struct s_42sh *sh) +int builtin_unset(char *argv[]) { - int f = 0; - int v = 1; - int i; + int f = 0; + int v = 1; - assert(argv && sh); - for (i = 0; argv[i]; ++i) - if (!strcmp(argv[i], "-v")) - v = 1; - else if (!strcmp(argv[i], "-v")) - f = 1; - for (i = 0; argv[i]; ++i) - if (argv[i][0] == '-') - continue; - else - { - if (v) - var_unset(sh->vars, argv[i]); - if (f) - func_del(argv[i], &sh->funcs); - } - return 0; + assert(argv); + for (int i = 0; argv[i]; ++i) + if (!strcmp(argv[i], "-v")) + v = 1; + else if (!strcmp(argv[i], "-f")) + f = 1; + for (int i = 0; argv[i]; ++i) + if (argv[i][0] == '-') + continue; + else { + if (v) var_del(shell->var, argv[i]); + if (f) func_del(shell->func, argv[i]); + } + return 0; } diff --git a/src/builtin/builtin_varlist.c b/src/builtin/builtin_varlist.c deleted file mode 100644 index 8efe9e14495bea1a23636a5daa92d9afca0c9450..0000000000000000000000000000000000000000 --- a/src/builtin/builtin_varlist.c +++ /dev/null @@ -1,23 +0,0 @@ -/* -** builtin_varlist.c for 42sh in /goinfre/seblu/42sh/src/builtin -** -** Made by Seblu -** Login -** -** Started on Thu May 11 10:00:36 2006 Seblu -** Last update Sun May 21 18:40:43 2006 Seblu -*/ - -#include -#include "builtin.h" -#include "../var/var.h" -#include "../main/42sh.h" - -int builtin_varlist(char *argv[], struct s_42sh *sh) -{ - assert(sh); - var_print(sh->vars); - return 0; - argv = argv; - sh = sh; -} diff --git a/src/common/constant.h b/src/common/constant.h index 4e53307ddec21122d518e134081676fb75e558e0..dec133847d3734b83b87d35dd49fd9c20b063c27 100644 --- a/src/common/constant.h +++ b/src/common/constant.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Fri Aug 25 03:39:03 2006 Seblu -** Last update Fri Oct 13 14:25:22 2006 seblu +** Last update Fri Nov 17 13:16:09 2006 seblu */ #ifndef CONSTANT_H_ @@ -13,10 +13,11 @@ typedef enum error { - ERROR_PARSE = 2, - ERROR_FORK = 128, - ERROR_REDIR = 1, - ERROR_MEM = 42, + ERROR_RED = 1, //redirection error + ERROR_PARSE = 2, //parser or lex error + ERROR_MEM = 42, //no memory left + ERROR_FORK = 128, //error in fork + ERROR_PIPE = 128, // error in pipe } e_error; typedef enum prompt { diff --git a/src/exec/exec.h b/src/exec/exec.h index 3acaab58cf2365ea318fb4ad504cb0e2ff9fa695..ab33aa39b356af293461aca36037601fe30006fe 100644 --- a/src/exec/exec.h +++ b/src/exec/exec.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Mar 30 16:02:07 2006 Seblu -** Last update Thu Nov 16 16:06:41 2006 seblu +** Last update Fri Nov 17 14:27:55 2006 seblu */ #ifndef EXEC_H_ @@ -17,17 +17,67 @@ # define DEBUG_EXEC 0 +/*! +** Exec an ast node. Call an exec function according node type +** +** @param node node to execute. +*/ void exec_node(s_ast_node *node); +/*! +** Execute a command. +** +** @param cmd command to execute +*/ void exec_cmd(s_cmd_node *cmd); + +/*! +** Execute a command in a pipeline. This call preserve for too +** many system call fork Take care, this must be called after a fork +** +** @param cmd command to execute +*/ +void exec_piped_cmd(s_cmd_node *cmd); + +void exec_case(s_case_node *node); + +void exec_for(s_for_node *node); + void exec_and(s_bin_node *node); void exec_or(s_bin_node *node); void exec_bang(s_bin_node *node); void exec_if(s_if_node *node); -void exec_red(s_red_node *red); +void exec_pipe(s_bin_node *node); +void exec_red(s_red_node *node); void exec_while(s_while_node *node); + +/*! +** Execute a task list +** +** @param node task list +*/ void exec_sep(s_bin_node *node); + +/*! +** Execute a task in background +** +** @param node backgroudn task node +*/ void exec_sepand(s_bin_node *node); + +/*! +** Execute a function declaration. +** Register this function. +** +** @param node function to register +*/ void exec_funcdec(s_funcdec_node *node); +/*! +** Execute a subshell +** +** @param node node to treat +*/ +void exec_subshell(s_bin_node *node); + #endif diff --git a/src/exec/exec_case.c b/src/exec/exec_case.c new file mode 100644 index 0000000000000000000000000000000000000000..43206fb52697284816b95f7e2574d4d0245a563d --- /dev/null +++ b/src/exec/exec_case.c @@ -0,0 +1,19 @@ +/* +** exec_case.c for 42sh +** +** Made by seblu +** Login +** +** Started on Fri Nov 17 14:26:10 2006 seblu +** Last update Fri Nov 17 14:26:55 2006 seblu +*/ + +#include "exec.h" + +void exec_case(s_case_node *node) +{ + assert(node); + //FIXME: code it + assert(0); + node = node; +} diff --git a/src/exec/exec_cmd.c b/src/exec/exec_cmd.c index 9b5d77406d66ca8f7687735826a4db6bc4c6b741..6a16a1692efe2105680a123574686a929c8bd18f 100644 --- a/src/exec/exec_cmd.c +++ b/src/exec/exec_cmd.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sat Apr 8 07:38:48 2006 Seblu -** Last update Thu Nov 16 17:15:37 2006 seblu +** Last update Fri Nov 17 14:08:10 2006 seblu */ #include @@ -29,6 +29,12 @@ static int exec_program(s_cmd_node *cmd); static void exec_function(char **argv); static void exec_argv(char **argv); static void exec_prefix(char **prefix, int glob); + +/*! +** Debug execution +** +** @param cmd command +*/ static void cmd_debugger(s_cmd_node *cmd); /* @@ -55,6 +61,27 @@ void exec_cmd(s_cmd_node *cmd) shell->status = exec_program(cmd); } +void exec_piped_cmd(s_cmd_node *cmd) +{ + assert(cmd); + if (DEBUG_EXEC) + cmd_debugger(cmd); + //FIXME: expansions here + if (!cmd->argv) { + if (cmd->prefix) exec_prefix(cmd->prefix, 0); + return; + } + if (is_a_function(shell->func, cmd->argv[0])) + exec_function(cmd->argv); + else if (is_a_builtin(cmd->argv[0])) + shell->status = get_builtin(cmd->argv[0])(cmd->argv); + else { + if (cmd->prefix) + exec_prefix(cmd->prefix, 1); + exec_argv(cmd->argv); + } +} + static int exec_program(s_cmd_node *cmd) { pid_t pid; @@ -103,7 +130,7 @@ static void exec_prefix(char **prefix, int glob) if (glob) setenv2(prefix[i], value, !0); else - var_set(shell->var, prefix[i], value, !0); + var_add(shell->var, prefix[i], value, !0); } } @@ -114,50 +141,16 @@ static void exec_function(char **argv) exec_node(func_get(shell->func, argv[0])); } -/* /\*! */ -/* ** Execute a command in a pipeline. This call preserve for too many system call fork */ -/* ** Take care, this must be called after a fork */ -/* ** */ -/* ** @param cmd cmd to execute */ -/* ** @param sh sh structure */ -/* *\/ */ -/* void exec_piped_cmd(struct s_cmd *cmd, struct s_42sh *sh) */ -/* { */ -/* assert(cmd && sh); */ -/* if (DEBUG_EXEC) */ -/* cmd_debugger(cmd); */ -/* word_expansion(&cmd->argv, sh); */ -/* if (!apply_reds(cmd->redirs)) */ -/* exit(RED_ERROR); */ -/* if (is_a_builtin(cmd->argv[0], sh)) */ -/* sh->last_status = exec_builtin(cmd, sh); */ -/* else */ -/* { */ -/* parse_prefix(cmd->prefix, 1, sh); */ -/* launch_cmd(cmd); */ -/* } */ -/* } */ -/*! -** Debug execution -** -** @param cmd command -*/ static void cmd_debugger(s_cmd_node *cmd) { - int i; - - fprintf(stderr, "-----------------------------------\n"); - fprintf(stderr, "exec command\n"); - for (i = 0; cmd->argv && cmd->argv[i]; ++i) - fprintf(stderr, "argv[%d] : %-15s\n", i, cmd->argv[i]); - for (i = 0; cmd->prefix && cmd->prefix[i]; ++i) - fprintf(stderr, "prefix[%d] : %-15s\n", i, cmd->prefix[i]); -/* for (i = 0; cmd->redirs && cmd->redirs[i]; ++i) */ -/* { */ -/* fprintf(stderr, "reds[%d] : type : %d\n", i, cmd->redirs[i]->type); */ -/* fprintf(stderr, " : fd : %d\n", cmd->redirs[i]->fd); */ -/* fprintf(stderr, " : file : %s\n", cmd->redirs[i]->file); */ -/* } */ - fprintf(stderr, "-----------------------------------\n"); + int i; + + fprintf(stderr, "-----------------------------------\n"); + fprintf(stderr, "exec command\n"); + for (i = 0; cmd->argv && cmd->argv[i]; ++i) + fprintf(stderr, "argv[%d] : %-15s\n", i, cmd->argv[i]); + for (i = 0; cmd->prefix && cmd->prefix[i]; ++i) + fprintf(stderr, "prefix[%d] : %-15s\n", i, cmd->prefix[i]); + fprintf(stderr, "-----------------------------------\n"); } diff --git a/src/exec/exec_for.c b/src/exec/exec_for.c index 1bba1f6ae45909d227410e324a81c622ef80c3dc..7bfaab4b40dc7ddda517887eabf23d0bc11d9237 100644 --- a/src/exec/exec_for.c +++ b/src/exec/exec_for.c @@ -1,28 +1,19 @@ /* -** exec_for.c for 42sh in /home/seblu +** exec_for.c for 42sh ** ** Made by Seblu ** Login ** ** Started on Sat Mar 25 15:27:20 2006 Seblu -** Last update Sun May 21 18:46:45 2006 Seblu +** Last update Fri Nov 17 14:27:00 2006 seblu */ -#include "execution.h" +#include "exec.h" -#include "mem.h" - -/*! -** Executre for instruction -** -** @param node node to treat -** @param sh sh info -*/ -void exec_for(struct s_for *node, struct s_42sh *sh) +void exec_for(s_for_node *node) { - assert(node && sh); + assert(node); + //FIXME: code it assert(0); node = node; - sh = sh; - /* explain for node */ } diff --git a/src/exec/exec_node.c b/src/exec/exec_node.c index 44cdf53ce044ae0e2749c52bde83f2965687e01f..099313c1cddde80ce59967cf48f8d9461961d9b8 100644 --- a/src/exec/exec_node.c +++ b/src/exec/exec_node.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sat Mar 25 14:51:09 2006 Seblu -** Last update Thu Nov 16 16:48:52 2006 seblu +** Last update Fri Nov 17 14:25:08 2006 seblu */ #include "exec.h" @@ -18,15 +18,16 @@ void exec_node(s_ast_node *node) case T_SEPAND: exec_sepand(&node->body.child_sepand);break; case T_CMD: exec_cmd(&node->body.child_cmd); break; case T_RED: exec_red(&node->body.child_red); break; -/* case T_PIPE: exec_pipe(&node->body.child_pipe); break; */ + case T_PIPE: exec_pipe(&node->body.child_pipe); break; case T_AND: exec_and(&node->body.child_and); break; case T_OR: exec_or(&node->body.child_or); break; case T_IF: exec_if(&node->body.child_if); break; case T_WHILE: exec_while(&node->body.child_while); break; case T_BANG: exec_bang(&node->body.child_bang); break; - case T_SUBSHELL: assert(0); break; + case T_SUBSHELL: exec_subshell(&node->body.child_subshell); break; case T_FUNCDEC: exec_funcdec(&node->body.child_funcdec); break; - case T_CASE: assert(0); break; + case T_FOR: exec_for(&node->body.child_for); break; + case T_CASE: exec_case(&node->body.child_case); break; default: assert(0); } } diff --git a/src/exec/exec_pipe.c b/src/exec/exec_pipe.c index 4d6a6aed93fb13505783fcaac541f0f299e3e26c..76cd597c286ed0ecf740f685183c0a6f1097f786 100644 --- a/src/exec/exec_pipe.c +++ b/src/exec/exec_pipe.c @@ -1,88 +1,127 @@ /* -** exec_pipe.c for 42sh in /home/seblu/devel/c/42sh/src/execution +** exec_pipe.c for 42sh ** ** Made by Seblu ** Login ** ** Started on Wed Apr 12 01:52:31 2006 Seblu -** Last update Sat Apr 15 08:43:26 2006 Seblu +** Last update Fri Nov 17 13:51:22 2006 seblu */ #include #include #include +#include +#include #include #include -#include "execution.h" -#include "../ast/ast.h" -#include "../builtin/builtin.h" +#include "exec.h" +#include "../common/constant.h" -#include "mem.h" +/* +** ============ +** DECLARATIONS +** ============ +*/ -struct s_pipeline +typedef struct pipeline { int count; int last; pid_t *list; -}; - -void exec_piped_cmd(struct s_cmd *node, struct s_42sh *sh); -static void init_pipeline(struct s_pipeline *pipeline); -static void push_pid(struct s_pipeline *ls, pid_t new); -static pid_t pop_pid(struct s_pipeline *ls); - -static void wait_controler(struct s_pipeline *pipeline, - struct s_42sh *sh, - int killer); -static int exec_pipeline(struct s_pipeline *pipeline, - struct s_op *node, - struct s_42sh *sh); -static pid_t exec_left_hand(int p[2], - struct s_ast *left, - struct s_pipeline *pipeline, - struct s_42sh *sh); -static pid_t exec_right_hand(int p[2], - struct s_ast *right, - struct s_pipeline *pipeline, - struct s_42sh *sh); +} s_pipeline; - -static const int PIPE_ERROR = 128; +/*! +** Initialize a pipeline structure +** +** @param pipeline pipele struct to init +*/ +static void init_pipeline(s_pipeline *pipeline); /*! -** Execute a pipe node +** Push an pid to the pipeline ** -** @param node ast node pipe -** @param sh shell structure +** @param pipeline list of pid +** @param new new pid to add */ -void exec_pipe(struct s_op *node, struct s_42sh *sh) -{ - int ret; - struct s_pipeline pipeline; +static void push_pid(s_pipeline *ls, pid_t new); - assert(node && sh); - init_pipeline(&pipeline); - if (!(ret = exec_pipeline(&pipeline, node, sh))) - { - perror("42sh"); - sh->last_status = PIPE_ERROR; - } - wait_controler(&pipeline, sh, !ret); - free(pipeline.list); -} +/*! +** Pop the first pid pushed (FILE) +** +** @param pipeline pipeline +** +** @return the first pid pushed +*/ +static pid_t pop_pid(s_pipeline *ls); /*! ** Execute a pipe sequence ** ** @param pipeline pipeline info ** @param node pipe node to execute -** @param sh shell struct info ** ** @return 0 if pipe fail, else 1 */ -static int exec_pipeline(struct s_pipeline *pipeline, - struct s_op *node, - struct s_42sh *sh) +static int exec_pipeline(s_pipeline *pipeline, s_bin_node *node); + +/*! +** Wait process exit status +** +** @param pipeline the pipeline of process id +** @param killer if true, destroy all open process +*/ +static void wait_controler(s_pipeline *pipeline, int killer); + +/*! +** Execute a command writer on the pipe +** +** @param p the pipe +** @param left command to execute +** @param pipeline pipeline information +** @param sh shell structure +** +** @return pid for father, exit with last_status for the son +*/ +static pid_t exec_left_hand(int p[2], + s_ast_node *left, + s_pipeline *pipeline); +/*! +** Execute a command reader on the pipe +** +** @param p the pipe +** @param right command to execute +** @param pipeline pipeline information +** @param sh shell structure +** +** @return pid for father, exit with last_status for the son +*/ +static pid_t exec_right_hand(int p[2], + s_ast_node *right, + s_pipeline *pipeline); + +/* +** =========== +** DEFINITIONS +** =========== +*/ + +void exec_pipe(s_bin_node *node) +{ + int ret; + s_pipeline pipeline; + + assert(node); + init_pipeline(&pipeline); + if (!(ret = exec_pipeline(&pipeline, node))) { + fprintf(stderr, "%s: %s.\n", shell->name, strerror(errno)); + shell->status = ERROR_PIPE; + } + wait_controler(&pipeline, !ret); + free(pipeline.list); +} + +static int exec_pipeline(s_pipeline *pipeline, s_bin_node *node) { int p[2]; pid_t pid; @@ -91,41 +130,30 @@ static int exec_pipeline(struct s_pipeline *pipeline, if (pipe(p)) return 0; - if ((pid = exec_right_hand(p, node->right, pipeline, sh)) < 0) + if ((pid = exec_right_hand(p, node->rhs, pipeline)) < 0) return 0; - if (node->left->type == T_PIPE) - { + if (node->lhs->type == T_PIPE) { save = dup(STDOUT_FILENO); dup2(p[1], STDOUT_FILENO); close(p[1]); - ret = exec_pipeline(pipeline, &node->left->data.node_op, sh); + ret = exec_pipeline(pipeline, &node->lhs->body.child_pipe); dup2(save, STDOUT_FILENO); close(save); return ret; } - return (exec_left_hand(p, node->left, pipeline, sh) < 0) ? 0 : 1; + return (exec_left_hand(p, node->lhs, pipeline) < 0) ? 0 : 1; } -/*! -** Wait process exit status -** -** @param pipeline the pipeline of process id -** @param sh shell struct -** @param killer if true, destroy all open process -*/ -static void wait_controler(struct s_pipeline *pipeline, - struct s_42sh *sh, - int killer) +static void wait_controler(s_pipeline *pipeline, int killer) { int status; pid_t pid; - if (!killer) - { + if (!killer) { pid = pop_pid(pipeline); waitpid(pid, &status, 0); status = WEXITSTATUS(status); - sh->last_status = WEXITSTATUS(status); + shell->status = WEXITSTATUS(status); } while ((pid = pop_pid(pipeline)) != -1) { @@ -135,20 +163,9 @@ static void wait_controler(struct s_pipeline *pipeline, } } -/*! -** Execute a command reader on the pipe -** -** @param p the pipe -** @param right command to execute -** @param pipeline pipeline information -** @param sh shell structure -** -** @return pid for father, exit with last_status for the son -*/ -static pid_t exec_right_hand(int p[2], - struct s_ast *right, - struct s_pipeline *pipeline, - struct s_42sh *sh) +static pid_t exec_right_hand(int p[2], + s_ast_node *right, + s_pipeline *pipeline) { int pid; @@ -163,34 +180,22 @@ static pid_t exec_right_hand(int p[2], dup2(p[0], STDIN_FILENO); close(p[1]); if (right->type == T_CMD) - exec_piped_cmd(&right->data.node_cmd, sh); + exec_piped_cmd(&right->body.child_cmd); else - exec_node(right, sh); - exit(sh->last_status); + exec_node(right); + exit(shell->status); return pid; } -/*! -** Execute a command writer on the pipe -** -** @param p the pipe -** @param left command to execute -** @param pipeline pipeline information -** @param sh shell structure -** -** @return pid for father, exit with last_status for the son -*/ -static pid_t exec_left_hand(int p[2], - struct s_ast *left, - struct s_pipeline *pipeline, - struct s_42sh *sh) +static pid_t exec_left_hand(int p[2], + s_ast_node *left, + s_pipeline *pipeline) { int pid; if ((pid = fork()) == -1) return -1; - if (pid) - { + if (pid) { close(p[1]); push_pid(pipeline, pid); return pid; @@ -198,19 +203,14 @@ static pid_t exec_left_hand(int p[2], dup2(p[1], STDOUT_FILENO); close(p[0]); if (left->type == T_CMD) - exec_piped_cmd(&left->data.node_cmd, sh); + exec_piped_cmd(&left->body.child_cmd); else - exec_node(left, sh); - exit(sh->last_status); + exec_node(left); + exit(shell->status); return pid; } -/*! -** Initialize a pipeline structure -** -** @param pipeline pipele struct to init -*/ -static void init_pipeline(struct s_pipeline *pipeline) +static void init_pipeline(s_pipeline *pipeline) { assert(pipeline); pipeline->count = 0; @@ -218,13 +218,7 @@ static void init_pipeline(struct s_pipeline *pipeline) pipeline->list = NULL; } -/*! -** Push an pid to the pipeline -** -** @param pipeline list of pid -** @param new new pid to add -*/ -static void push_pid(struct s_pipeline *pipeline, pid_t new) +static void push_pid(s_pipeline *pipeline, pid_t new) { assert(pipeline); if (new < 0) @@ -233,14 +227,7 @@ static void push_pid(struct s_pipeline *pipeline, pid_t new) pipeline->list[pipeline->count - 1] = new; } -/*! -** Pop the first pid pushed (FILE) -** -** @param pipeline pipeline -** -** @return the first pid pushed -*/ -static pid_t pop_pid(struct s_pipeline *pipeline) +static pid_t pop_pid(s_pipeline *pipeline) { assert(pipeline); if (pipeline->count <= 0 || pipeline->last + 1 >= pipeline->count) diff --git a/src/exec/exec_red.c b/src/exec/exec_red.c index a8910d076a0e028a27e563de6bb9173fa15a5b42..dd44696ac3938bac68f7c4e1e515cf0c2545a05e 100644 --- a/src/exec/exec_red.c +++ b/src/exec/exec_red.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Nov 12 16:39:51 2006 Seblu -** Last update Thu Nov 16 15:52:08 2006 seblu +** Last update Fri Nov 17 13:16:51 2006 seblu */ #include @@ -13,6 +13,7 @@ #include #include #include "exec.h" +#include "../common/constant.h" /* ** =========== @@ -21,7 +22,7 @@ */ #define rederror(file, msg) do { fprintf(stderr, "%s: %s: %s.\n", \ - shell->name, file, msg); return 1; } while (0) + shell->name, file, msg); return ERROR_PIPE; } while (0) #define is_open_read(flags) (((flags) & 0x3) == O_RDONLY || \ ((flags) & 0x2) == O_RDWR) @@ -182,7 +183,7 @@ static int apply_red(s_red_node *reds) default: fprintf(stderr, "%s: Invalid redirection.\n", shell->name); assert(0); - return 1; + return ERROR_RED; } } return 0; diff --git a/src/exec/exec_subshell.c b/src/exec/exec_subshell.c index a6bea566325289452d28f6284a0f5b5c2ee31125..5b11b98260898fc160d6d0a1d3a4505a79c037fc 100644 --- a/src/exec/exec_subshell.c +++ b/src/exec/exec_subshell.c @@ -5,43 +5,35 @@ ** Login ** ** Started on Sat Apr 15 08:54:51 2006 Seblu -** Last update Sun Nov 12 03:48:42 2006 seblu +** Last update Fri Nov 17 14:23:49 2006 seblu */ #include #include #include #include +#include #include -#include "execution.h" +#include "exec.h" +#include "../common/constant.h" -#include "mem.h" - -void in_subshell(struct s_subshell *node, struct s_42sh *sh); - -/*! -** Execute a subshell -** -** @param node node to treat -** @param sh sh info -*/ -void exec_subshell(struct s_subshell *node, struct s_42sh *sh) +void exec_subshell(s_bin_node *node) { pid_t pid; int status; - assert(node && node->head && sh); - if ((pid = fork()) == -1) - { - perror("42sh"); - sh->last_status = FORK_ERROR; - return; + assert(node && node->lhs); + if ((pid = fork()) == -1) { + fprintf(stderr, "%s: %s.\n", shell->name, strerror(errno)); + shell->status = ERROR_FORK; + return; + } + if (pid) { + waitpid(pid, &status, 0); + shell->status = WEXITSTATUS(status); } - if (pid) - { - waitpid(pid, &status, 0); - sh->last_status = WEXITSTATUS(status); + else { + exec_node(node->lhs); + exit(ERROR_FORK); } - else - exec_node(node->head, sh); } diff --git a/src/parser/lexer.c b/src/parser/lexer.c index ad1b47a4b80afc0530f828391af83ae4f43a3fec..e4faa30887043c0583ea60afb8d34f09cd3214a8 100644 --- a/src/parser/lexer.c +++ b/src/parser/lexer.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:36:53 2006 Seblu -** Last update Tue Nov 14 15:38:16 2006 seblu +** Last update Fri Nov 17 15:51:32 2006 seblu */ #include @@ -13,8 +13,8 @@ #include #include #include "parser.h" -#include "../shell/shell.h" #include "getline.h" +#include "../shell/shell.h" #include "../common/function.h" #include "../common/macro.h" diff --git a/src/parser/parser.c b/src/parser/parser.c index df8b22746d008b808615481b081034bc70d23bff..124dfb32ab34f9349d51c9b81cedffd50136dbf8 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -5,10 +5,9 @@ ** Login ** ** Started on Wed Aug 2 00:56:07 2006 Seblu -** Last update Thu Nov 16 15:52:31 2006 seblu +** Last update Fri Nov 17 15:53:35 2006 seblu */ - #include #include #include @@ -352,7 +351,7 @@ static int parse_element(s_parser *parser, } else if (token.id == TOK_WORD && first && !is_keyword(token)) { first = 0; - //TODO: gestion des alias + //FIXME: gestion des alias ast_cmd_add_argv(cmd, lexer_gettoken(parser->lexer).str); ++found; } diff --git a/src/shell/option.c b/src/shell/option.c index 34325d1db185a0d98a1d421cf6d1e5a4995d07f0..8202aeb9b83735b405049c3f195ade796dd29b57 100644 --- a/src/shell/option.c +++ b/src/shell/option.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Tue Mar 21 19:00:38 2006 Seblu -** Last update Wed Nov 15 13:35:24 2006 seblu +** Last update Fri Nov 17 14:36:27 2006 seblu */ /* @@ -43,7 +43,6 @@ s_option *option_init(void) secmalloc(new, sizeof (s_option)); new->command = NULL; - //FIXME: item is uninitialized! Do it here return new; } diff --git a/src/shell/var.c b/src/shell/var.c index 76be55457f70e870a0800cc98ace75b2c266cca8..8e11911eced6b4eb6ea54d988c5509faacebd5e8 100644 --- a/src/shell/var.c +++ b/src/shell/var.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Tue Nov 14 13:55:46 2006 seblu -** Last update Thu Nov 16 15:14:34 2006 seblu +** Last update Fri Nov 17 13:11:10 2006 seblu */ #include @@ -42,7 +42,7 @@ const char *var_get(const s_var *var, const char *name) return NULL; } -void var_set(s_var *var, +void var_add(s_var *var, char *name, char *value, int overwrite) @@ -72,7 +72,7 @@ void var_set(s_var *var, /* add_var(var, name, value); */ } -int var_unset(s_var *var, const char *name) +int var_del(s_var *var, const char *name) { assert(var && name); var = var; name = name; diff --git a/src/shell/var.h b/src/shell/var.h index 7dfd7270aaa7cd742d9eb9c02dc4190fb33dbc40..8b3646e696a8ddfc9995ccf69d235a7820c41860 100644 --- a/src/shell/var.h +++ b/src/shell/var.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Tue Nov 14 13:54:14 2006 seblu -** Last update Wed Nov 15 10:36:09 2006 seblu +** Last update Fri Nov 17 13:11:08 2006 seblu */ #ifndef VAR_H_ @@ -52,11 +52,13 @@ s_var *var_init(void); const char *var_get(const s_var *var, const char *name); -void var_set(s_var *var, +void var_add(s_var *var, char *name, char *value, int overwrite); +int var_del(s_var *var, const char *name); + /*! ** Print all variables on standard output **