Does recursive call able to print in same page as main call

Y

Yohan N. Leder

I'm trying to do a differenciated recursive call (using command line
argument) print to same STDOUT than the one used during main first call.

#!/usr/bin/perl -w
use strict;
print "Content-type: text/html\n\n";
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "<p>main call</p>";}
exit 0;

or

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "Content-type: text/html\n\n<p>main call</p>";}
exit 0;

Both show "main call" in browser, but nothing about "recursive call with
cmdline argument".

How to do ?
 
D

David Squire

Yohan said:
I'm trying to do a differenciated recursive call (using command line
argument) print to same STDOUT than the one used during main first call.

#!/usr/bin/perl -w
use strict;
print "Content-type: text/html\n\n";
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "<p>main call</p>";}
exit 0;

or

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "Content-type: text/html\n\n<p>main call</p>";}
exit 0;

Both show "main call" in browser, but nothing about "recursive call with
cmdline argument".

I'm not at all sure what you are trying to do here, but it looks as if
you mean that you want your CGI script to call itself, while printing
its output to the browser. How are you doing the recursive call? Via a
call to system? How are you capturing and printing the output? Where are
the command line arguments getting set?

These scripts to not provide enough information to work out what you are
trying to do. There is no recursive call to a subroutine (the more
common sense of "recursive call"), nor is there any CGI redirect or
system call.

DS
 
T

Tad McClellan

Yohan N Leder said:
I'm trying to do a differenciated recursive call (using command line
argument) print to same STDOUT than the one used during main first call.


You don't show any recursion, so we can't help you with the recursion.

#!/usr/bin/perl -w
use strict;
print "Content-type: text/html\n\n";
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}

How to do ?


You can't in a CGI program.

CGI programs take input either in an environment variable, or from
stdin, there is no "command line" for programs run in a CGI environment.
 
G

Gunnar Hjalmarsson

Yohan said:
I'm trying to do a differenciated recursive call (using command line
argument) print to same STDOUT than the one used during main first call.

#!/usr/bin/perl -w
use strict;
print "Content-type: text/html\n\n";
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "<p>main call</p>";}
exit 0;

or

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){print "<p>recursive call with cmdline argument</p>";}
else{print "Content-type: text/html\n\n<p>main call</p>";}
exit 0;

Both show "main call" in browser, but nothing about "recursive call with
cmdline argument".

How to do ?

Let me guess: Are you possibly trying to test whether a query string was
appended to the URL when the script was invoked via a browser?

if ( $ENV{QUERY_STRING} ) { print ...
 
Y

Yohan N. Leder

I'm not at all sure what you are trying to do here, but it looks as if
you mean that you want your CGI script to call itself, while printing
its output to the browser. How are you doing the recursive call?

Oops, in my precipitation to ask for help, I written a totaly stupid
piece of test code. Sorry, here is a one closer to the real subject :

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){
print "<p>recursive call with cmdline argument</p>";}
else
{
use Config;
use Win32::process;
my $proc;
print "Content-type: text/html\n\n<p>main call</p>";
Win32::process::Create($proc, $Config::Config{perlpath},
"\"$Config::Config{perlpath}\" \"$0\" arg",
0, &Win32::process::DETACHED_PROCESS, ".")
|| die Win32::FormatMessage(Win32::GetLastError());
}

exit 0;


And, I never see the "<p>recursive call with cmdline argument</p>" in
browser.
 
Y

Yohan N. Leder

You can't in a CGI program.

CGI programs take input either in an environment variable, or from
stdin, there is no "command line" for programs run in a CGI environment.

Sory for the first test code which was written too quickly : don't take
care about it. The real one is this one :

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){
print "<p>recursive call with cmdline argument</p>";}
else
{
use Config;
use Win32::process;
my $proc;
print "Content-type: text/html\n\n<p>main call</p>";
Win32::process::Create($proc, $Config::Config{perlpath},
"\"$Config::Config{perlpath}\" \"$0\" arg",
0, &Win32::process::DETACHED_PROCESS, ".")
|| die Win32::FormatMessage(Win32::GetLastError());
}

exit 0;

But, reading you, I'm wondering if it's really valid to do this second
process, calling the script through a command line ?
 
Y

Yohan N. Leder

Let me guess: Are you possibly trying to test whether a query string was
appended to the URL when the script was invoked via a browser?

