diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-21 10:00:01 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-21 10:00:01 +0000 |
commit | 87cb2db7039d4f26a9290f4149e9774c4afe4a37 (patch) | |
tree | 5ca22a16b7551ad9753c3cd028e3fce9c7d00d74 /shell/hush.c | |
parent | 54e7ffb3a405ab058d12fbed9a63314ba996be90 (diff) | |
download | busybox-w32-87cb2db7039d4f26a9290f4149e9774c4afe4a37.tar.gz busybox-w32-87cb2db7039d4f26a9290f4149e9774c4afe4a37.tar.bz2 busybox-w32-87cb2db7039d4f26a9290f4149e9774c4afe4a37.zip |
hush: do not print message if killed by signal;
move some functions up before main()
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 237 |
1 files changed, 115 insertions, 122 deletions
diff --git a/shell/hush.c b/shell/hush.c index 7792887a5..c4b393bce 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -390,8 +390,8 @@ static void remove_bg_job(struct pipe *pi); | |||
390 | static char **make_list_in(char **inp, char *name); | 390 | static char **make_list_in(char **inp, char *name); |
391 | static char *insert_var_value(char *inp); | 391 | static char *insert_var_value(char *inp); |
392 | static const char *get_local_var(const char *var); | 392 | static const char *get_local_var(const char *var); |
393 | static void unset_local_var(const char *name); | ||
394 | static int set_local_var(const char *s, int flg_export); | 393 | static int set_local_var(const char *s, int flg_export); |
394 | static void unset_local_var(const char *name); | ||
395 | 395 | ||
396 | /* Table of built-in functions. They can be forked or not, depending on | 396 | /* Table of built-in functions. They can be forked or not, depending on |
397 | * context: within pipes, they fork. As simple commands, they do not. | 397 | * context: within pipes, they fork. As simple commands, they do not. |
@@ -440,20 +440,8 @@ static void sigexit(int sig) | |||
440 | sigfillset(&block_all); | 440 | sigfillset(&block_all); |
441 | sigprocmask(SIG_SETMASK, &block_all, NULL); | 441 | sigprocmask(SIG_SETMASK, &block_all, NULL); |
442 | 442 | ||
443 | if (interactive_fd) { | 443 | if (interactive_fd) |
444 | if (sig > 0) { | ||
445 | enum { KILLED = sizeof("Killed by signal ")-1 }; | ||
446 | char buf[KILLED + sizeof(int)*3 + 1]; | ||
447 | char *p; | ||
448 | |||
449 | /* bash actually says "Illegal instruction" and the like */ | ||
450 | strcpy(buf, "Killed by signal "); | ||
451 | p = utoa_to_buf(sig, buf+KILLED, sizeof(buf)-KILLED); | ||
452 | *p++ = '\n'; | ||
453 | write(interactive_fd, buf, p-buf); | ||
454 | } | ||
455 | tcsetpgrp(interactive_fd, saved_tty_pgrp); | 444 | tcsetpgrp(interactive_fd, saved_tty_pgrp); |
456 | } | ||
457 | 445 | ||
458 | /* Not a signal, just exit */ | 446 | /* Not a signal, just exit */ |
459 | if (sig <= 0) | 447 | if (sig <= 0) |
@@ -1134,16 +1122,18 @@ static void restore_redirects(int squirrel[]) | |||
1134 | /* never returns */ | 1122 | /* never returns */ |
1135 | /* XXX no exit() here. If you don't exec, use _exit instead. | 1123 | /* XXX no exit() here. If you don't exec, use _exit instead. |
1136 | * The at_exit handlers apparently confuse the calling process, | 1124 | * The at_exit handlers apparently confuse the calling process, |
1137 | * in particular stdin handling. Not sure why? */ | 1125 | * in particular stdin handling. Not sure why? -- because of vfork! (vda) */ |
1138 | static void pseudo_exec(struct child_prog *child) | 1126 | static void pseudo_exec(struct child_prog *child) |
1139 | { | 1127 | { |
1140 | int i, rcode; | 1128 | int i, rcode; |
1141 | char *p; | 1129 | char *p; |
1142 | const struct built_in_command *x; | 1130 | const struct built_in_command *x; |
1131 | |||
1143 | if (child->argv) { | 1132 | if (child->argv) { |
1144 | for (i = 0; is_assignment(child->argv[i]); i++) { | 1133 | for (i = 0; is_assignment(child->argv[i]); i++) { |
1145 | debug_printf("pid %d environment modification: %s\n", | 1134 | debug_printf("pid %d environment modification: %s\n", |
1146 | getpid(), child->argv[i]); | 1135 | getpid(), child->argv[i]); |
1136 | // FIXME: vfork case?? | ||
1147 | p = insert_var_value(child->argv[i]); | 1137 | p = insert_var_value(child->argv[i]); |
1148 | putenv(strdup(p)); | 1138 | putenv(strdup(p)); |
1149 | if (p != child->argv[i]) | 1139 | if (p != child->argv[i]) |
@@ -1152,6 +1142,8 @@ static void pseudo_exec(struct child_prog *child) | |||
1152 | child->argv += i; /* XXX this hack isn't so horrible, since we are about | 1142 | child->argv += i; /* XXX this hack isn't so horrible, since we are about |
1153 | to exit, and therefore don't need to keep data | 1143 | to exit, and therefore don't need to keep data |
1154 | structures consistent for free() use. */ | 1144 | structures consistent for free() use. */ |
1145 | // FIXME: ...unless we have _vforked_! Think NOMMU! | ||
1146 | |||
1155 | /* If a variable is assigned in a forest, and nobody listens, | 1147 | /* If a variable is assigned in a forest, and nobody listens, |
1156 | * was it ever really set? | 1148 | * was it ever really set? |
1157 | */ | 1149 | */ |
@@ -1191,12 +1183,13 @@ static void pseudo_exec(struct child_prog *child) | |||
1191 | #endif | 1183 | #endif |
1192 | debug_printf("exec of %s\n", child->argv[0]); | 1184 | debug_printf("exec of %s\n", child->argv[0]); |
1193 | execvp(child->argv[0], child->argv); | 1185 | execvp(child->argv[0], child->argv); |
1194 | bb_perror_msg("cannot exec: %s", child->argv[0]); | 1186 | bb_perror_msg("cannot exec '%s'", child->argv[0]); |
1195 | _exit(1); | 1187 | _exit(1); |
1196 | } | 1188 | } |
1197 | 1189 | ||
1198 | if (child->group) { | 1190 | if (child->group) { |
1199 | debug_printf("runtime nesting to group\n"); | 1191 | debug_printf("runtime nesting to group\n"); |
1192 | // FIXME: do not modify globals! Think vfork! | ||
1200 | interactive_fd = 0; /* crucial!!!! */ | 1193 | interactive_fd = 0; /* crucial!!!! */ |
1201 | rcode = run_list_real(child->group); | 1194 | rcode = run_list_real(child->group); |
1202 | /* OK to leak memory by not calling free_pipe_list, | 1195 | /* OK to leak memory by not calling free_pipe_list, |
@@ -1873,6 +1866,86 @@ static int xglob(o_string *dest, int flags, glob_t *pglob) | |||
1873 | return gr; | 1866 | return gr; |
1874 | } | 1867 | } |
1875 | 1868 | ||
1869 | static char **make_list_in(char **inp, char *name) | ||
1870 | { | ||
1871 | int len, i; | ||
1872 | int name_len = strlen(name); | ||
1873 | int n = 0; | ||
1874 | char **list; | ||
1875 | char *p1, *p2, *p3; | ||
1876 | |||
1877 | /* create list of variable values */ | ||
1878 | list = xmalloc(sizeof(*list)); | ||
1879 | for (i = 0; inp[i]; i++) { | ||
1880 | p3 = insert_var_value(inp[i]); | ||
1881 | p1 = p3; | ||
1882 | while (*p1) { | ||
1883 | if ((*p1 == ' ')) { | ||
1884 | p1++; | ||
1885 | continue; | ||
1886 | } | ||
1887 | p2 = strchr(p1, ' '); | ||
1888 | if (p2) { | ||
1889 | len = p2 - p1; | ||
1890 | } else { | ||
1891 | len = strlen(p1); | ||
1892 | p2 = p1 + len; | ||
1893 | } | ||
1894 | /* we use n + 2 in realloc for list, because we add | ||
1895 | * new element and then we will add NULL element */ | ||
1896 | list = xrealloc(list, sizeof(*list) * (n + 2)); | ||
1897 | list[n] = xmalloc(2 + name_len + len); | ||
1898 | strcpy(list[n], name); | ||
1899 | strcat(list[n], "="); | ||
1900 | strncat(list[n], p1, len); | ||
1901 | list[n++][name_len + len + 1] = '\0'; | ||
1902 | p1 = p2; | ||
1903 | } | ||
1904 | if (p3 != inp[i]) free(p3); | ||
1905 | } | ||
1906 | list[n] = NULL; | ||
1907 | return list; | ||
1908 | } | ||
1909 | |||
1910 | static char *insert_var_value(char *inp) | ||
1911 | { | ||
1912 | int res_str_len = 0; | ||
1913 | int len; | ||
1914 | int done = 0; | ||
1915 | char *p, *res_str = NULL; | ||
1916 | const char *p1; | ||
1917 | |||
1918 | while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { | ||
1919 | if (p != inp) { | ||
1920 | len = p - inp; | ||
1921 | res_str = xrealloc(res_str, (res_str_len + len)); | ||
1922 | strncpy((res_str + res_str_len), inp, len); | ||
1923 | res_str_len += len; | ||
1924 | } | ||
1925 | inp = ++p; | ||
1926 | p = strchr(inp, SPECIAL_VAR_SYMBOL); | ||
1927 | *p = '\0'; | ||
1928 | p1 = lookup_param(inp); | ||
1929 | if (p1) { | ||
1930 | len = res_str_len + strlen(p1); | ||
1931 | res_str = xrealloc(res_str, (1 + len)); | ||
1932 | strcpy((res_str + res_str_len), p1); | ||
1933 | res_str_len = len; | ||
1934 | } | ||
1935 | *p = SPECIAL_VAR_SYMBOL; | ||
1936 | inp = ++p; | ||
1937 | done = 1; | ||
1938 | } | ||
1939 | if (done) { | ||
1940 | res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp))); | ||
1941 | strcpy((res_str + res_str_len), inp); | ||
1942 | while ((p = strchr(res_str, '\n'))) { | ||
1943 | *p = ' '; | ||
1944 | } | ||
1945 | } | ||
1946 | return (res_str == NULL) ? inp : res_str; | ||
1947 | } | ||
1948 | |||
1876 | /* This is used to get/check local shell variables */ | 1949 | /* This is used to get/check local shell variables */ |
1877 | static const char *get_local_var(const char *s) | 1950 | static const char *get_local_var(const char *s) |
1878 | { | 1951 | { |
@@ -2424,6 +2497,32 @@ static const char *lookup_param(const char *src) | |||
2424 | return p; | 2497 | return p; |
2425 | } | 2498 | } |
2426 | 2499 | ||
2500 | /* Make new string for parser */ | ||
2501 | static char* make_string(char ** inp) | ||
2502 | { | ||
2503 | char *p; | ||
2504 | char *str = NULL; | ||
2505 | int n; | ||
2506 | int len = 2; | ||
2507 | |||
2508 | for (n = 0; inp[n]; n++) { | ||
2509 | p = insert_var_value(inp[n]); | ||
2510 | str = xrealloc(str, (len + strlen(p))); | ||
2511 | if (n) { | ||
2512 | strcat(str, " "); | ||
2513 | } else { | ||
2514 | *str = '\0'; | ||
2515 | } | ||
2516 | strcat(str, p); | ||
2517 | len = strlen(str) + 3; | ||
2518 | if (p != inp[n]) free(p); | ||
2519 | } | ||
2520 | len = strlen(str); | ||
2521 | str[len] = '\n'; | ||
2522 | str[len+1] = '\0'; | ||
2523 | return str; | ||
2524 | } | ||
2525 | |||
2427 | /* return code: 0 for OK, 1 for syntax error */ | 2526 | /* return code: 0 for OK, 1 for syntax error */ |
2428 | static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) | 2527 | static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) |
2429 | { | 2528 | { |
@@ -2943,109 +3042,3 @@ int hush_main(int argc, char **argv) | |||
2943 | final_return: | 3042 | final_return: |
2944 | hush_exit(opt ? opt : last_return_code); | 3043 | hush_exit(opt ? opt : last_return_code); |
2945 | } | 3044 | } |
2946 | |||
2947 | static char *insert_var_value(char *inp) | ||
2948 | { | ||
2949 | int res_str_len = 0; | ||
2950 | int len; | ||
2951 | int done = 0; | ||
2952 | char *p, *res_str = NULL; | ||
2953 | const char *p1; | ||
2954 | |||
2955 | while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { | ||
2956 | if (p != inp) { | ||
2957 | len = p - inp; | ||
2958 | res_str = xrealloc(res_str, (res_str_len + len)); | ||
2959 | strncpy((res_str + res_str_len), inp, len); | ||
2960 | res_str_len += len; | ||
2961 | } | ||
2962 | inp = ++p; | ||
2963 | p = strchr(inp, SPECIAL_VAR_SYMBOL); | ||
2964 | *p = '\0'; | ||
2965 | p1 = lookup_param(inp); | ||
2966 | if (p1) { | ||
2967 | len = res_str_len + strlen(p1); | ||
2968 | res_str = xrealloc(res_str, (1 + len)); | ||
2969 | strcpy((res_str + res_str_len), p1); | ||
2970 | res_str_len = len; | ||
2971 | } | ||
2972 | *p = SPECIAL_VAR_SYMBOL; | ||
2973 | inp = ++p; | ||
2974 | done = 1; | ||
2975 | } | ||
2976 | if (done) { | ||
2977 | res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp))); | ||
2978 | strcpy((res_str + res_str_len), inp); | ||
2979 | while ((p = strchr(res_str, '\n'))) { | ||
2980 | *p = ' '; | ||
2981 | } | ||
2982 | } | ||
2983 | return (res_str == NULL) ? inp : res_str; | ||
2984 | } | ||
2985 | |||
2986 | static char **make_list_in(char **inp, char *name) | ||
2987 | { | ||
2988 | int len, i; | ||
2989 | int name_len = strlen(name); | ||
2990 | int n = 0; | ||
2991 | char **list; | ||
2992 | char *p1, *p2, *p3; | ||
2993 | |||
2994 | /* create list of variable values */ | ||
2995 | list = xmalloc(sizeof(*list)); | ||
2996 | for (i = 0; inp[i]; i++) { | ||
2997 | p3 = insert_var_value(inp[i]); | ||
2998 | p1 = p3; | ||
2999 | while (*p1) { | ||
3000 | if ((*p1 == ' ')) { | ||
3001 | p1++; | ||
3002 | continue; | ||
3003 | } | ||
3004 | p2 = strchr(p1, ' '); | ||
3005 | if (p2) { | ||
3006 | len = p2 - p1; | ||
3007 | } else { | ||
3008 | len = strlen(p1); | ||
3009 | p2 = p1 + len; | ||
3010 | } | ||
3011 | /* we use n + 2 in realloc for list, because we add | ||
3012 | * new element and then we will add NULL element */ | ||
3013 | list = xrealloc(list, sizeof(*list) * (n + 2)); | ||
3014 | list[n] = xmalloc(2 + name_len + len); | ||
3015 | strcpy(list[n], name); | ||
3016 | strcat(list[n], "="); | ||
3017 | strncat(list[n], p1, len); | ||
3018 | list[n++][name_len + len + 1] = '\0'; | ||
3019 | p1 = p2; | ||
3020 | } | ||
3021 | if (p3 != inp[i]) free(p3); | ||
3022 | } | ||
3023 | list[n] = NULL; | ||
3024 | return list; | ||
3025 | } | ||
3026 | |||
3027 | /* Make new string for parser */ | ||
3028 | static char* make_string(char ** inp) | ||
3029 | { | ||
3030 | char *p; | ||
3031 | char *str = NULL; | ||
3032 | int n; | ||
3033 | int len = 2; | ||
3034 | |||
3035 | for (n = 0; inp[n]; n++) { | ||
3036 | p = insert_var_value(inp[n]); | ||
3037 | str = xrealloc(str, (len + strlen(p))); | ||
3038 | if (n) { | ||
3039 | strcat(str, " "); | ||
3040 | } else { | ||
3041 | *str = '\0'; | ||
3042 | } | ||
3043 | strcat(str, p); | ||
3044 | len = strlen(str) + 3; | ||
3045 | if (p != inp[n]) free(p); | ||
3046 | } | ||
3047 | len = strlen(str); | ||
3048 | str[len] = '\n'; | ||
3049 | str[len+1] = '\0'; | ||
3050 | return str; | ||
3051 | } | ||