On Wed, Nov 14, 2007 at 11:47:09AM -0800, John DuBois wrote:
> On Fri, Nov 09, 2007 at 12:49:37PM +0100, Dr. Werner Fink wrote:
> > as ksh script like
> > 
> >   #!/bin/ksh
> >   echo starting ./testsig
> >   ./testsig
> >   echo ending
> > 
> > does not ignore SIGINT but does exit.  The bash and also all
> > bourne shell I know ignores as long the job ./testsig is
> > running which is that the jon its self receives the SIGINT.
> 
> I see this problem too, on all of my test platforms (Linux, OS X, and
> OpenServer).
> 
> If I run this on any of those OSes:
> 
> ksh -c "ksh -c \"trap '' INT; sleep 1000\"; print"
> 
> and send an interrupt, the parent shell exits and leaves the child process
> hanging around.  This happens in ksh93f, o, and r.  Using ksh88, bash, sh, or
> zsh for the outer shell, the interrupt is ignored.
> 
> ksh88's signal disposition in this test:
> 
>         sig#      signal oldmask sigmask
>            1:  0x8051000    -     1
>            2:  0x80519b0    -     2
>            3: ignore        -     3
>            4:  0x8051000    -     4
>            5:  0x8051000    -     5
>            6:  0x8051000    -     6
>            7:  0x8051000    -     7
>            8:  0x8051000    -     8
>           10:  0x8051000    -    10
>           12:  0x8051000    -    12
>           13:  0x8051000    -    13
>           14:  0x80519b0    -    14
>           15:  0x8051000    -    15
>           16:  0x8051000    -    16
>           17:  0x8051000    -    17
>           18: default       -    18
>           20:  0x80519b0    -    20
>           31: ignore        -    31
> 
> ksh93's signal disposition in the same test:
> 
>         sig#      signal oldmask sigmask
>           18:  0x80567a0    -
> 
>     John

I've just hacked a bit to work around this problem, you may try
out the patch in the attachment. It should apply to ksh93s+ from
2007-11-05 and also from 2007-06-28.

The main difference is a one line, which adds sh_sigdone() within
the non-interactive initialization part of exfile() in sh/main.c.

I've marked also SIGINT with the SH_SIGDONE bit in data/signals.c
which enables me to catch SIGINT and also SIGQUIT within sh_fault()
in sh/fault.c.  For a forked or a sub shell and without job I jump
to the old way of signal handling (which makes SIGINT working
within an interactive or non-interactive shell as without this
patch).  With a running job the SIGINT is simply ignored.

For SIGQUIT I use the same behavior as it the bash does, it will
be ignored in any case.

In the last two years I've got a lot of bug reports with the ksh
from users switching from AIX/HP-UX to Linux and run into problems
with their old ksh scripts.  This problem is likewise.  Now after
a lot patches I've done the question rises: where the patches done
by IBM and/or HP developers can be found?  It is very uncommon
within open source community to loose patches.

If there are any patches or changes included, the names of the
(initial) author(s) are not found in the RELEASE files.  In such
cases a bugzilla number would help.


       Werner

-- 
 Dr. Werner Fink <[EMAIL PROTECTED]>
 SuSE LINUX Products GmbH,  Maxfeldstrasse 5,  Nuernberg,  Germany
 GF: Markus Rex,  HRB 16746 (AG Nuernberg)
 phone: +49-911-740-53-0,  fax: +49-911-3206727,  www.opensuse.org
------------------------------------------------------------------
  "Having a smoking section in a restaurant is like having
          a peeing section in a swimming pool." -- Edward Burr
--- src/cmd/ksh93/sh/main.c
+++ src/cmd/ksh93/sh/main.c     2007-11-13 13:07:40.000000000 +0000
@@ -418,6 +418,7 @@ static void exfile(register Shell_t *shp
                        sh_onoption(SH_TRACKALL);
                        sh_offoption(SH_MONITOR);
                }
+               sh_sigdone();
                sh_offstate(SH_INTERACTIVE);
                sh_offstate(SH_MONITOR);
                sh_offstate(SH_HISTORY);
--- src/cmd/ksh93/sh/fault.c
+++ src/cmd/ksh93/sh/fault.c    2007-11-13 13:53:15.000000000 +0000
@@ -98,12 +98,27 @@ void        sh_fault(register int sig)
                if(flag&SH_SIGDONE)
                {
                        void *ptr=0;
-                       if((flag&SH_SIGINTERACTIVE) && 
sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_FORKED) && ! shp->subshell)
+                       switch (sig)
                        {
-                               /* check for TERM signal between fork/exec */
-                               if(sig==SIGTERM && job.in_critical)
-                                       shp->trapnote |= SH_SIGTERM;
-                               return;
+                               case SIGINT:
+                                       if(sh_isstate(SH_FORKED) || 
shp->subshell)
+                                               goto out;
+                                       if(!job.in_critical)
+                                               goto out;
+                                       return;
+                               case SIGTERM:
+                                       if(sh_isstate(SH_FORKED) || 
shp->subshell)
+                                               break;
+                                       /* check for TERM signal between 
fork/exec */
+                                       if(job.in_critical)
+                                               shp->trapnote |= SH_SIGTERM;
+                                       if((flag&SH_SIGINTERACTIVE) && 
sh_isstate(SH_INTERACTIVE))
+                                               return;
+                                       break;
+                               case SIGQUIT:
+                                       return;
+                               default:
+                                       break;
                        }
                        shp->lastsig = sig;
                        sigrelease(sig);
@@ -136,6 +151,7 @@ void        sh_fault(register int sig)
                        return;
                }
        }
+out:
        errno = 0;
        if(pp->mode==SH_JMPCMD)
                shp->lastsig = sig;
--- src/cmd/ksh93/data/signals.c
+++ src/cmd/ksh93/data/signals.c        2007-11-13 13:55:49.000000000 +0000
@@ -20,6 +20,7 @@
 #include       <ast.h>
 #include       "shtable.h"
 #include       "fault.h"
+#include       "jobs.h"
 
 #if defined(SIGCLD) && !defined(SIGCHLD)
 #   define SIGCHLD     SIGCLD
@@ -95,9 +96,9 @@ const struct shtable2 shtab_signals[] =
        "HUP",          VAL(SIGHUP,SH_SIGDONE),         S("Hangup"),
        "ILL",          VAL(SIGILL,SH_SIGDONE),         S("Illegal 
instruction"),
 #ifdef JOBS
-       "INT",          VAL(SIGINT,SH_SIGINTERACTIVE),  S("Interrupt"),
+       "INT",          VAL(SIGINT,SH_SIGDONE|SH_SIGINTERACTIVE),       
S("Interrupt"),
 #else
-       "INT",          VAL(SIGINT,SH_SIGINTERACTIVE),  "",
+       "INT",          VAL(SIGINT,SH_SIGDONE|SH_SIGINTERACTIVE),       "",
 #endif /* JOBS */
 #ifdef SIGIO
        "IO",           VAL(SIGIO,SH_SIGIGNORE),        S("IO signal"),
_______________________________________________
ast-users mailing list
[email protected]
https://mailman.research.att.com/mailman/listinfo/ast-users

Reply via email to