if ( $ENV{QUERY_STRING} ) { print ...

In fact, not, since my way is simply to replace fork (which bugs in Win
with ActivePerl 5.8.8) with something which is right under Windows. So,
I'm going through Win32::process and a command line call, like this
(forgot the first inaccurate test code;)) :

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){
print "<p>recursive call with cmdline argument</p>";}
else
{
use Config;
use Win32::process;
my $proc;
print "Content-type: text/html\n\n<p>main call</p>";
Win32::process::Create($proc, $Config::Config{perlpath},
"\"$Config::Config{perlpath}\" \"$0\" arg",
0, &Win32::process::DETACHED_PROCESS, ".")
|| die Win32::FormatMessage(Win32::GetLastError());
}

exit 0;
 
M

Mumia W.

Yohan said:
Oops, in my precipitation to ask for help, I written a totaly stupid
piece of test code. Sorry, here is a one closer to the real subject :

#!/usr/bin/perl -w
use strict;
if ($#ARGV >= 0){
print "<p>recursive call with cmdline argument</p>";}
else
{
use Config;
use Win32::process;
my $proc;
print "Content-type: text/html\n\n<p>main call</p>";
Win32::process::Create($proc, $Config::Config{perlpath},
"\"$Config::Config{perlpath}\" \"$0\" arg",
0, &Win32::process::DETACHED_PROCESS, ".")
|| die Win32::FormatMessage(Win32::GetLastError());
}

exit 0;


And, I never see the "<p>recursive call with cmdline argument</p>" in
browser.

This is a bad idea. The CGI environment is complicated enough. This
forces your script have to have to deal with two, rather different,
environments. You should make the process you call a completely
different script.

But if you're wedded to the idea of making a recursive call, I advise
that you distinguish the recursive invocation using the QUERY_STRING
environment variable (to be consistent with CGI).

Also, before you do recursive invocations using Win32::process::Create,
make sure that you can do simple, non-recursive invocations of other
scripts and programs using Win32::process::Create.

Again, recursion this way is a bad idea. There is a 99% chance that
creating a separate process for each recursive "call" is not necessary
for your application. Just create one big subroutine and call it
recursively like so:

#!/usr/bin/perl

use strict;
use warnings;

sub bigsub;
bigsub;

sub bigsub {
my $job = shift;
if (! $job) {
print "Content-Type: text/html\n\n";
print "<title> Recursive Call </title>\n";
print "<p> main call </p>\n";
print bigsub($_) for qw(Sailor Construction-Worker
Police-Man Indian);
} else {
return "<p> I'm a $job. </p>\n";
}
}
 
Y

Yohan N. Leder

Again, recursion this way is a bad idea. There is a 99% chance that
creating a separate process for each recursive "call" is not necessary
for your application. Just create one big subroutine and call it
recursively like so:

Yes, but originally, I needed to fork. Unfortunately, it bug when script
is in taint mode under ActivePerl 5.8.8 (known bug). Then, I did it
going through threads with async : unfortunatly again, it's subject to
same bug : perl crash ! So, I've finally tried using Win32::process...
And here I am.

Well, so, since you told me to don't use command line call and knowing
it's the way Win32::process:Create works : how to do ?

How to launch asynchronously a call to a sub in the same script knowing
I can't fork() nor threads's async{} ?
 
E

Eric R. Meyers

Yohan said:
Yes, but originally, I needed to fork. Unfortunately, it bug when script
is in taint mode under ActivePerl 5.8.8 (known bug). Then, I did it
going through threads with async : unfortunatly again, it's subject to
same bug : perl crash ! So, I've finally tried using Win32::process...
And here I am.

Well, so, since you told me to don't use command line call and knowing
it's the way Win32::process:Create works : how to do ?

How to launch asynchronously a call to a sub in the same script knowing
I can't fork() nor threads's async{} ?

One simple redirection may be a possible solution, but I don't think that
anyone quite knows yet what you where trying to do in the first place,
before you encountered the bug and started heading in this direction.

Please provide some details, or an example, of your CGI program's original
purpose, the CGI environment, the calls that need to be made and the
arguments that need to be passed along to process the data.
 
Y

Yohan N. Leder

One simple redirection may be a possible solution, but I don't think that
anyone quite knows yet what you where trying to do in the first place,
before you encountered the bug and started heading in this direction.

Please provide some details, or an example, of your CGI program's original
purpose, the CGI environment, the calls that need to be made and the
arguments that need to be passed along to process the data.

The sub I want to fork, async or Win32::process is quite long, but
mainly, it does calculations against input user (collected by main
process) and data already written in server files, then update these
same server files with new results. However, durin,g this time, main
process has to continue and doesn't wait for anything about this
secondary process (because of this, I indicated DETACHED_PROCESS in
Win32::process, $SIG{CHLD} = 'IGNORE' when I gone through fork(), and
detach() about threads).

