2022年7月18日(月) 12:52 Koichi Murase <myoga.mur...@gmail.com>:
> Description:
>
>   In interactive shells, the foreground dead jobs (i.e., foreground
>   jobs that have already terminated) in trap handlers, commands called
>   through `bind -x', and `PROMPT_COMMAND' (...) are treated as
>   if they are the background dead jobs.

Sorry, I forgot to attach the patches. Here they are.

--
Koichi
From 3c274c2bbc792815e1142df30c1b3c285bfd5e4d Mon Sep 17 00:00:00 2001
From: Koichi Murase <myoga.mur...@gmail.com>
Date: Wed, 10 Feb 2021 17:37:02 +0900
Subject: [PATCH 1/2] clean up fg dead jobs in trap (Option 1)

---
 jobs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jobs.c b/jobs.c
index 2c91fb0e..278aac12 100644
--- a/jobs.c
+++ b/jobs.c
@@ -1226,7 +1226,7 @@ cleanup_dead_jobs ()
       if (i > js.j_lastj && jobs[i])
        INTERNAL_DEBUG(("cleanup_dead_jobs: job %d non-null after js.j_lastj 
(%d)", i, js.j_lastj));
 
-      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i))
+      if (jobs[i] && DEADJOB (i) && (IS_NOTIFIED (i) || IS_FOREGROUND (i)))
        delete_job (i, 0);
     }
 
-- 
2.36.1

From 7c0ee1548390f2929c315e388a2e5a4a52ae6841 Mon Sep 17 00:00:00 2001
From: Koichi Murase <myoga.mur...@gmail.com>
Date: Thu, 11 Feb 2021 01:21:21 +0900
Subject: [PATCH 1/2] clean up fg dead jobs in trap (Option 2)

---
 jobs.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/jobs.c b/jobs.c
index 2c91fb0e..b49c5cf6 100644
--- a/jobs.c
+++ b/jobs.c
@@ -1226,8 +1226,37 @@ cleanup_dead_jobs ()
       if (i > js.j_lastj && jobs[i])
        INTERNAL_DEBUG(("cleanup_dead_jobs: job %d non-null after js.j_lastj 
(%d)", i, js.j_lastj));
 
-      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i))
-       delete_job (i, 0);
+      if (jobs[i] && DEADJOB (i))
+       {
+         if (IS_NOTIFIED (i))
+           delete_job (i, 0);
+         else if (IS_FOREGROUND (i))
+           {
+             /* The control path usually does not come here because foreground
+                dead jobs are already notified in `notify_of_job_status'.
+                However, the control path can come here in trap handlers where
+                `notify_of_job_status' is skipped.  When the job is terminated
+                by a signal (the exist status is larger than 128), it is
+                notified even in trap handlers. */
+             WAIT s;
+             int termsig;
+             s = raw_job_exit_status (i);
+             termsig = WTERMSIG (s);
+#if !defined (DONT_REPORT_SIGPIPE)
+             if (termsig && WIFSIGNALED (s) && termsig != SIGINT)
+#else
+             if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != 
SIGPIPE)
+#endif
+               {
+                 fprintf (stderr, "%s", j_strsignal (termsig));
+                 if (WIFCORED (s))
+                   fprintf (stderr, _(" (core dumped)"));
+                 fprintf (stderr, "\n");
+               }
+
+             delete_job (i, 0);
+           }
+       }
     }
 
 #if defined (PROCESS_SUBSTITUTION)
-- 
2.36.1

From a00fc76b27c92a593b86fa131f1c06c8deec1e16 Mon Sep 17 00:00:00 2001
From: Koichi Murase <myoga.mur...@gmail.com>
Date: Thu, 11 Feb 2021 01:21:21 +0900
Subject: [PATCH 1/2] clean up fg dead jobs in trap (Option 3)

---
 jobs.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/jobs.c b/jobs.c
index 2c91fb0e..e8f6b79e 100644
--- a/jobs.c
+++ b/jobs.c
@@ -1226,8 +1226,32 @@ cleanup_dead_jobs ()
       if (i > js.j_lastj && jobs[i])
        INTERNAL_DEBUG(("cleanup_dead_jobs: job %d non-null after js.j_lastj 
(%d)", i, js.j_lastj));
 
-      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i))
-       delete_job (i, 0);
+      if (jobs[i] && DEADJOB (i))
+       {
+         if (IS_NOTIFIED (i))
+           delete_job (i, 0);
+         else if (IS_FOREGROUND (i))
+           {
+             /* Usually, foreground dead jobs may be immediately
+                deleted even when they are not flagged as
+                `IS_NOTIFIED (i)'.  However, signaled ones may be
+                later notified in `notify_of_job_status ()', so do
+                not delete them now.  The following condition is
+                copied from `notify_of_job_status ()'. */
+             WAIT s;
+             int termsig;
+             s = raw_job_exit_status (i);
+             termsig = WTERMSIG (s);
+#if !defined (DONT_REPORT_SIGPIPE)
+             if (termsig && WIFSIGNALED (s) && termsig != SIGINT)
+#else
+             if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != 
SIGPIPE)
+#endif
+               continue;
+
+             delete_job (i, 0);
+           }
+       }
     }
 
 #if defined (PROCESS_SUBSTITUTION)
@@ -2073,7 +2097,8 @@ print_job (job, format, state, job_index)
      JOB *job;
      int format, state, job_index;
 {
-  if (state == -1 || (JOB_STATE)state == job->state)
+  if ((state == -1 && !(DEADJOB (job_index) && IS_FOREGROUND (job_index))) ||
+    (JOB_STATE)state == job->state)
     pretty_print_job (job_index, format, stdout);
   return (0);
 }
@@ -3283,7 +3308,7 @@ wait_for_any_job (flags, ps)
     {
       if ((flags & JWAIT_WAITING) && jobs[i] && IS_WAITING (i) == 0)
        continue;               /* if we don't want it, skip it */
-      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i) == 0)
+      if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i) == 0 && IS_FOREGROUND (i) 
== 0)
        {
 return_job:
          r = job_exit_status (i);
-- 
2.36.1

Reply via email to