View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0000544 | tcsh | General | public | 2024-07-20 12:41 | 2024-07-20 12:41 |
| Reporter | alzwded | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | new | Resolution | open | ||
| Product Version | 6.24.13 | ||||
| Summary | 0000544: fix job count in set prompt=%j | ||||
| Description | (also opened a PR at https://github.com/tcsh-org/tcsh/pull/110 ) The job count reported by putting %j in $prompt is only updated after starting a (non builtin) command. Suspending something (^Z) or just having them exit does not. The code in question is in tc.prompt.c tprintf. The code that handles the `jobs' builtin works fine (`dojobs' from sh.proc.c). So this patch cut pastes that code in tc.prompt.c tprintf and replaces whatever that was. With this patch, %j prints the expected number of jobs (i.e. the same amount of jobs I'd count by running jobs), making it more useful. I couldn't wrap my head around why it was doing what it was doing. | ||||
| Steps To Reproduce | tested on master HEAD (as of July 20 2024) 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 Note after suspending the first ed, it stays 0. Note after suspending the SECOND ed, it goes to 1. I run sleep in the background, it is now 2. It exits, it is still 2. I kill the first ed. It is still two. I `fg' the last remaining ed (job %2 if anyone cares), and exit normally, it is still two. This is not useful. By transplanting the code from sh.proc.c: 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 Note, after ^Z-ing out of the first ed, it prints 1 (jobs would list a job). Suspending the second, prints 2. Running a sleep in the background, moves it to 3. After some time, hit enter, the shell prints [3] Done sleep 5, and %j results in 2 (correct). I kill the first ed (%1). Well, it stays "2" (jobs would list it as [1] Killed), but hitting enter does print [1] Killed and drops it to 1. I fg the last remaining ed (%2), quit, and the %j now prints 0 (as expected). %j is now useful. | ||||
| Additional Information | How did I end up with %j in my prompt? I got bored of closing down an unspecified number of vi's trying to reboot without keeping a ton of swp files around :-) | ||||
| Tags | No tags attached. | ||||
|
|
fix-percent-j.diff (1,164 bytes)
diff --git a/tc.prompt.c b/tc.prompt.c
index 65066f1..e86499b 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);
|