CGI: Execute a perl script inside another perl script

X

xdarcos

Hello,

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

[12/Jan/2005:10:43:22] failure ( 632): for host 10.70.176.104 trying
to POST /surcouf.cgi, cgi_scan_headers reports: HTTP4044: the CGI
program C:\Perl\bin\perl.exe did not produce a valid header (program
terminated without a valid CGI header. Check for core dump or other
abnormal termination).

Here is my perl script:

#!C:/perl/bin/perl.exe

exec('envCGI.pl');

//Then an exe is executed (in which the content-type is set) and the
HTML page is well displayed.
$matchAdmin = "Routage%3DADMIN";
$matchConso = "Routage%3DCONSO";
if ($ENV{QUERY_STRING} =~ /$matchAdmin/)
{
$cmd = 'admin.exe'; exec($cmd);
}
elsif ($ENV{QUERY_STRING} =~ /$matchConso/)
{
$cmd = 'conso.exe'; exec($cmd);
}
else
{
$cmd = 'contrat.exe'; exec($cmd);
}

I tried also to use: system('envCGI.pl'). There are no errors but the
variables are not set. Is there an equivalent of EXPORT command of Unix
?

Thanks for your help
Xavier
Note:I am using SunOne Web Server 6.1 and I am under Windows 2000
 
P

Paul Lalli

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

[12/Jan/2005:10:43:22] failure ( 632): for host 10.70.176.104 trying
to POST /surcouf.cgi, cgi_scan_headers reports: HTTP4044: the CGI
program C:\Perl\bin\perl.exe did not produce a valid header (program
terminated without a valid CGI header. Check for core dump or other
abnormal termination).

Here is my perl script:

#!C:/perl/bin/perl.exe

exec('envCGI.pl');

You need to read up on what exec actually does
perldoc -f exec

I tried also to use: system('envCGI.pl'). There are no errors but the
variables are not set. Is there an equivalent of EXPORT command of Unix
?

this launches an entirely seperate process. Any environment variables
set in that process are set only for that process.

If your seperate file is only modifying globals (which %ENV is), you can
just use the do 'file' syntax.

perldoc -f do

Paul Lalli
 
G

Gunnar Hjalmarsson

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

[12/Jan/2005:10:43:22] failure ( 632): for host 10.70.176.104 trying
to POST /surcouf.cgi, cgi_scan_headers reports: HTTP4044: the CGI
program C:\Perl\bin\perl.exe did not produce a valid header (program
terminated without a valid CGI header. Check for core dump or other
abnormal termination).

Here is my perl script:

#!C:/perl/bin/perl.exe

Why don't you have:

use strict;
use warnings;
exec('envCGI.pl');

Have you read the docs for the exec() function?

perldoc -f exec
//Then an exe is executed (in which the content-type is set)

Odd way to set content-type in a Perl program.
and the HTML page is well displayed.
$matchAdmin = "Routage%3DADMIN";
$matchConso = "Routage%3DCONSO";
if ($ENV{QUERY_STRING} =~ /$matchAdmin/)
{
$cmd = 'admin.exe'; exec($cmd);
}
elsif ($ENV{QUERY_STRING} =~ /$matchConso/)
{
$cmd = 'conso.exe'; exec($cmd);
}
else
{
$cmd = 'contrat.exe'; exec($cmd);
}

I tried also to use: system('envCGI.pl').

Have you read the docs for the system() function?

perldoc -f system

Don't just try, read the docs, too.

Anyway, neither exec() nor system() is an appropriate way to include a
Perl program in another Perl program. I suppose that you should use 'do'
instead.

do 'envCGI.pl';

See "perldoc -f do".
 
J

Jürgen Exner

Hello,

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

Your Question is Asked Frequently, please see "perldoc -q environment":

I {changed directory, modified my environment} in a perl script. How come
the change disappeared when I exited the script? How do I get my changes to
be visible?

jue
 
C

Chris Mattern

Hello,

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

[12/Jan/2005:10:43:22] failure ( 632): for host 10.70.176.104 trying
to POST /surcouf.cgi, cgi_scan_headers reports: HTTP4044: the CGI
program C:\Perl\bin\perl.exe did not produce a valid header (program
terminated without a valid CGI header. Check for core dump or other
abnormal termination).

Here is my perl script:

#!C:/perl/bin/perl.exe

exec('envCGI.pl');

And nothing beyond this line executes, since envCGI.pl completely
replaces the currently running program. perldoc -f exec.
//Then an exe is executed (in which the content-type is set) and the
HTML page is well displayed.
$matchAdmin = "Routage%3DADMIN";
$matchConso = "Routage%3DCONSO";
if ($ENV{QUERY_STRING} =~ /$matchAdmin/)
{
$cmd = 'admin.exe'; exec($cmd);
}
elsif ($ENV{QUERY_STRING} =~ /$matchConso/)
{
$cmd = 'conso.exe'; exec($cmd);
}
else
{
$cmd = 'contrat.exe'; exec($cmd);
}

I tried also to use: system('envCGI.pl'). There are no errors but the
variables are not set.

