*: add optimization barrier to all "G trick" locations
[oweals/busybox.git] / shell / hush.c
index 3f46103911081ca9d8b0c199993a6539aaef33aa..b44f35bdd9f63c391e7257c4ccbcd6c5e87389c6 100644 (file)
@@ -460,6 +460,9 @@ enum { run_list_level = 0 };
 #endif
 #define charmap          (G.charmap         )
 #define user_input_buf   (G.user_input_buf  )
+#define INIT_G() do { \
+       SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
+} while (0)
 
 
 #define B_CHUNK  100
@@ -709,28 +712,34 @@ static void signal_SA_RESTART(int sig, void (*handler)(int))
 /* Signals are grouped, we handle them in batches */
 static void set_fatal_sighandler(void (*handler)(int))
 {
-       signal(SIGILL , handler);
-       signal(SIGTRAP, handler);
-       signal(SIGABRT, handler);
-       signal(SIGFPE , handler);
-       signal(SIGBUS , handler);
-       signal(SIGSEGV, handler);
+       bb_signals(0
+               + (1 << SIGILL)
+               + (1 << SIGTRAP)
+               + (1 << SIGABRT)
+               + (1 << SIGFPE)
+               + (1 << SIGBUS)
+               + (1 << SIGSEGV)
        /* bash 3.2 seems to handle these just like 'fatal' ones */
-       signal(SIGHUP , handler);
-       signal(SIGPIPE, handler);
-       signal(SIGALRM, handler);
+               + (1 << SIGHUP)
+               + (1 << SIGPIPE)
+               + (1 << SIGALRM)
+               , handler);
 }
 static void set_jobctrl_sighandler(void (*handler)(int))
 {
-       signal(SIGTSTP, handler);
-       signal(SIGTTIN, handler);
-       signal(SIGTTOU, handler);
+       bb_signals(0
+               + (1 << SIGTSTP)
+               + (1 << SIGTTIN)
+               + (1 << SIGTTOU)
+               , handler);
 }
 static void set_misc_sighandler(void (*handler)(int))
 {
-       signal(SIGINT , handler);
-       signal(SIGQUIT, handler);
-       signal(SIGTERM, handler);
+       bb_signals(0
+               + (1 << SIGINT)
+               + (1 << SIGQUIT)
+               + (1 << SIGTERM)
+               , handler);
 }
 /* SIGCHLD is special and handled separately */
 
@@ -802,12 +811,7 @@ static void sigexit(int sig)
        if (sig <= 0)
                _exit(- sig);
 
-       /* Enable only this sig and kill ourself with it */
-       signal(sig, SIG_DFL);
-       sigdelset(&block_all, sig);
-       sigprocmask(SIG_SETMASK, &block_all, NULL);
-       raise(sig);
-       _exit(1); /* Should not reach it */
+       kill_myself_with_sig(sig); /* does not return */
 }
 
 /* Restores tty foreground process group, and exits. */
@@ -1267,10 +1271,10 @@ static void get_user_input(struct in_str *i)
        prompt_str = setup_prompt_string(i->promptmode);
 #if ENABLE_FEATURE_EDITING
        /* Enable command line editing only while a command line
-        * is actually being read; otherwise, we'll end up bequeathing
-        * atexit() handlers and other unwanted stuff to our
-        * child processes (rob@sysgo.de) */
-       r = read_line_input(prompt_str, user_input_buf, BUFSIZ-1, line_input_state);
+        * is actually being read */
+       do {
+               r = read_line_input(prompt_str, user_input_buf, BUFSIZ-1, line_input_state);
+       } while (r == 0); /* repeat if Ctrl-C */
        i->eof_flag = (r < 0);
        if (i->eof_flag) { /* EOF/error detected */
                user_input_buf[0] = EOF; /* yes, it will be truncated, it's ok */
@@ -3243,7 +3247,7 @@ static FILE *generate_stream_from_list(struct pipe *head)
        if (pid == 0) { /* child */
                if (ENABLE_HUSH_JOB)
                        die_sleep = 0; /* let nofork's xfuncs die */
-               close(channel[0]);
+               close(channel[0]); /* NB: close _first_, then move fd! */
                xmove_fd(channel[1], 1);
                /* Prevent it from trying to handle ctrl-z etc */
 #if ENABLE_HUSH_JOB
@@ -3777,7 +3781,7 @@ int hush_main(int argc, char **argv)
        char **e;
        struct variable *cur_var;
 
-       PTR_TO_GLOBALS = xzalloc(sizeof(G));
+       INIT_G();
 
        /* Deal with HUSH_VERSION */
        shell_ver = const_shell_ver; /* copying struct here */