hush: do not print message if killed by signal;

move some functions up before main()
This commit is contained in:
Denis Vlasenko 2007-04-21 10:00:01 +00:00
parent 54e7ffb3a4
commit 87cb2db703

View File

@ -390,8 +390,8 @@ static void remove_bg_job(struct pipe *pi);
static char **make_list_in(char **inp, char *name); static char **make_list_in(char **inp, char *name);
static char *insert_var_value(char *inp); static char *insert_var_value(char *inp);
static const char *get_local_var(const char *var); static const char *get_local_var(const char *var);
static void unset_local_var(const char *name);
static int set_local_var(const char *s, int flg_export); static int set_local_var(const char *s, int flg_export);
static void unset_local_var(const char *name);
/* Table of built-in functions. They can be forked or not, depending on /* Table of built-in functions. They can be forked or not, depending on
* context: within pipes, they fork. As simple commands, they do not. * context: within pipes, they fork. As simple commands, they do not.
@ -440,20 +440,8 @@ static void sigexit(int sig)
sigfillset(&block_all); sigfillset(&block_all);
sigprocmask(SIG_SETMASK, &block_all, NULL); sigprocmask(SIG_SETMASK, &block_all, NULL);
if (interactive_fd) { if (interactive_fd)
if (sig > 0) {
enum { KILLED = sizeof("Killed by signal ")-1 };
char buf[KILLED + sizeof(int)*3 + 1];
char *p;
/* bash actually says "Illegal instruction" and the like */
strcpy(buf, "Killed by signal ");
p = utoa_to_buf(sig, buf+KILLED, sizeof(buf)-KILLED);
*p++ = '\n';
write(interactive_fd, buf, p-buf);
}
tcsetpgrp(interactive_fd, saved_tty_pgrp); tcsetpgrp(interactive_fd, saved_tty_pgrp);
}
/* Not a signal, just exit */ /* Not a signal, just exit */
if (sig <= 0) if (sig <= 0)
@ -1134,16 +1122,18 @@ static void restore_redirects(int squirrel[])
/* never returns */ /* never returns */
/* XXX no exit() here. If you don't exec, use _exit instead. /* XXX no exit() here. If you don't exec, use _exit instead.
* The at_exit handlers apparently confuse the calling process, * The at_exit handlers apparently confuse the calling process,
* in particular stdin handling. Not sure why? */ * in particular stdin handling. Not sure why? -- because of vfork! (vda) */
static void pseudo_exec(struct child_prog *child) static void pseudo_exec(struct child_prog *child)
{ {
int i, rcode; int i, rcode;
char *p; char *p;
const struct built_in_command *x; const struct built_in_command *x;
if (child->argv) { if (child->argv) {
for (i = 0; is_assignment(child->argv[i]); i++) { for (i = 0; is_assignment(child->argv[i]); i++) {
debug_printf("pid %d environment modification: %s\n", debug_printf("pid %d environment modification: %s\n",
getpid(), child->argv[i]); getpid(), child->argv[i]);
// FIXME: vfork case??
p = insert_var_value(child->argv[i]); p = insert_var_value(child->argv[i]);
putenv(strdup(p)); putenv(strdup(p));
if (p != child->argv[i]) if (p != child->argv[i])
@ -1152,6 +1142,8 @@ static void pseudo_exec(struct child_prog *child)
child->argv += i; /* XXX this hack isn't so horrible, since we are about child->argv += i; /* XXX this hack isn't so horrible, since we are about
to exit, and therefore don't need to keep data to exit, and therefore don't need to keep data
structures consistent for free() use. */ structures consistent for free() use. */
// FIXME: ...unless we have _vforked_! Think NOMMU!
/* If a variable is assigned in a forest, and nobody listens, /* If a variable is assigned in a forest, and nobody listens,
* was it ever really set? * was it ever really set?
*/ */
@ -1191,12 +1183,13 @@ static void pseudo_exec(struct child_prog *child)
#endif #endif
debug_printf("exec of %s\n", child->argv[0]); debug_printf("exec of %s\n", child->argv[0]);
execvp(child->argv[0], child->argv); execvp(child->argv[0], child->argv);
bb_perror_msg("cannot exec: %s", child->argv[0]); bb_perror_msg("cannot exec '%s'", child->argv[0]);
_exit(1); _exit(1);
} }
if (child->group) { if (child->group) {
debug_printf("runtime nesting to group\n"); debug_printf("runtime nesting to group\n");
// FIXME: do not modify globals! Think vfork!
interactive_fd = 0; /* crucial!!!! */ interactive_fd = 0; /* crucial!!!! */
rcode = run_list_real(child->group); rcode = run_list_real(child->group);
/* OK to leak memory by not calling free_pipe_list, /* 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)
return gr; return gr;
} }
static char **make_list_in(char **inp, char *name)
{
int len, i;
int name_len = strlen(name);
int n = 0;
char **list;
char *p1, *p2, *p3;
/* create list of variable values */
list = xmalloc(sizeof(*list));
for (i = 0; inp[i]; i++) {
p3 = insert_var_value(inp[i]);
p1 = p3;
while (*p1) {
if ((*p1 == ' ')) {
p1++;
continue;
}
p2 = strchr(p1, ' ');
if (p2) {
len = p2 - p1;
} else {
len = strlen(p1);
p2 = p1 + len;
}
/* we use n + 2 in realloc for list, because we add
* new element and then we will add NULL element */
list = xrealloc(list, sizeof(*list) * (n + 2));
list[n] = xmalloc(2 + name_len + len);
strcpy(list[n], name);
strcat(list[n], "=");
strncat(list[n], p1, len);
list[n++][name_len + len + 1] = '\0';
p1 = p2;
}
if (p3 != inp[i]) free(p3);
}
list[n] = NULL;
return list;
}
static char *insert_var_value(char *inp)
{
int res_str_len = 0;
int len;
int done = 0;
char *p, *res_str = NULL;
const char *p1;
while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
if (p != inp) {
len = p - inp;
res_str = xrealloc(res_str, (res_str_len + len));
strncpy((res_str + res_str_len), inp, len);
res_str_len += len;
}
inp = ++p;
p = strchr(inp, SPECIAL_VAR_SYMBOL);
*p = '\0';
p1 = lookup_param(inp);
if (p1) {
len = res_str_len + strlen(p1);
res_str = xrealloc(res_str, (1 + len));
strcpy((res_str + res_str_len), p1);
res_str_len = len;
}
*p = SPECIAL_VAR_SYMBOL;
inp = ++p;
done = 1;
}
if (done) {
res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp)));
strcpy((res_str + res_str_len), inp);
while ((p = strchr(res_str, '\n'))) {
*p = ' ';
}
}
return (res_str == NULL) ? inp : res_str;
}
/* This is used to get/check local shell variables */ /* This is used to get/check local shell variables */
static const char *get_local_var(const char *s) static const char *get_local_var(const char *s)
{ {
@ -2424,6 +2497,32 @@ static const char *lookup_param(const char *src)
return p; return p;
} }
/* Make new string for parser */
static char* make_string(char ** inp)
{
char *p;
char *str = NULL;
int n;
int len = 2;
for (n = 0; inp[n]; n++) {
p = insert_var_value(inp[n]);
str = xrealloc(str, (len + strlen(p)));
if (n) {
strcat(str, " ");
} else {
*str = '\0';
}
strcat(str, p);
len = strlen(str) + 3;
if (p != inp[n]) free(p);
}
len = strlen(str);
str[len] = '\n';
str[len+1] = '\0';
return str;
}
/* return code: 0 for OK, 1 for syntax error */ /* return code: 0 for OK, 1 for syntax error */
static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
{ {
@ -2943,109 +3042,3 @@ int hush_main(int argc, char **argv)
final_return: final_return:
hush_exit(opt ? opt : last_return_code); hush_exit(opt ? opt : last_return_code);
} }
static char *insert_var_value(char *inp)
{
int res_str_len = 0;
int len;
int done = 0;
char *p, *res_str = NULL;
const char *p1;
while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
if (p != inp) {
len = p - inp;
res_str = xrealloc(res_str, (res_str_len + len));
strncpy((res_str + res_str_len), inp, len);
res_str_len += len;
}
inp = ++p;
p = strchr(inp, SPECIAL_VAR_SYMBOL);
*p = '\0';
p1 = lookup_param(inp);
if (p1) {
len = res_str_len + strlen(p1);
res_str = xrealloc(res_str, (1 + len));
strcpy((res_str + res_str_len), p1);
res_str_len = len;
}
*p = SPECIAL_VAR_SYMBOL;
inp = ++p;
done = 1;
}
if (done) {
res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp)));
strcpy((res_str + res_str_len), inp);
while ((p = strchr(res_str, '\n'))) {
*p = ' ';
}
}
return (res_str == NULL) ? inp : res_str;
}
static char **make_list_in(char **inp, char *name)
{
int len, i;
int name_len = strlen(name);
int n = 0;
char **list;
char *p1, *p2, *p3;
/* create list of variable values */
list = xmalloc(sizeof(*list));
for (i = 0; inp[i]; i++) {
p3 = insert_var_value(inp[i]);
p1 = p3;
while (*p1) {
if ((*p1 == ' ')) {
p1++;
continue;
}
p2 = strchr(p1, ' ');
if (p2) {
len = p2 - p1;
} else {
len = strlen(p1);
p2 = p1 + len;
}
/* we use n + 2 in realloc for list, because we add
* new element and then we will add NULL element */
list = xrealloc(list, sizeof(*list) * (n + 2));
list[n] = xmalloc(2 + name_len + len);
strcpy(list[n], name);
strcat(list[n], "=");
strncat(list[n], p1, len);
list[n++][name_len + len + 1] = '\0';
p1 = p2;
}
if (p3 != inp[i]) free(p3);
}
list[n] = NULL;
return list;
}
/* Make new string for parser */
static char* make_string(char ** inp)
{
char *p;
char *str = NULL;
int n;
int len = 2;
for (n = 0; inp[n]; n++) {
p = insert_var_value(inp[n]);
str = xrealloc(str, (len + strlen(p)));
if (n) {
strcat(str, " ");
} else {
*str = '\0';
}
strcat(str, p);
len = strlen(str) + 3;
if (p != inp[n]) free(p);
}
len = strlen(str);
str[len] = '\n';
str[len+1] = '\0';
return str;
}