Jenda has asked for the wisdom of the Perl Monks concerning the following question:

I was notified that Mail::Sender (sending emails through SMTP via socket()s) doesn't work with Perl 5.8 with some SMTP servers if the script runs under Windows.

I tried to compile 5.8 myself (Win2k, perlio enabled) and used a TCP/IP sniffer to see what do I send to the server, and sure enough ... even though I do binmode($socket); the \x0D\x0A I send into the socket gets changed into 0D0D0A.

I tried to use binmode( $socket, ':raw:perlio') as well as binmode( $socket, ':raw'), but it did not change the results at all.

Adding

use open OUT => ':raw';
or
use open OUT => ':raw:perlio';
into the module did help though. Since I would like to be able to support 5.005, I cannot just add the use statement into the module, but
BEGIN { if ($] >= 5.008) { require 'open.pm'; 'open'->import(OUT=>":raw:perlio"); } }
seems to work fine.

I'm also using

binmode($s) unless ($] >= 5.008);
later though that's probably not necessary.

I don't like this solution though. Is there any other (better) way? What should I do?

Thanks, Jenda

Replies are listed 'Best First'.
Re: Perl 5.8, sockets and binmode()
by Aristotle (Chancellor) on Nov 06, 2002 at 20:14 UTC
    How about (untested!) something like this for clarity:
    BEGIN { eval "require 5.008; use open OUT => ':raw:perlio'; sub _binmode() + {}"; eval "sub _binmode { binmode @_ }" if $@; }
    Then replace the binmode with _binmode and everything should happen automagically. The prototype will even cause these calls to be optimized away complete on Perls that don't need them.

    Makeshifts last the longest.

      I guess I could redefine the binmode(). I can't use the sub binmode () {} though ... keep in mind that the procedure gets some parameters. So it can't be optimized away. It's a shame the $] is not treated as a constant. If it was then the binmode(...) unless $] < 5.008 could be optimized away. Not that it matters.

      But the use open ... within the eval "" doesn't work. The use open pragma seems to be lexical if used this way. That's why am I using the require() and 'open'->import().

      Jenda

        Ah, but you can retrofit that.
        use constant PRE_5_8 => $[ < 5.008; binmode $fh if PRE_5_8;
        You can also use the constant for the BEGIN block if you are so inclined, of course (provided you define it before the block).

        Makeshifts last the longest.

Re: Perl 5.8, sockets and binmode()
by RMGir (Prior) on Nov 07, 2002 at 14:25 UTC
    Your fix (and the other suggestions here) all seem reasonable to me.

    This is a known problem, by the way, so it's already been fixed in the development branches.
    --
    Mike