From c3114a7735c85b79771e08bd156470bde1a36950 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 26 Oct 2013 16:11:40 -0700 Subject: 31906: fix race-condition interaction of $pipestatus with job control printjob() should not reference oldjobtab for job numbers unless it is being called from bin_fg(). printjob() also must not attempt to update pipestats when called from bin_fg(). acquire_pgrp() should not loop infintely if the shell is not interactive. Update the $pipestatus stress test so that it also exercises the oldjobtab repair. --- Src/jobs.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'Src/jobs.c') diff --git a/Src/jobs.c b/Src/jobs.c index c218743f0..336c5d4cf 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -941,10 +941,13 @@ printjob(Job jn, int lng, int synch) int doneprint = 0, skip_print = 0; FILE *fout = (synch == 2 || !shout) ? stdout : shout; - if (oldjobtab != NULL) + if (synch > 1 && oldjobtab != NULL) job = jn - oldjobtab; else job = jn - jobtab; + DPUTS3(job < 0 || job > (synch > 1 ? oldmaxjob : maxjob), + "bogus job number, jn = %L, jobtab = %L, oldjobtab = %L", + (long)jn, (long)jobtab, (long)oldjobtab); if (jn->stat & STAT_NOPRINT) { skip_print = 1; @@ -995,7 +998,8 @@ printjob(Job jn, int lng, int synch) if (skip_print) { if (jn->stat & STAT_DONE) { /* This looks silly, but see update_job() */ - storepipestats(jn, job == thisjob, job == thisjob); + if (synch <= 1) + storepipestats(jn, job == thisjob, job == thisjob); if (should_report_time(jn)) dumptime(jn); deletejob(jn, 0); @@ -1128,7 +1132,8 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { /* This looks silly, but see update_job() */ - storepipestats(jn, job == thisjob, job == thisjob); + if (synch <= 1) + storepipestats(jn, job == thisjob, job == thisjob); if (should_report_time(jn)) dumptime(jn); deletejob(jn, 0); @@ -2610,6 +2615,8 @@ acquire_pgrp(void) while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) { mypgrp = GETPGRP(); if (mypgrp == mypid) { + if (!interact) + break; /* attachtty() will be a no-op, give up */ signal_setmask(oldset); attachtty(mypgrp); /* Might generate SIGT* */ signal_block(blockset); -- cgit 1.4.1