diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-17 18:54:50 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-17 18:54:50 +0000 |
| commit | 270b1c3f68d48797ccc2475c03024ccd91f8e07c (patch) | |
| tree | 7319719ad3cddd5f8b09703c6d3b0906eecbf8f2 /shell | |
| parent | 4ea187fd62c57799784b06f3c37b63b7e3f6794a (diff) | |
| download | busybox-w32-270b1c3f68d48797ccc2475c03024ccd91f8e07c.tar.gz busybox-w32-270b1c3f68d48797ccc2475c03024ccd91f8e07c.tar.bz2 busybox-w32-270b1c3f68d48797ccc2475c03024ccd91f8e07c.zip | |
hush: set $n properly for "source" builtin
function old new delta
restore_G_args - 78 +78
save_and_replace_G_args - 64 +64
builtin_source 72 107 +35
run_list 2549 2367 -182
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 1/1 up/down: 177/-182) Total: -5 bytes
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/shell/hush.c b/shell/hush.c index 4a0fc2353..84364e0e7 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -939,6 +939,52 @@ static void free_strings(char **strings) | |||
| 939 | } | 939 | } |
| 940 | 940 | ||
| 941 | 941 | ||
| 942 | /* Helpers for setting new $n and restoring them back | ||
| 943 | */ | ||
| 944 | typedef struct save_arg_t { | ||
| 945 | char *sv_argv0; | ||
| 946 | char **sv_g_argv; | ||
| 947 | int sv_g_argc; | ||
| 948 | smallint sv_g_malloced; | ||
| 949 | } save_arg_t; | ||
| 950 | |||
| 951 | static void save_and_replace_G_args(save_arg_t *sv, char **argv) | ||
| 952 | { | ||
| 953 | int n; | ||
| 954 | |||
| 955 | sv->sv_argv0 = argv[0]; | ||
| 956 | sv->sv_g_argv = G.global_argv; | ||
| 957 | sv->sv_g_argc = G.global_argc; | ||
| 958 | sv->sv_g_malloced = G.global_args_malloced; | ||
| 959 | |||
| 960 | argv[0] = G.global_argv[0]; /* retain $0 */ | ||
| 961 | G.global_argv = argv; | ||
| 962 | G.global_args_malloced = 0; | ||
| 963 | |||
| 964 | n = 1; | ||
| 965 | while (*++argv) | ||
| 966 | n++; | ||
| 967 | G.global_argc = n; | ||
| 968 | } | ||
| 969 | |||
| 970 | static void restore_G_args(save_arg_t *sv, char **argv) | ||
| 971 | { | ||
| 972 | char **pp; | ||
| 973 | |||
| 974 | if (G.global_args_malloced) { | ||
| 975 | /* someone ran "set -- arg1 arg2 ...", undo */ | ||
| 976 | pp = G.global_argv; | ||
| 977 | while (*++pp) /* note: does not free $0 */ | ||
| 978 | free(*pp); | ||
| 979 | free(G.global_argv); | ||
| 980 | } | ||
| 981 | argv[0] = sv->sv_argv0; | ||
| 982 | G.global_argv = sv->sv_g_argv; | ||
| 983 | G.global_argc = sv->sv_g_argc; | ||
| 984 | G.global_args_malloced = sv->sv_g_malloced; | ||
| 985 | } | ||
| 986 | |||
| 987 | |||
| 942 | /* Basic theory of signal handling in shell | 988 | /* Basic theory of signal handling in shell |
| 943 | * ======================================== | 989 | * ======================================== |
| 944 | * This does not describe what hush does, rather, it is current understanding | 990 | * This does not describe what hush does, rather, it is current understanding |
| @@ -2802,54 +2848,24 @@ static void exec_function(nommu_save_t *nommu_save, | |||
| 2802 | 2848 | ||
| 2803 | static int run_function(const struct function *funcp, char **argv) | 2849 | static int run_function(const struct function *funcp, char **argv) |
| 2804 | { | 2850 | { |
| 2805 | int n; | 2851 | int rc; |
| 2806 | char **pp; | 2852 | save_arg_t sv; |
| 2807 | char *sv_argv0; | ||
| 2808 | smallint sv_g_malloced; | ||
| 2809 | int sv_g_argc; | ||
| 2810 | char **sv_g_argv; | ||
| 2811 | |||
| 2812 | sv_argv0 = argv[0]; | ||
| 2813 | sv_g_malloced = G.global_args_malloced; | ||
| 2814 | sv_g_argc = G.global_argc; | ||
| 2815 | sv_g_argv = G.global_argv; | ||
| 2816 | |||
| 2817 | pp = argv; | ||
| 2818 | n = 1; | ||
| 2819 | while (*++pp) | ||
| 2820 | n++; | ||
| 2821 | |||
| 2822 | argv[0] = G.global_argv[0]; /* retain $0 */ | ||
| 2823 | G.global_args_malloced = 0; | ||
| 2824 | G.global_argc = n; | ||
| 2825 | G.global_argv = argv; | ||
| 2826 | 2853 | ||
| 2854 | save_and_replace_G_args(&sv, argv); | ||
| 2827 | /* On MMU, funcp->body is always non-NULL */ | 2855 | /* On MMU, funcp->body is always non-NULL */ |
| 2828 | #if !BB_MMU | 2856 | #if !BB_MMU |
| 2829 | if (!funcp->body) { | 2857 | if (!funcp->body) { |
| 2830 | /* Function defined by -F */ | 2858 | /* Function defined by -F */ |
| 2831 | parse_and_run_string(funcp->body_as_string); | 2859 | parse_and_run_string(funcp->body_as_string); |
| 2832 | n = G.last_exitcode; | 2860 | rc = G.last_exitcode; |
| 2833 | } else | 2861 | } else |
| 2834 | #endif | 2862 | #endif |
| 2835 | { | 2863 | { |
| 2836 | n = run_list(funcp->body); | 2864 | rc = run_list(funcp->body); |
| 2837 | } | ||
| 2838 | |||
| 2839 | if (G.global_args_malloced) { | ||
| 2840 | /* function ran "set -- arg1 arg2 ..." */ | ||
| 2841 | pp = G.global_argv; | ||
| 2842 | while (*++pp) | ||
| 2843 | free(*pp); | ||
| 2844 | free(G.global_argv); | ||
| 2845 | } | 2865 | } |
| 2866 | restore_G_args(&sv, argv); | ||
| 2846 | 2867 | ||
| 2847 | argv[0] = sv_argv0; | 2868 | return rc; |
| 2848 | G.global_args_malloced = sv_g_malloced; | ||
| 2849 | G.global_argc = sv_g_argc; | ||
| 2850 | G.global_argv = sv_g_argv; | ||
| 2851 | |||
| 2852 | return n; | ||
| 2853 | } | 2869 | } |
| 2854 | #endif | 2870 | #endif |
| 2855 | 2871 | ||
| @@ -6659,6 +6675,7 @@ static int builtin_shift(char **argv) | |||
| 6659 | static int builtin_source(char **argv) | 6675 | static int builtin_source(char **argv) |
| 6660 | { | 6676 | { |
| 6661 | FILE *input; | 6677 | FILE *input; |
| 6678 | save_arg_t sv; | ||
| 6662 | 6679 | ||
| 6663 | if (*++argv == NULL) | 6680 | if (*++argv == NULL) |
| 6664 | return EXIT_FAILURE; | 6681 | return EXIT_FAILURE; |
| @@ -6672,11 +6689,11 @@ static int builtin_source(char **argv) | |||
| 6672 | close_on_exec_on(fileno(input)); | 6689 | close_on_exec_on(fileno(input)); |
| 6673 | 6690 | ||
| 6674 | /* Now run the file */ | 6691 | /* Now run the file */ |
| 6675 | /* TODO: argv and argc are broken; need to save old G.global_argv | 6692 | save_and_replace_G_args(&sv, argv); |
| 6676 | * (pointer only is OK!) on this stack frame, | ||
| 6677 | * set G.global_argv=argv+1, recurse, and restore. */ | ||
| 6678 | parse_and_run_file(input); | 6693 | parse_and_run_file(input); |
| 6694 | restore_G_args(&sv, argv); | ||
| 6679 | fclose(input); | 6695 | fclose(input); |
| 6696 | |||
| 6680 | return G.last_exitcode; | 6697 | return G.last_exitcode; |
| 6681 | } | 6698 | } |
| 6682 | 6699 | ||
