Re: [Exim] Exim 4.20 and Local_scan

Top Page
Delete this message
Reply to this message
Author: Kevin Smith
Date:  
To: mb
CC: ravi, exim-users
Subject: Re: [Exim] Exim 4.20 and Local_scan
mb <mb@???> wrote:
> At 16:53 +0100 Raviraj Jeyanolipavan wrote:
>
> >I am trying to use local_scan.c from L001 on the web site together
> >with McAfee's uvscan to virus check emails but on a test email I
> >keep getting "UVSCAN_ERROR: couldn't wait for child".
>
> Could you please verify it still fails please with my new script (don't
> think it made it into the 4.20 docs)?
>
> http://www.dcs.qmul.ac.uk/~mb/local_scan/local_scan.c
>
> >A small test program simulating the local_scan.c code doesn't get
> >these errors and I am unable to work out why this error occurs. This
> >is running on Solaris 8 on a SPARC platform.
>
> I've not tested it on this platform. Perhaps waitpid behaves differently?
> (Or more likely I've got a variable type wrong.. and it happens to work
> on Linux.)


This sounds like a problem I had where you couldn't wait on a
child process with SIGCHLD ignored, which is the case when you
enter local_scan (on my 4.12).

I set SIGCHLD handling to SIG_DFL on entry (remembering the original
setting), and reset it to the remembered value on exit.

I stole some code from elsewhere in the source. I also set SIGPIPE
to SIG_IGN to capture write errors to the pipe.

On entry to local_scan()

    /*
     * Setup signal handling
     * - Set child signal handling back to the default.
     *   Normal mode (in exim) is SIG_IGN which causes wait to wait
     *   for processes but it always returns -1 and no status.  This
     *   breaks trying to get a exit code from our scanner sub-process
     * - Set pipe signal handling to SIG_IGN so we get write errors
     *   rather than signals if our sub-process fails
     */
    void        (*oldPipeSig)();        /* Old pipe signal value */
#ifdef SA_NOCLDWAIT
    struct      sigaction act,oldChldSig;


    act.sa_handler = SIG_DFL;
    sigemptyset(&(act.sa_mask));
    act.sa_flags = 0;
    sigaction(SIGCHLD, &act, &oldChldSig);
#else
    void        (*oldChldSig)();        /* Old pipe signal value */


    oldChldSig = signal(SIGCHLD, SIG_DFL);
#endif
    oldPipeSig = signal(SIGPIPE,SIG_IGN);



On exit (remember to funnel all exit paths through this)

#ifdef SA_NOCLDWAIT
    sigaction(SIGCHLD, &oldChldSig, NULL);
#else
    (void)signal(SIGPIPE,oldChldSig);
#endif
    (void)signal(SIGPIPE,oldPipeSig);


--
Do two rights make | Kevin Smith, ShadeTree Software, Philadelphia, PA, USA
a libertarian      | 001-215-487-3811  shady,com,kevin