summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-21 10:00:01 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-21 10:00:01 +0000
commit87cb2db7039d4f26a9290f4149e9774c4afe4a37 (patch)
tree5ca22a16b7551ad9753c3cd028e3fce9c7d00d74 /shell/hush.c
parent54e7ffb3a405ab058d12fbed9a63314ba996be90 (diff)
downloadbusybox-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.c237
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);
390static char **make_list_in(char **inp, char *name); 390static char **make_list_in(char **inp, char *name);
391static char *insert_var_value(char *inp); 391static char *insert_var_value(char *inp);
392static const char *get_local_var(const char *var); 392static const char *get_local_var(const char *var);
393static void unset_local_var(const char *name);
394static int set_local_var(const char *s, int flg_export); 393static int set_local_var(const char *s, int flg_export);
394static 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) */
1138static void pseudo_exec(struct child_prog *child) 1126static 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
1869static 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
1910static 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 */
1877static const char *get_local_var(const char *s) 1950static 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 */
2501static 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 */
2428static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) 2527static 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
2947static 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
2986static 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 */
3028static 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}