What I want is that this long calculation/file_writing sub be launched
in an asychonous manner. Also, I don"'t want to put this sub in a second
script because it may be call in another place of the main process, but
with sub parameters doing it's a short computing this time ; in others
wod, depending of the sub parameters, this sub will be long or short.
And for the long call (one only in the entire script), I wish it be a
non blocking one : fork and or threads was ideal for this... But...
 
E

Eric R. Meyers

Yohan said:
The sub I want to fork, async or Win32::process is quite long, but
mainly, it does calculations against input user (collected by main
process) and data already written in server files, then update these
same server files with new results. However, durin,g this time, main
process has to continue and doesn't wait for anything about this
secondary process (because of this, I indicated DETACHED_PROCESS in
Win32::process, $SIG{CHLD} = 'IGNORE' when I gone through fork(), and
detach() about threads).

First things first, this is a CGI program, so let's keep it simple, if we
can. The CGI program is getting the new data submitted by the user, and
that data needs to be processed (short or long), and the server files are
to be updated with the new results. Apparently, the CGI program, having
received the new data, doesn't need to wait around for that long background
processing, so you just want to queue that long background processing and
return some HTML content to the user. Right? No problem.

Do you want to ensure that your long background processing is always
completed, before receiving the next CGI submission of more new data to be
calculated against the server file data, which may or may not have finished
updating from the last session? You may need to develop a means to verify
that the current server file data that you're using in your short
"on-the-fly" calculations is completely up to date. How many user sessions
will be occurring concurrently? Maybe you will actually want to wait for
the new data to be fully processed, before returning that HTML content to
the user, or users.
What I want is that this long calculation/file_writing sub be launched
in an asychonous manner. Also, I don"'t want to put this sub in a second
script because it may be call in another place of the main process, but
with sub parameters doing it's a short computing this time ; in others
wod, depending of the sub parameters, this sub will be long or short.
And for the long call (one only in the entire script), I wish it be a
non blocking one : fork and or threads was ideal for this... But...

Seems to me like you need to create a new Perl module that contains your
reusable (short and long) processing code.

One program using that new Perl module of your's is the CGI program
performing the short "on-the-fly" processing, and another new program of
your's, to be developed to run in the background, can use that same new
Perl module of your's, to watch your server file queue for the long "batch"
processing.

If the server file queue is empty and unlocked, then you can safely assume
that your server files are up to date for the short "on-the-fly" processing
to be done accurately in the CGI program. You'll need to develop a locking
mechanism to handle the concurrency issues of multiple processes and
multiple users.

I hope this helps.

Eric
 
Y

Yohan N. Leder

First things first, this is a CGI program, so let's keep it simple, if we
can. The CGI program is getting the new data submitted by the user, and
that data needs to be processed (short or long), and the server files are
to be updated with the new results. Apparently, the CGI program, having
received the new data, doesn't need to wait around for that long background
processing, so you just want to queue that long background processing and
return some HTML content to the user. Right? No problem.

Do you want to ensure that your long background processing is always
completed, before receiving the next CGI submission of more new data to be
calculated against the server file data, which may or may not have finished
updating from the last session? You may need to develop a means to verify
that the current server file data that you're using in your short
"on-the-fly" calculations is completely up to date. How many user sessions
will be occurring concurrently? Maybe you will actually want to wait for
the new data to be fully processed, before returning that HTML content to
the user, or users.


Seems to me like you need to create a new Perl module that contains your
reusable (short and long) processing code.

One program using that new Perl module of your's is the CGI program
performing the short "on-the-fly" processing, and another new program of
your's, to be developed to run in the background, can use that same new
Perl module of your's, to watch your server file queue for the long "batch"
processing.

If the server file queue is empty and unlocked, then you can safely assume
that your server files are up to date for the short "on-the-fly" processing
to be done accurately in the CGI program. You'll need to develop a locking
mechanism to handle the concurrency issues of multiple processes and
multiple users.

I hope this helps.

Eric

Thanks for your long analysis, Eric... But, I've not any problem about
what to do in the long and short calculation (same sub) and how to
manage concurrent calls from several users. All of this done and works
fine under Unix plateform on which I'm going through a simple fork()...
So, now, I just want to do that this same script (working right under
*nix) work under Win32 too. So, I just drive to a branch of code or
another depending of $^O value.

So, don't enter in sub detail. I just wish to know how to replace the
following code for it to work under ActivePerl 5.8.8 for Win32.

$SIG{CHLD} = 'IGNORE';
my $pid = fork();
die "fork: $!\n" unless defined($pid);
if (!$pid){compute_it($a, $b, $c, $d); exit 0;}

