capture/supress stdout from perl module called from cgi

P

project2501

i have a problem. i'm using apache with perl cgi and the cgi calls
functions from the VCS::CVS module. this is fine... but the
CVS::commit($message) sends items to stdout.

sterr is fine as the webserver redirects that to the apache error logs,
but stdout appears before html stream headers "content type etc" ... and
so the server logs a "malformed header from script. Bad header=..." error
as expected.

i wonder if i can block stdout around that block of code... i've
investigated the use iof eval{} but there don't appear to be options to do
this. the CVS::CVS module itself cannot be set to not output stdout.

any help appreciated.

t
 
E

Eric Bohlman

i have a problem. i'm using apache with perl cgi and the cgi calls
functions from the VCS::CVS module. this is fine... but the
CVS::commit($message) sends items to stdout.

sterr is fine as the webserver redirects that to the apache error
logs, but stdout appears before html stream headers "content type etc"
... and so the server logs a "malformed header from script. Bad
header=..." error as expected.

i wonder if i can block stdout around that block of code... i've
investigated the use iof eval{} but there don't appear to be options
to do this. the CVS::CVS module itself cannot be set to not output
stdout.

Would IO::Scalar be any help?
 
A

Anno Siegel

project2501 said:
i have a problem. i'm using apache with perl cgi and the cgi calls
functions from the VCS::CVS module. this is fine... but the
CVS::commit($message) sends items to stdout.

Well, it shouldn't. No module should print to stdout unless that is
its express purpose.
sterr is fine as the webserver redirects that to the apache error logs,

I wouldn't call that "fine", but yes, error logs have a big belly.
but stdout appears before html stream headers "content type etc" ... and
so the server logs a "malformed header from script. Bad header=..." error
as expected.

i wonder if i can block stdout around that block of code... i've
investigated the use iof eval{} but there don't appear to be options to do
this. the CVS::CVS module itself cannot be set to not output stdout.

Eval is for very different purposes. That it can be used to suppress
unwanted error output bears only a superficial resemblance to your
situation.

The solution depends a bit on what the module actually does. If it
just print()s without a filehandle argument (most likely), select()
is the solution. You need a filehandle to redirect the unwanted
output to (you *could* use STDERR for that, but opening /dev/null may
be a better idea, if available). So (untested):

my $devnull;
open $devnull, ">", $_ or die "Can't write to $_" for '/dev/null';
my $oldfh = select( $devnull);

# code that *prints* *things*

select( $oldfh);

# code that is entitled to print

If the module explicitly prints to STDOUT, stronger medicine is indicated
(and available), but that won't be necessary.

Anno
 
I

Ilmari Karonen

i wonder if i can block stdout around that block of code... i've
investigated the use iof eval{} but there don't appear to be options to do
this. the CVS::CVS module itself cannot be set to not output stdout.

You don't mention if the output comes from VCS::CVS itself or from
some external program it calls. In any case, you can capture the
output by reopening STDOUT to a temporary file:

use File::Temp qw(tempfile);

my $tempfile = tempfile() or die "Can't create temp file: $!\n";
open TMPOUT, '>&', \*STDOUT or die "Can't dup stdout: $!\n";
open STDOUT, '>&', $tempfile or die "Can't redirect stdout: $!\n";

# ... do something ...

open STDOUT, '>&', \*TMPOUT or die "Can't restore stdout: $!\n";
seek $tempfile, 0, 0 or die "Can't rewind temp file: $!\n";
my @lines = <$tempfile>;

If you just want to send any output to the bit bucket, that's even
easier:

open TMPOUT, '>&', \*STDOUT or die "Can't dup stdout: $!\n";
open STDOUT, '>/dev/null' or die "Can't redirect stdout: $!\n";
# ... do something ...
open STDOUT, '>&', \*TMPOUT or die "Can't restore stdout: $!\n";
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top