[Rt-commit] rt branch, 3.8/open2-fileno, created. rt-3.8.12-2-gb7a5a53

Alex Vandiver alexmv at bestpractical.com
Thu May 24 14:14:47 EDT 2012

The branch, 3.8/open2-fileno has been created
        at  b7a5a5366475d75edffb6dcf0ed0191cdfb71818 (commit)

- Log -----------------------------------------------------------------
commit b7a5a5366475d75edffb6dcf0ed0191cdfb71818
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Thu May 24 13:49:49 2012 -0400

    Fix sending email with 'perl-script' mod_perl handler and 'sendmailpipe'
    ef35fe5 switched to using IPC::Open2 to communicate with the sendmail
    process.  Unfortunately, due to the way it is implemented, IPC::Open2
    assumes that the filehandle named STDIN is always on file descriptor 0;
    if it is not, the child process does not recieve the expected pipe on
    its FD 0, and mail fails to be sent.  This is manifest either as a
    SIGPIPE when the parent attempts to read from their end of the pipe, or
    an abnormal exit code if the child exits (noting it has no input) before
    Apache's mod_perl, when running under the 'perl-script' handler, not
    only TIEs STDIN and STDOUT, as noted in d80b1e4, but also moves them to
    not be on FD 0 and FD 1.  While RT 4.0 has moved to requiring the
    'modperl' handler (for more or less this exact reason), RT 3.8 is not
    prepared for such.
    In order to ensure that IPC::Open2 works on all deployment options,
    locally override STDIN to be on file descriptor 0, regardless of what FD
    0 is currently being used for.

diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index 6e48019..a8e2ce8 100755
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -450,6 +450,14 @@ sub SendEmail {
             # if something wrong with $mail->print we will get PIPE signal, handle it
             local $SIG{'PIPE'} = sub { die "program unexpectedly closed pipe" };
+            # Make it look to open2 like STDIN is on FD 0, like it
+            # should be; this is necessary because under mod_perl with
+            # the perl-script handler, it's not.  This causes our
+            # child's "STDIN" (FD 10-ish) to be set to the pipe we want,
+            # but FD 0 (which the exec'd sendmail assumes is STDIN) is
+            # still open to /dev/null; this ends disasterously.
+            local *STDIN = IO::Handle->new_from_fd( 0, "r" );
             require IPC::Open2;
             my ($mail, $stdout);
             my $pid = IPC::Open2::open2( $stdout, $mail, $path, @args )


More information about the Rt-commit mailing list