diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-04-30 18:18:45 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-04-30 18:18:45 +0000 |
commit | aac75e5a7818ce944dc21cabb69920e7ba78c902 (patch) | |
tree | 34730eac1c30366f6305f3cf75ce0c5ddbfb24b4 | |
parent | 0e9aef36fa5ca820e2fed506ad4032412445e942 (diff) | |
download | busybox-w32-aac75e5a7818ce944dc21cabb69920e7ba78c902.tar.gz busybox-w32-aac75e5a7818ce944dc21cabb69920e7ba78c902.tar.bz2 busybox-w32-aac75e5a7818ce944dc21cabb69920e7ba78c902.zip |
Some more hush.c updates from Larry Doolittle.
-rw-r--r-- | hush.c | 59 | ||||
-rw-r--r-- | shell/hush.c | 59 |
2 files changed, 92 insertions, 26 deletions
@@ -45,14 +45,12 @@ | |||
45 | * fancy forms of Parameter Expansion | 45 | * fancy forms of Parameter Expansion |
46 | * Arithmetic Expansion | 46 | * Arithmetic Expansion |
47 | * <(list) and >(list) Process Substitution | 47 | * <(list) and >(list) Process Substitution |
48 | * reserved words: if, then, elif, else, fi, while, until, for, | 48 | * reserved words: case, esac, function |
49 | * do, done, case | ||
50 | * Here Documents ( << word ) | 49 | * Here Documents ( << word ) |
51 | * Functions | 50 | * Functions |
52 | * Major bugs: | 51 | * Major bugs: |
53 | * job handling woefully incomplete and buggy | 52 | * job handling woefully incomplete and buggy |
54 | * reserved word execution woefully incomplete and buggy | 53 | * reserved word execution woefully incomplete and buggy |
55 | * incomplete reserved word sequence doesn't request more lines of input | ||
56 | * to-do: | 54 | * to-do: |
57 | * port selected bugfixes from post-0.49 busybox lash | 55 | * port selected bugfixes from post-0.49 busybox lash |
58 | * finish implementing reserved words | 56 | * finish implementing reserved words |
@@ -73,7 +71,6 @@ | |||
73 | * more testing, especially quoting rules and redirection | 71 | * more testing, especially quoting rules and redirection |
74 | * maybe change map[] to use 2-bit entries | 72 | * maybe change map[] to use 2-bit entries |
75 | * (eventually) remove all the printf's | 73 | * (eventually) remove all the printf's |
76 | * more integration with BusyBox: prompts, cmdedit, applets | ||
77 | * | 74 | * |
78 | * This program is free software; you can redistribute it and/or modify | 75 | * This program is free software; you can redistribute it and/or modify |
79 | * it under the terms of the GNU General Public License as published by | 76 | * it under the terms of the GNU General Public License as published by |
@@ -105,7 +102,7 @@ | |||
105 | #include <signal.h> | 102 | #include <signal.h> |
106 | 103 | ||
107 | /* #include <dmalloc.h> */ | 104 | /* #include <dmalloc.h> */ |
108 | /* #define DEBUG_SHELL */ | 105 | #define DEBUG_SHELL |
109 | 106 | ||
110 | #ifdef BB_VER | 107 | #ifdef BB_VER |
111 | #include "busybox.h" | 108 | #include "busybox.h" |
@@ -977,6 +974,42 @@ static void pseudo_exec(struct child_prog *child) | |||
977 | exit(x->function(child)); | 974 | exit(x->function(child)); |
978 | } | 975 | } |
979 | } | 976 | } |
977 | |||
978 | /* Check if the command matches any busybox internal commands | ||
979 | * ("applets") here. | ||
980 | * FIXME: This feature is not 100% safe, since | ||
981 | * BusyBox is not fully reentrant, so we have no guarantee the things | ||
982 | * from the .bss are still zeroed, or that things from .data are still | ||
983 | * at their defaults. We could exec ourself from /proc/self/exe, but I | ||
984 | * really dislike relying on /proc for things. We could exec ourself | ||
985 | * from global_argv[0], but if we are in a chroot, we may not be able | ||
986 | * to find ourself... */ | ||
987 | #ifdef BB_FEATURE_SH_STANDALONE_SHELL | ||
988 | { | ||
989 | int argc_l; | ||
990 | char** argv_l=child->argv; | ||
991 | char *name = child->argv[0]; | ||
992 | |||
993 | #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN | ||
994 | /* Following discussions from November 2000 on the busybox mailing | ||
995 | * list, the default configuration, (without | ||
996 | * get_last_path_component()) lets the user force use of an | ||
997 | * external command by specifying the full (with slashes) filename. | ||
998 | * If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets | ||
999 | * _aways_ override external commands, so if you want to run | ||
1000 | * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the | ||
1001 | * filesystem and is _not_ busybox. Some systems may want this, | ||
1002 | * most do not. */ | ||
1003 | name = get_last_path_component(name); | ||
1004 | #endif | ||
1005 | /* Count argc for use in a second... */ | ||
1006 | for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); | ||
1007 | optind = 1; | ||
1008 | debug_printf("running applet %s\n", name); | ||
1009 | run_applet_by_name(name, argc_l, child->argv); | ||
1010 | exit(1); | ||
1011 | } | ||
1012 | #endif | ||
980 | debug_printf("exec of %s\n",child->argv[0]); | 1013 | debug_printf("exec of %s\n",child->argv[0]); |
981 | execvp(child->argv[0],child->argv); | 1014 | execvp(child->argv[0],child->argv); |
982 | perror("execvp"); | 1015 | perror("execvp"); |
@@ -1842,14 +1875,13 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1842 | ch,ch,m,dest->quote); | 1875 | ch,ch,m,dest->quote); |
1843 | if (m==0 || ((m==1 || m==2) && dest->quote)) { | 1876 | if (m==0 || ((m==1 || m==2) && dest->quote)) { |
1844 | b_addqchr(dest, ch, dest->quote); | 1877 | b_addqchr(dest, ch, dest->quote); |
1845 | } else if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | 1878 | } else { |
1846 | debug_printf("leaving parse_stream\n"); | 1879 | if (m==2) { /* unquoted IFS */ |
1847 | return 0; | 1880 | done_word(dest, ctx); |
1848 | } else if (m==2 && !dest->quote) { /* IFS */ | 1881 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); |
1849 | done_word(dest, ctx); | 1882 | } |
1850 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); | ||
1851 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | 1883 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { |
1852 | debug_printf("leaving parse_stream (stupid duplication)\n"); | 1884 | debug_printf("leaving parse_stream\n"); |
1853 | return 0; | 1885 | return 0; |
1854 | } | 1886 | } |
1855 | #if 0 | 1887 | #if 0 |
@@ -1860,7 +1892,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1860 | initialize_context(ctx); | 1892 | initialize_context(ctx); |
1861 | } | 1893 | } |
1862 | #endif | 1894 | #endif |
1863 | } else switch (ch) { | 1895 | if (m!=2) switch (ch) { |
1864 | case '#': | 1896 | case '#': |
1865 | if (dest->length == 0 && !dest->quote) { | 1897 | if (dest->length == 0 && !dest->quote) { |
1866 | while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } | 1898 | while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } |
@@ -1962,6 +1994,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1962 | default: | 1994 | default: |
1963 | syntax(); /* this is really an internal logic error */ | 1995 | syntax(); /* this is really an internal logic error */ |
1964 | return 1; | 1996 | return 1; |
1997 | } | ||
1965 | } | 1998 | } |
1966 | } | 1999 | } |
1967 | /* complain if quote? No, maybe we just finished a command substitution | 2000 | /* complain if quote? No, maybe we just finished a command substitution |
diff --git a/shell/hush.c b/shell/hush.c index 9a43a03dc..4753bd7ab 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -45,14 +45,12 @@ | |||
45 | * fancy forms of Parameter Expansion | 45 | * fancy forms of Parameter Expansion |
46 | * Arithmetic Expansion | 46 | * Arithmetic Expansion |
47 | * <(list) and >(list) Process Substitution | 47 | * <(list) and >(list) Process Substitution |
48 | * reserved words: if, then, elif, else, fi, while, until, for, | 48 | * reserved words: case, esac, function |
49 | * do, done, case | ||
50 | * Here Documents ( << word ) | 49 | * Here Documents ( << word ) |
51 | * Functions | 50 | * Functions |
52 | * Major bugs: | 51 | * Major bugs: |
53 | * job handling woefully incomplete and buggy | 52 | * job handling woefully incomplete and buggy |
54 | * reserved word execution woefully incomplete and buggy | 53 | * reserved word execution woefully incomplete and buggy |
55 | * incomplete reserved word sequence doesn't request more lines of input | ||
56 | * to-do: | 54 | * to-do: |
57 | * port selected bugfixes from post-0.49 busybox lash | 55 | * port selected bugfixes from post-0.49 busybox lash |
58 | * finish implementing reserved words | 56 | * finish implementing reserved words |
@@ -73,7 +71,6 @@ | |||
73 | * more testing, especially quoting rules and redirection | 71 | * more testing, especially quoting rules and redirection |
74 | * maybe change map[] to use 2-bit entries | 72 | * maybe change map[] to use 2-bit entries |
75 | * (eventually) remove all the printf's | 73 | * (eventually) remove all the printf's |
76 | * more integration with BusyBox: prompts, cmdedit, applets | ||
77 | * | 74 | * |
78 | * This program is free software; you can redistribute it and/or modify | 75 | * This program is free software; you can redistribute it and/or modify |
79 | * it under the terms of the GNU General Public License as published by | 76 | * it under the terms of the GNU General Public License as published by |
@@ -105,7 +102,7 @@ | |||
105 | #include <signal.h> | 102 | #include <signal.h> |
106 | 103 | ||
107 | /* #include <dmalloc.h> */ | 104 | /* #include <dmalloc.h> */ |
108 | /* #define DEBUG_SHELL */ | 105 | #define DEBUG_SHELL |
109 | 106 | ||
110 | #ifdef BB_VER | 107 | #ifdef BB_VER |
111 | #include "busybox.h" | 108 | #include "busybox.h" |
@@ -977,6 +974,42 @@ static void pseudo_exec(struct child_prog *child) | |||
977 | exit(x->function(child)); | 974 | exit(x->function(child)); |
978 | } | 975 | } |
979 | } | 976 | } |
977 | |||
978 | /* Check if the command matches any busybox internal commands | ||
979 | * ("applets") here. | ||
980 | * FIXME: This feature is not 100% safe, since | ||
981 | * BusyBox is not fully reentrant, so we have no guarantee the things | ||
982 | * from the .bss are still zeroed, or that things from .data are still | ||
983 | * at their defaults. We could exec ourself from /proc/self/exe, but I | ||
984 | * really dislike relying on /proc for things. We could exec ourself | ||
985 | * from global_argv[0], but if we are in a chroot, we may not be able | ||
986 | * to find ourself... */ | ||
987 | #ifdef BB_FEATURE_SH_STANDALONE_SHELL | ||
988 | { | ||
989 | int argc_l; | ||
990 | char** argv_l=child->argv; | ||
991 | char *name = child->argv[0]; | ||
992 | |||
993 | #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN | ||
994 | /* Following discussions from November 2000 on the busybox mailing | ||
995 | * list, the default configuration, (without | ||
996 | * get_last_path_component()) lets the user force use of an | ||
997 | * external command by specifying the full (with slashes) filename. | ||
998 | * If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets | ||
999 | * _aways_ override external commands, so if you want to run | ||
1000 | * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the | ||
1001 | * filesystem and is _not_ busybox. Some systems may want this, | ||
1002 | * most do not. */ | ||
1003 | name = get_last_path_component(name); | ||
1004 | #endif | ||
1005 | /* Count argc for use in a second... */ | ||
1006 | for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); | ||
1007 | optind = 1; | ||
1008 | debug_printf("running applet %s\n", name); | ||
1009 | run_applet_by_name(name, argc_l, child->argv); | ||
1010 | exit(1); | ||
1011 | } | ||
1012 | #endif | ||
980 | debug_printf("exec of %s\n",child->argv[0]); | 1013 | debug_printf("exec of %s\n",child->argv[0]); |
981 | execvp(child->argv[0],child->argv); | 1014 | execvp(child->argv[0],child->argv); |
982 | perror("execvp"); | 1015 | perror("execvp"); |
@@ -1842,14 +1875,13 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1842 | ch,ch,m,dest->quote); | 1875 | ch,ch,m,dest->quote); |
1843 | if (m==0 || ((m==1 || m==2) && dest->quote)) { | 1876 | if (m==0 || ((m==1 || m==2) && dest->quote)) { |
1844 | b_addqchr(dest, ch, dest->quote); | 1877 | b_addqchr(dest, ch, dest->quote); |
1845 | } else if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | 1878 | } else { |
1846 | debug_printf("leaving parse_stream\n"); | 1879 | if (m==2) { /* unquoted IFS */ |
1847 | return 0; | 1880 | done_word(dest, ctx); |
1848 | } else if (m==2 && !dest->quote) { /* IFS */ | 1881 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); |
1849 | done_word(dest, ctx); | 1882 | } |
1850 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); | ||
1851 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | 1883 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { |
1852 | debug_printf("leaving parse_stream (stupid duplication)\n"); | 1884 | debug_printf("leaving parse_stream\n"); |
1853 | return 0; | 1885 | return 0; |
1854 | } | 1886 | } |
1855 | #if 0 | 1887 | #if 0 |
@@ -1860,7 +1892,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1860 | initialize_context(ctx); | 1892 | initialize_context(ctx); |
1861 | } | 1893 | } |
1862 | #endif | 1894 | #endif |
1863 | } else switch (ch) { | 1895 | if (m!=2) switch (ch) { |
1864 | case '#': | 1896 | case '#': |
1865 | if (dest->length == 0 && !dest->quote) { | 1897 | if (dest->length == 0 && !dest->quote) { |
1866 | while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } | 1898 | while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } |
@@ -1962,6 +1994,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1962 | default: | 1994 | default: |
1963 | syntax(); /* this is really an internal logic error */ | 1995 | syntax(); /* this is really an internal logic error */ |
1964 | return 1; | 1996 | return 1; |
1997 | } | ||
1965 | } | 1998 | } |
1966 | } | 1999 | } |
1967 | /* complain if quote? No, maybe we just finished a command substitution | 2000 | /* complain if quote? No, maybe we just finished a command substitution |