From d9100b8a4cbe568aded1208874e3bfd96d4c2846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vlad=20Me=C8=99co?= Date: Thu, 18 Jul 2024 10:40:32 +0200 Subject: [PATCH] Fix job count reported by set prompt=%j I noticed that if I have %j in my $prompt it wouldn't update until I run a (forked) command. Without this patch, on master HEAD: tcsh$ set prompt=%j\ 0 ed ^Z Suspended 0 ed ^Z Suspended 1 sleep 5 & [3] 317772 2 [3] Done sleep 5 2 kill -9 %1 2 [1] Killed ed 2 fg ed Q 2 Running a ls >& /dev/null in between would update the job count. I couldn't quite wrap my head around the existing code (like why it started at -1, but -1 was printed as 0, etc), but the `jobs' builtin seemed to always report the correct count. So I cut-pasted code from `dojobs' into the `%j' handler in tc.prompt.c so that it now reports the number of jobs in a way I actually expect. I don't know how to automate tests for this, I couldn't even effectively break into gdb because ^Z was involved and it ended up getting processed by the shell controlling the terminal and I gave up trying to figure it out with `kill(1)' blabla. Anyway... I tested by hand: tcsh$ set prompt='%j ' 0 ed ^Z Suspended 1 ed ^Z Suspended 2 sleep 5 & [3] 12345 3 [3] Done sleep 5 2 kill -9 %1 2 [1] Killed 1 fg ed Q 0 Notice how after coming out of `ed' after ^Z, the prompt is 1; same after the second one. Same after sleep. Killing a job does not update it, but I didn't want to mess with how it usually works and get in the way of the jobs builtin or how the shell eventually reports jobs that went away etc. If anyone has a better implementation, I'd be happy to test it/use it, but the existing code doesn't quite seem to work right. --- tc.prompt.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tc.prompt.c b/tc.prompt.c index 65066f11..e86499b9 100644 --- a/tc.prompt.c +++ b/tc.prompt.c @@ -538,13 +538,19 @@ tprintf(int what, const Char *fmt, const char *str, time_t tim, ptr_t info) case 'j': { - int njobs = -1; + int njobs = 0; struct process *pp; - for (pp = proclist.p_next; pp; pp = pp->p_next) - njobs++; - if (njobs == -1) - njobs++; + /* this counts jobs which haven't been "reaped" yet, but + unless you've just run kill -9 %1, it shouldn't be an issue */ + for (pp = proclist.p_next; pp; pp = pp->p_next) { + if (pp->p_index > 0 && pp->p_index <= pmaxindex + && pp->p_procid == pp->p_jobid) + { + ++njobs; + } + } + p = Itoa(njobs, 1, attributes); Strbuf_append(&buf, p); xfree(p);