Of course not. system spawns a child process. What the child
process does with its environment variables cannot affect the
parent.
Is there an equivalent of EXPORT command of Unix
?

Er, you don't understand environment variables. Children cannot affect
the environment of their parents. This is universally true in Unix, and
export can't--and doesn't--change that.
Thanks for your help
Xavier
Note:I am using SunOne Web Server 6.1 and I am under Windows 2000

Don't know much about environment variables in Windows, but your approach
seems to be fundamentally flawed.

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
X

xdarcos

Thanks all for your answers but it doesn't work yet :-(.
So OK, 'exec' is not the good solution, neither 'system'.
I didn't know the 'do' function, I tried it but without success: in my
exe, the environnement variables I have set in 'envCGI.pl' are still
unknown.

Regarding "perldoc -q environment" Jürgen, this is dedicated to Unix
and I am using Windows

Note that my exe is developed in C++, not in perl. The perl script is
here to call the right exe depending on the query string.
Any new help will be welcome.
Thanks
Xavier
 
B

Brian McCauley

Thanks all for your answers but it doesn't work yet :-(.
So OK, 'exec' is not the good solution, neither 'system'.
I didn't know the 'do' function, I tried it but without success: in my
exe, the environnement variables I have set in 'envCGI.pl' are still
unknown.

Please always produce a _minimal_ but _complete_ test case.

I just did this on my windows box here and was unable to reproduce the
problem.

------------x.pl---------------
do 'y.pl';
system 'cmd';
-------------------------------

------------y.pl---------------
$ENV{FOO}='BAR';
-------------------------------

When I run x.pl the child cmd.exe could see the environment variable set
in y.pl.

Rather than expecting each person who tries to help to produce a minimal
but complete test case to attempt to reproduce the symptoms is is much
more efficient (and polite) for the person asking the question to do so.

Often the act of doing so will find the problem.

Have you read the posting guidelines that are posted here frequenting?
They contain a lot of valuable advice that will help you to get answers
and also help you to avoid accidently giving the appearance of being
lazy/arrogant/selfish.
Regarding "perldoc -q environment" Jürgen, this is dedicated to Unix
and I am using Windows

What it says applies largely to Windows too. I believe there is in
Windows a way to alter the environment variables of another process -
but that's low-level OS-specific stuff that you'd need to discuss in an
OS specific group.
 
J

Jürgen Exner

Regarding "perldoc -q environment" Jürgen, this is dedicated to Unix
and I am using Windows

Actually, this particular behaviour (modifications of the environment of a
child process will never be back-propped to the parent process) applies to
Windows, too.

jue
 
X

xdarcos

Hello all,

I found your responses very strong and the idea of you might think that
I am "lazy/arrogant/selfish" make me feel uncomfortable because this is
not me. So the word "accidently" was well chosen because this was not
at all my purpose.
What I didn't mention is that I was a real perl beginner. My first
script was working well but all the environment variables were in it.
So I decided to move them to another one. You mentioned to have a look
to "perldoc -f do" OK but if you don't know the "do" command, it is not
so easy. I can also maybe explain that because I am not fluent in
English, my question could have been felt too direct. I would like to
apologize if it is what you felt.

To come back to my problem:
Brian, the short example you gave me works well also for me.
But when I try to use it with my web server (SunOne Web Server), it is
not working anymore:

------------x.pl---------------
do 'y.pl';

print "Content-type:text/html\n\n";
print "<html><head><title>HTTP Environment</title></head> <body>";
print "FOO=".$ENV{FOO};
print "</body></html>";
----------------------------------

Here is the output I get in my HTML browser:
FOO=

To be more complete in my investigation, I tried also with Apache and
here is what I get:
FOO=BAR
This works !!
So it seems this is a configuration problem of SunOne i.e nothing to do
with Perl.

Thanks for time and sorry for the inconvenience.
Have a good day.
Xavier
 
B

Brian McCauley

Brian, the short example you gave me works well also for me.
But when I try to use it with my web server (SunOne Web Server), it is
not working anymore:

------------x.pl---------------
do 'y.pl';

print "Content-type:text/html\n\n";
print "<html><head><title>HTTP Environment</title></head> <body>";
print "FOO=".$ENV{FOO};
print "</body></html>";
----------------------------------

Here is the output I get in my HTML browser:
FOO=

To be more complete in my investigation, I tried also with Apache and
here is what I get:
FOO=BAR
This works !!
So it seems this is a configuration problem of SunOne i.e nothing to do
with Perl.

As you say this is not related to Perl. The CGI standard does not define
the setting of the current working directory when a CGI process is
spawned. In the case of Apache it (almost?) always sets the CWD to the
directory containing the script. I'm guessing that SunOne does not do
this. You need to use a fully qualified filename in the do().
 
X

xad

Thanks for your response. You were right, it works with the full path
to the script in the do().
The only concern is that I also wanted to put all environment variables
in one script in order to give users the ability to modify it by
setting their own configurations files, and in another side keeping a
generic root script not to be modified. So now they will also need to
modify the root script.
Anyway I thought that SunOne Web Server was based on Apache. Isn't it
right ?

