diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-12 13:57:46 -0800 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-14 16:17:01 -0800 |
commit | f533861f868afc167aae06968db5bc138729189f (patch) | |
tree | eff8b5e0ce0b88c2ab470a1bfd841668f26a005d /jobs.c | |
parent | fc7695ee76400ee9833301f98a3fe483d64591b5 (diff) | |
download | vyatta-bash-f533861f868afc167aae06968db5bc138729189f.tar.gz vyatta-bash-f533861f868afc167aae06968db5bc138729189f.zip |
patched with "debian_patches" in bash_3.1dfsg-8.diff.gz
Diffstat (limited to 'jobs.c')
-rw-r--r-- | jobs.c | 60 |
1 files changed, 51 insertions, 9 deletions
@@ -619,8 +619,11 @@ stop_pipeline (async, deferred) * once in the parent and once in each child. This is where * the parent gives it away. * + * Don't give the terminal away if this shell is an asynchronous + * subshell. + * */ - if (job_control && newjob->pgrp) + if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0) give_terminal_to (newjob->pgrp, 0); } } @@ -844,9 +847,10 @@ static void realloc_jobs_list () { sigset_t set, oset; - int nsize, i, j; + int nsize, i, j, ncur, nprev; JOB **nlist; + ncur = nprev = NO_JOB; nsize = ((js.j_njobs + JOB_SLOTS - 1) / JOB_SLOTS); nsize *= JOB_SLOTS; i = js.j_njobs % JOB_SLOTS; @@ -854,17 +858,51 @@ realloc_jobs_list () nsize += JOB_SLOTS; BLOCK_CHILD (set, oset); - nlist = (JOB **) xmalloc (nsize * sizeof (JOB *)); + nlist = (js.j_jobslots == nsize) ? jobs : (JOB **) xmalloc (nsize * sizeof (JOB *)); + for (i = j = 0; i < js.j_jobslots; i++) if (jobs[i]) - nlist[j++] = jobs[i]; + { + if (i == js.j_current) + ncur = j; + if (i == js.j_previous) + nprev = j; + nlist[j++] = jobs[i]; + } + +#if defined (DEBUG) + itrace ("realloc_jobs_list: resize jobs list from %d to %d", js.j_jobslots, nsize); + itrace ("realloc_jobs_list: j_lastj changed from %d to %d", js.j_lastj, (j > 0) ? j - 1 : 0); + itrace ("realloc_jobs_list: j_njobs changed from %d to %d", js.j_njobs, (j > 0) ? j - 1 : 0); +#endif js.j_firstj = 0; - js.j_lastj = (j > 0) ? j - 1: 0; + js.j_lastj = (j > 0) ? j - 1 : 0; + js.j_njobs = j; js.j_jobslots = nsize; - free (jobs); - jobs = nlist; + /* Zero out remaining slots in new jobs list */ + for ( ; j < nsize; j++) + nlist[j] = (JOB *)NULL; + + if (jobs != nlist) + { + free (jobs); + jobs = nlist; + } + + if (ncur != NO_JOB) + js.j_current = ncur; + if (nprev != NO_JOB) + js.j_previous = nprev; + + /* Need to reset these */ + if (js.j_current == NO_JOB || js.j_previous == NO_JOB || js.j_current > js.j_lastj || js.j_previous > js.j_lastj) + reset_current (); + +#ifdef DEBUG + itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous); +#endif UNBLOCK_CHILD (oset); } @@ -1655,7 +1693,7 @@ make_child (command, async_p) In this case, we don't want to give the terminal to the shell's process group (we could be in the middle of a pipeline, for example). */ - if (async_p == 0 && pipeline_pgrp != shell_pgrp) + if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&SUBSHELL_ASYNC) == 0)) give_terminal_to (pipeline_pgrp, 0); #if defined (PGRP_PIPE) @@ -2198,7 +2236,11 @@ wait_for (pid) /* This is possibly a race condition -- should it go in stop_pipeline? */ wait_sigint_received = 0; if (job_control == 0) - old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler); + { + old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler); + if (old_sigint_handler == SIG_IGN) + set_signal_handler (SIGINT, old_sigint_handler); + } termination_state = last_command_exit_value; |