Archive for May, 2005

[BUG] Mail::Mailer, Mail::Internet, and MIME::Entity fork / eval oddity

Tuesday, May 24th, 2005

The Perl module Mail::Mailer, and those modules that rely upon it (at
least, Mail::Internet and MIME::Entity), have an undocumented fork that
can wreak havoc with your code if you call the send() method within an
eval \{\} block.  The solution is to either be very anal about
checking for PIDs or to use a different means for sending your
messages, like MIME::Lite.

Briefly, the problem is that the sending procedure forks, using the
open(“|-“) idiom to create a filehandle for writing to the child, which
immediately exec()’s a sendmail (or whatever) process.  The parent
returns the filehandle, to which is printed the message; the filehandle
is then closed for final sending (this is all hidden in the
Mail::Internet and MIME::Entity classes’ send() method).  However,
if you are running in taint mode with an insecure path (for one
example), the exec() will fail in the child and will die.

If you were running this in an eval \{\} block, and didn’t account for
the possibility of a fork within the eval\{\}, you could find that both
code paths — the success AND the failure code blocks — get
executed.  Since this is often done for db transactions or other
things that might be shared external resources, this could lead to some
nasty race conditions.

In defense of Mail::Mailer, it is *technically* the job of the coder to
check on forks, but this argument ad absurdum would have every line
that calls module code wrapped in an elaborate eval with checking of
the PIDs.  Clearly not OK.

I have explained this bug and opened it up to discussion on
perlmonks.org, at http://perlmonks.org/index.pl?node_id=459739 and have
reported the bug in Mail::Mailer under the MailTools distribution at
http://rt.cpan.org/NoAuth/Bug.html?id=12890

The workaround at present is to either 1. obsessively check the PIDs
before and after the eval, or 2. use MIME::Lite, which appears not to
fork.  NOT a valid workaround would be to ignore this becaues your
exec() hasn’t died yet or to turn off taint mode.

[BUG] Mail::Mailer, Mail::Internet, and MIME::Entity fork / eval oddity …

FIX: Compiling SWI-Prolog on Mac OS X 10.2

Monday, May 16th, 2005

SWI-Prolog is available as prepackaged binaries for Mac OS X 10.3+, but
not for 10.2.  If you try and install the 10.3 binary package, you
will get errors (at least, I did).  The answer is to compile from
source.  You are probably compile-savvy if you are looking to
install a Prolog interpreter, but if not, it’s a fairly painless
./configure, make, make install process.

1. However, the docs warn that you’ll want readline and a number of
other libraries installed.  There are some binary packages on the
SWI-Prolog site.  If you want to use those, and you don’t have any
other versions of the libraries, so be it — but I would recommend
using Fink instead, so that you can install the most up to date
versions.

2. Especially if using Fink, be sure to alert the ./configure script to
the locations by including LDFLAGS=”-I /sw/include” and CFLAGS=”-L
/sw/lib” (or wherever).

For me, all it took was pointing the configure script to the /sw tree and it compiled with no further questions.