Xavier
 
G

Gunnar Hjalmarsson

Brian said:
As you say this is not related to Perl.

I think it is.
The CGI standard does not define the setting of the current working
directory when a CGI process is spawned. In the case of Apache it
(almost?) always sets the CWD to the directory containing the script.
I'm guessing that SunOne does not do this.

"do" does not use the working directory, it searches @INC if the path is
relative.

perldoc -f do
You need to use a fully qualified filename in the do().

Suppose you mean the full path. That always works, of course, but you
can also do:

use lib '.';
do 'y.pl';
 
G

Gunnar Hjalmarsson

xad said:
Thanks for your response. You were right, it works with the full path
to the script in the do().

It should be noted that a simple check for success would have saved you
some trouble:

do 'y.pl' or die "Couldn't execute y.pl: $!";
The only concern is that I also wanted to put all environment variables
in one script in order to give users the ability to modify it by
setting their own configurations files, and in another side keeping a
generic root script not to be modified. So now they will also need to
modify the root script.

Not if you do:

use lib '.';
do 'y.pl';

See my reply to Brian.
 
B

Brian McCauley

Gunnar said:
I think it is.

"do" does not use the working directory, it searches @INC if the path is
relative.

I always seem to forget that. For some inexplicable reason I always
imagine that the @INC search is in require() not in the lower level do().
 
J

Jürgen Exner

Ryan said:
Try
system('C:/perl/bin/perl.exe envCGI.pl');

And why do you think that if called with an absolute path the child process
would be able to overwrite environment variables in the parent process?

jue
 
A

Alan J. Flavell

Try

system('C:/perl/bin/perl.exe envCGI.pl');

Why would the hon Usenaut need to "try" it? - aren't you sure it's
going to work? Where's your explanation of what you suppose the
questioner was doing wrong? Where's your explanation of how you
imagine the called process is going to be able to set environment
variables in the calling process?

TOFU posters rarely do. Statistically, in my experience, their
answers rarely address the substantive issues in the material that
they are so comprehensively quoting - but rarely, it seems, bothered
to read.

[ fullquote snipped ]

That's the point, just in case you still didn't get it.
 
W

Wes Groleau

I am using perl scripts as CGI. What I want to do is to call another
perl script where I only set environment variables (envCGI.pl).

If I set these variables in my initial perl script, it works well (I
get my HTML page) but if I call the other perl script, I get:

"require" works OK for this. Or at least I think it
worked. It's been three or four years since I did it.

--
Wes Groleau

Answer not a fool according to his folly,
lest thou also be like unto him.
Answer a fool according to his folly,
lest he be wise according to his own conceit.
-- Solomon

Are you saying there's no good way to answer a fool?
-- Groleau
 
X

xad

Hello,
Suppose you mean the full path. That always works, of course, but you
can also do:
use lib '.';
do 'y.pl';

Actually it does not work yet.

x.pl:
-----------------------------------------------------
#!C:/Perl/bin/perl.exe
use lib '.';
do 'y.pl';

print "Content-type:text/html\n\n";

print @INC;
print "|FOO=".$ENV{'FOO'};
-------------------------------------------------
With that code, I can see that @INC is well updated. Indeed, the
following output is printed out in my browser
..C:/Perl/libC:/Perl/site/lib|FOO=
but the script y.pl is not executed.

If I replace
use lib '.';
by
use lib 'D:/cc_views/v3_4/Dev/bin'; (that corresponds to the location
of the 2 scripts),
@INC is updated with the new location:
D:/cc_views/v3_4/Dev/binC:/Perl/libC:/Perl/site/lib.|FOO=BAR
and the script y.pl is well executed (FOO has been set to BAR)

It seems that SunOne Web Server does not interpret the '.' location ?
Xavier

PS: "require" command has the same behavior
 
G

Gunnar Hjalmarsson

xad said:
Actually it does not work yet.

x.pl:
-----------------------------------------------------
#!C:/Perl/bin/perl.exe
use lib '.';
do 'y.pl';

print "Content-type:text/html\n\n";

print @INC;
print "|FOO=".$ENV{'FOO'};
-------------------------------------------------
With that code, I can see that @INC is well updated. Indeed, the
following output is printed out in my browser
.C:/Perl/libC:/Perl/site/lib|FOO=
but the script y.pl is not executed.

If I replace
use lib '.';
by
use lib 'D:/cc_views/v3_4/Dev/bin'; (that corresponds to the location
of the 2 scripts),
@INC is updated with the new location:
D:/cc_views/v3_4/Dev/binC:/Perl/libC:/Perl/site/lib.|FOO=BAR
and the script y.pl is well executed (FOO has been set to BAR)

It seems that SunOne Web Server does not interpret the '.' location ?

Maybe it doesn't acknowledge relative paths in @INC. Then, to prevent
that the users need to edit the main script, you can try to manipulate
@INC like this instead:

use lib $0 =~ /(.+)[\\\/]/;

(Or you can use the FindBin module, even if it isn't mod_perl or taint
safe.)
 

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

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top