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

After playing with this question for a while this morning I have discovered some strange behaviour that appears to be related to the CGI module on Win32. Basically it appears to break reading from STDIN. I'm very bad at explaining things so take a look at this code:
#!/usr/bin/perl -w use strict; use CGI; my $indir = <STDIN>; chomp $indir; my $dir = 'c:/temp'; print "Opening $dir\n"; opendir (DIR, $dir) || die "Could not open dir: $!"; my @array=readdir (DIR); closedir (DIR); print "$_\n" foreach @array; print "Opening $indir\n"; opendir (INDIR, $indir) || die "Could not open dir: $!"; my @inarray=readdir (INDIR); closedir (INDIR); print "$_\n" foreach @inarray;
This works fine on a Linux machine but dies during the $indir open in the second part on a Win32 machine, all the $dir bits work just fine. Poking at the CGI.pm I notice this little bit of code:
if ($needs_binmode) { $CGI::DefaultClass->binmode(main::STDOUT); $CGI::DefaultClass->binmode(main::STDIN); $CGI::DefaultClass->binmode(main::STDERR); }
If I uncomment those then both opendirs work fine. Can anybody enlighten me as to why this is happening?

Replies are listed 'Best First'.
Re: Win32 CGI breaks STDIN?
by chipmunk (Parson) on Feb 01, 2001 at 00:14 UTC
    I expect the reason that the open(INDIR, $indir) part breaks is that, binmode() having been called on STDIN, $indir ends with a carriage return.

    my $indir = <STDIN>; # $indir = "directory\r\n"; # binmode stops the \r\n -> \n translation chomp $indir; # chomp removes $/, which is "\n" # the \r is left intact
    A quick fix in your script is to make sure the \r is removed as well.

    The ideal fix is for CGI not to call binmode() on STDIN when the script is run interactively.

      Perhaps even...

      if ($needs_binmode) { $CGI::DefaultClass->binmode(main::STDOUT) unless ( -t main::STDOUT ); $CGI::DefaultClass->binmode(main::STDIN) unless ( -t main::STDIN ); $CGI::DefaultClass->binmode(main::STDERR) unless ( -t main::STDERR ); }

      ?

Re: Win32 CGI breaks STDIN?
by the_slycer (Chaplain) on Feb 01, 2001 at 00:07 UTC
    Sorry, the last line there should read "If I comment these lines out ...."

    UPDATE: To answer the questions posed below as to why use <STDIN> in CGI:
    I have no idea why <STDIN> was being used. As I said, it was a question posted to Q&A that I noticed, started playing with, and was subsequently driven crazy by.. the \r does appear as though it was causing the problem.
Re: Win32 CGI breaks STDIN?
by $code or die (Deacon) on Feb 01, 2001 at 02:31 UTC
    This is probably a stupid question, but why are you using CGI in that script? I don't see you actually use any of it's methods...

    $code or die
    Using perl at
    The Spiders Web
Re: Win32 CGI breaks STDIN?
by InfiniteSilence (Curate) on Feb 01, 2001 at 21:09 UTC
    After thinking about it I agree with $code_or_die. Why would you use STDIN when using CGI? You can use the params() to get anything you want, even in offline mode by entering on the command line (you must use 'name=value' style in this mode like so:
    #!/usr/bin/perl -w use strict; use CGI; my $q = new CGI; print $q->header, $q->start_html('hello world'), $q->h1('hello world'), $q->end_html; 1;
    Don't forget to use ^Z on Win32 to break out of offline mode.

    Celebrate Intellectual Diversity