How to write this code part for ActivePerl and work-around its known bug
when using fork or threads when in taint mode ? How to do it without
changing any other thing in the rest of the script's code ? Do you have
another idea than Win32::process ? Or, how to do it using
Win32::process ?
 
T

Tad McClellan

Yohan N Leder said:
Sory for the first test code which was written too quickly :


That is unfortunate.

I've already spent the full allocation of volunteer time on a
problem that doesn't even exist.

Your carelessness has tricked me into spending time on something
worthless rather than in answering someone else's real Perl question.

That can annoy folks, so you should take more care when composing
a post.

There are (likely) hundreds of readers here.

Would you walk into an auditorium full of people and just start
saying stuff, or would you think about what to say a bit before
making your presentation?

Does this newsgroup deserve less courtesy than a room full
of live people?

don't take
care about it.


Too late.
 
E

Eric R. Meyers

Yohan said:
How to write this code part for ActivePerl and work-around its known bug
when using fork or threads when in taint mode ? How to do it without
changing any other thing in the rest of the script's code ? Do you have
another idea than Win32::process ? Or, how to do it using
Win32::process ?

I tried my best to come up with an alternative structure for you, not
knowing much other than what I read. Are you using CGI.pm? If so, have
you tried running this script directly from the command line, rather than
from under the http server? The reason that I'm asking you this is because
I've found a lot of Perl CGI problems caused by strict system-security
protections. I'm not on Windows, so I can't help you with an ActivePerl
problem, but I've found a lot of issues running my Perl CGI programs under
Security Enhanced Linux (SELinux) on my FC-4 linux system. If your script
is CGI.pm based, and you find that it does actually run as planned directly
from the command line, then I would look for a strict system-security
setting causing the ActivePerl fork problem under the http server.

Just another idea. Last thought. Good luck.
 
Y

Yohan N. Leder

I tried my best to come up with an alternative structure for you, not
knowing much other than what I read. Are you using CGI.pm? If so, have
you tried running this script directly from the command line, rather than
from under the http server? The reason that I'm asking you this is because
I've found a lot of Perl CGI problems caused by strict system-security
protections. I'm not on Windows, so I can't help you with an ActivePerl
problem, but I've found a lot of issues running my Perl CGI programs under
Security Enhanced Linux (SELinux) on my FC-4 linux system. If your script
is CGI.pm based, and you find that it does actually run as planned directly
from the command line, then I would look for a strict system-security
setting causing the ActivePerl fork problem under the http server.

Just another idea. Last thought. Good luck.

Thanks again for your effort, Eric : very kindly. Unfortunately, this
script (you'll think it's a nightmare, sure;-)) CGI script has to stay a
'CGI' because a major entry pointy is several web forms, and it can't be
CGI.pm based because of some target servers in the park.

Thanks too for your 'good luck' : I'm going to regret to engage myself
to be Win32 compatible too :-(

When does a Perl for Win will be stable enough on these fork/threading
subjects : that is the question !
 
Y

Yohan N. Leder

That is unfortunate.

I've already spent the full allocation of volunteer time on a
problem that doesn't even exist.

Your carelessness has tricked me into spending time on something
worthless rather than in answering someone else's real Perl question.

That can annoy folks, so you should take more care when composing
a post.

There are (likely) hundreds of readers here.

Would you walk into an auditorium full of people and just start
saying stuff, or would you think about what to say a bit before
making your presentation?

Does this newsgroup deserve less courtesy than a room full
of live people?




Too late.

Didn't you done any mistake at a time or another ? Tolerance sounds
better than morality, isn't it.
 
E

Eric R. Meyers

Yohan said:
Didn't you done any mistake at a time or another ? Tolerance sounds
better than morality, isn't it.

Not everyone is jaded by their being a volunteer, so just forget about it
Yohan, and go on with your good, and occasionally erring life, like
everyone else of us has to do.

I see no problem with what you've done. We all make honest mistakes.

Eric
 
E

Eric R. Meyers

Yohan said:
When does a Perl for Win will be stable enough on these fork/threading
subjects : that is the question !

Windows stable? Your kidding right?

Kill Bill!
 
Y

Yohan N. Leder

Not everyone is jaded by their being a volunteer, so just forget about it
Yohan, and go on with your good, and occasionally erring life, like
everyone else of us has to do.

I see no problem with what you've done. We all make honest mistakes.

Eric

:)
 

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
474,197
Messages
2,571,040
Members
47,634
Latest member
RonnyBoelk

Latest Threads

Top