Hello, I'm trying to execute some CGI scripts by creating a CGI-like environment in a "driver program" and then running the CGI scripts with an open3 call. My most basic "CGI script" just prints some output to STDOUT and STDERR and my driver program can read both sets of output. When I try to run a real CGI script, I get illegal seek errors while reading STDERR. How do I debug this?

What are likely causes of illegal seek errors? My first thought was that the CGI script is doing something funky with the file handles, but I've tried recreating that in my testprog.pl to no avail.

I've distilled the concept down this example: test_servicing_request.pl:
#!/usr/bin/perl use strict; use warnings; use IPC::Open3; use Symbol; my $input = ''; my $_env = { 'SCRIPT_NAME' => '', 'SERVER_NAME' => 'my.site.example.com', 'HTTP_REFERER' => 'https://myother.site.example.com/', 'HTTP_ACCEPT_ENCODING' => 'gzip, deflate', 'PATH_INFO' => '/index.cgi', 'HTTP_CONNECTION' => 'Keep-Alive', 'REQUEST_METHOD' => 'GET', 'HTTP_ACCEPT' => '*/*', 'HTTP_UA_CPU' => 'x86', 'SERVER_SOFTWARE' => 'Apache', 'REMOTE_USER' => 'mylogonid', 'AUTH_TYPE' => 'Basic', 'HTTP_CLIENT_IP' => '112.113.114.115', 'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows N +T 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 1.1.4322; +MS-RTC LM 8)', 'QUERY_STRING' => '', 'SERVER_PORT' => '443', 'HTTP_COOKIE' => '', 'HTTP_ACCEPT_LANGUAGE' => 'en-us', 'REMOTE_ADDR' => '123.124.125.126', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'GATEWAY_INTERFACE' => 'CGI/1.1', 'HTTP_HOST' => 'my.site.example.com', 'PATH_TRANSLATED' => '/content/my.site.example.com/proxy.cgi/index +.cgi' }; # save the calling applications environment my $env_snapshot = { %ENV }; # merge a CGI-style environment foreach my $key (keys(%{$_env})) { if (!exists($ENV{$key})) { $ENV{$key} = $_env->{$key}; } } #my $cmd = '/home2/servicing' . ($ENV{'PATH_INFO'} || '/index.cgi'); my $cmd = '/tmp/testprog.sh'; my $dir = `dirname $cmd`; chomp $dir; # If PROG_STDERR isn't initialized then open3 treats it as a false # value and sends STDERR to STDOUT. Dumb default behavior; I'm using +open3 # because I want to capture that output! my $PROG_STDERR = gensym(); print "Executing $cmd\n"; my $pid = open3(my $PROG_STDIN, my $PROG_STDOUT, $PROG_STDERR, 'cd ' . + $dir . ' && ' . $cmd) or die $@; print "PROG_STDIN: $PROG_STDIN, tell(PROG_STDIN): " . tell($PROG_STDIN +) . "\n"; if ($input) { print $PROG_STDIN $input or die "Error sending data to STDIN: $!"; } close($PROG_STDIN); waitpid $pid, 0; print "PROG_STDOUT: $PROG_STDOUT, tell(PROG_STDOUT): " . tell($PROG_ST +DOUT) . "\n"; my $output = join('', <$PROG_STDOUT>) or die "Error reading data from +STDOUT: $!"; close($PROG_STDOUT); print "output: $output\n"; print "PROG_STDERR: $PROG_STDERR, tell(PROG_STDERR): " . tell($PROG_ST +DERR) . "\n"; my $error = join('', <$PROG_STDERR>) or die "Error reading data from S +TDERR: $!"; close($PROG_STDERR); print "error: $error\n"; # restore our environment %ENV = %{ $env_snapshot };
testprog.sh
#!/bin/sh exec ./testprog.pl
testprog.pl
#!/usr/bin/perl print "Sleeping for 3 seconds\n"; sleep 3; print "Sleeping for 5 seconds\n"; sleep 5; print STDERR "The sky is falling.\n";
Which executes successfully:
Executing /tmp/testprog.sh PROG_STDIN: GLOB(0x17f250), tell(PROG_STDIN): -1 PROG_STDOUT: GLOB(0x17f268), tell(PROG_STDOUT): -1 output: Sleeping for 3 seconds Sleeping for 5 seconds PROG_STDERR: GLOB(0x17f220), tell(PROG_STDERR): -1 error: The sky is falling.
Changing which $cmd I'm executing results in the illegal seek error:
Executing /home2/servicing/index.cgi PROG_STDIN: GLOB(0x17f274), tell(PROG_STDIN): -1 PROG_STDOUT: GLOB(0x17f28c), tell(PROG_STDOUT): -1 output: Content-type: text/html <HTML> <HEAD> <TITLE>Error</TITLE> </HEAD> <BODY TEXT="#000000" LINK="#0000FF" VLINK="#0000FF" BGCOLOR="#C0C0C0"> <CENTER> <FONT SIZE="+2" COLOR="#FF0000"> <P> <br /> Your attempt to log onto website failed.&nbsp; This is due to a proble +m NOT related to correctly keying your User ID and Password. <P> In order to access our secure websites, please report this event to +at <a href="mailto:customer_service@sample.com" tabindex="-1">customer_se +rvice@sample.com</a> or 111-111-1111.&nbsp; We will research the problem and assist you with your data and transac +tion needs. <P> Thank you for your assistance. </FONT> </CENTER> </BODY> </HTML> PROG_STDERR: GLOB(0x17f244), tell(PROG_STDERR): -1 Error reading data from STDERR: Illegal seek at test_servicing_request +.pl line 74.

In reply to open3 and illegal seeks by brainsick

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.