I have configure wamp for cgi scripts correctly but it is not running following code and giving following server error on executing.
Bad file descriptor: don't know how to spawn child process:
C:/wamp/www/New folder/hello.cgi, referer: http://localhost/New%20folder/
My active perl is installed on C:/wamp/www/perl
here is code:
#!C:\wamp\bin\perl.exe -w
print "Hello World.\n";
Windows does not pay attention to #! lines. You need to make sure that your file extension (.cgi in your case, or .pl more commonly) is associated with your perl executable in the registry.
More info:
There are two ways to run a perl program/script, one is to execute perl directly with the file name of the main program/script as a parameter:
C:\wamp\bin\perl.exe mydir\myprog.pl
Don't ever do this in the cgi directory of your web server.
The other way to execute a program is to just name the file to be run and depend on the OS's built in method to find the right program to run it.
mydir\myprog.pl
On a *nix OS, the 1st two bytes of the file are analyzed to determine what to do with it, if those two bytes are the equivalent of the ASCII string #! then the file is treated as text, & the rest of the 1st line is read with the expectation that it will contain the path to the file's interpreter.
On a Windows OS, the file extension is used to search the registry for the path to the interpreter associated with that file type.
Related
I've used the PAR packager (pp) to create a Windows executable foo.exe from a Perl script foo.pl. The Perl script runs fine (perl foo.pl <arguments>). The executable runs, too (foo.exe <arguments>), but doesn't produce the same results as the Perl script. I want to debug the perl script as run by the executable, to figure out where the difference comes from. How do I do that? In other words, how do I pass a -d to the perl.exe that starts when I execute foo.exe?
ADDENDUM 2020-05-26
Using "Process Explorer" I found the application that ends up getting executed. It was %TEMP%\par-<ID1>\cache-<ID2>\foo.exe, where <ID1> and <ID2> are short and long hexadecimal strings. I had hoped to find ...\perl.exe foo.pl instead, then I could have injected my -d into the command line.
Running foo.exe in that folder yields an error "Can't locate PAR.pm in #INC".
That same folder also contains numerous *.pm, *.dll (including perl528.dll), and a few *.pl files, with the *.pl and *.pm files having names that are short hexadecimal strings. One of the *.pl files (the one mentioned in the process's PAR_0 environment variable) turns out to have the same contents as foo.pl, with the following two lines prefixed:
package main;
#line 1 "script/foo.pl"
If I run perl -Iinc/lib <ID>.pl in that folder, with <ID>.pl the name of that perl script, then it produces the desired results, i.e., doesn't run into the problem that the exe runs into. I expect that the perl528.dll and other dlls in that folder are the bits that make up Perl, but don't know how to call them. The foo.exe in that folder is only 78 kB in size, so it cannot do much more than have those other bits do the work.
Problem: Windows XP is not passing command line arguments to perl scripts.
Symptom: a simple command like:
say "Argument 1 (\$ARGV[0]) is: $ARGV[0], argument 2 (\$ARGV[1]) is: $ARGV[1].";
Resulted in:
Use of uninitialized value $ARGV[0] in concatenation (.) or string at...
Solution:
The root problem is in Windows XP. The default method for starting perl passes only the first variable, which is the script name. Result is that $ARGV[0] is uninitialized.
The fix is to edit the Windows registry at:
\HKEY_CLASSES_ROOT\Perl\shell\Open\command
And make the entry:
"C:\Perl\bin\perl.exe" %*
Result is:
C:\whatever>perl argtest.pl 1 2
Argument 1 ($ARGV[0]) is: 1, argument 2 ($ARGV[1]) is: 2.
Thanks especially to David W who pointed me in the right direction.
Note that #ARGV in Perl is not quite like argv in C.
C Perl
Name of the program argv[0] $0
1st argument argv[1] $ARGV[0]
2nd argument argv[2] $ARGV[1]
n-th argument argv[n] $ARGV[n-1]
So if you provide one command line arguments to a Perl script, it will be found in $ARGV[0]. $ARGV[1] will be uninitialized.
Download Cygwin and test your code in the Cygwin environment. I bet this is a Windows issue. (If you're a Unix head, you'll like Cygwin because it gives you the Unix/Linux like environment on your Windows machine. I don't use Windows without it.)
Windows uses suffixes to determine what program opens what files. Is your Perl script called argtest, argtest.bat or argtest.pl?
On Windows, make sure all of your Perl scripts use the *.pl suffix, so Windows will use whatever Perl parameter to execute them. Windows doesn't use the shebang.
Another possible issue: On Windows XP, I had a problem with Perl scripts with parameters because Windows had this as an execution string:
perl %1
which would execute the Perl program with my script, but ignore the parameters. I had to change this to:
perl %*
Unfortunately, Windows Vista through Windows 8 changed the way this is set. However, I have Windows 7 and don't have this issue. I did make sure to install Perl under C:\Perl and not C:\Program Files\Perl because of the space in the directory name. I also have Strawberry Perl installed.
There is a special Windows environment variable called PATHEXT. This allows you to type in foo instead of foo.pl. If Windows can't see how to execute your file, Windows goes through %PATHEXT and tries appending various suffixes until it finds one that works. You might want to append .PL to that environment variable, so you can type in foo instead of foo.pl all the time.
There are two ways that Windows knows it is supposed to use Perl to execute a program.
The command line begins with the perl executable and the name of the script to be run is provided as a command line argument. This is how it works on Unix and other environments, too.
Your system associates one or more extensions, such as .pl, .pm, and/or .cgi with the Perl application, and Windows will launch Perl when you type a filename with one of those extensions or click on a file with one of those extensions in the Windows explorer.
You have invoked your script simply as
argtest 1 2
and not one of
perl argtest 1 2
argtest.pl 1 2
That makes me think that Perl is not the first application that gets to look at the file referred to by argtest. Perhaps there is a file called argtest.bat or argtest.exe which has the task of getting Perl to run your Perl code. For some reason this intermediate program is not passing the command line arguments that you provide on to the Perl application.
Provide the code for this intermediate file and we can help some more.
UPDATE: David W proposes a 3rd way -- setting the PATHEXT environment variable to inclue .pl files and invoking argtest from the command-line -- see his answer.
Then if Window's file association with the .pl extension was messed up, say, set as just C:\Dwimperl\perl\bin\perl" and not "C:\Dwimperl\perl\binperl %*" then the OP would get the behavior that he describes.
In perl file name is not part of the array of arguments. At least in the test I did you must remove ARGV[2] or pass three arguments, like argtest 1 2 3
I am trying to write my first test case in perl with the help of Test::Simple module.
I have saved the file with .t extension now when i am trying to run this file on windows system then it says windows can not open this file.
I had googled about this and what i found is for running this file you should make a new directory with name /t and keep this file to there.
http://perlmeme.org/tutorials/writing_test_harness.html
I have tried this also but still it is not working.
Can any body gives me some tips.
following is my Test cases :
#!/usr/bin/perl -w
use Test::Simple tests => 2;
ok( 1 + 1 == 2 );
ok( 2 + 2 == 5 );
A .t file in Perl is just a Perl script. The .t is just there to let you know that it's a test script instead of something else. The file extension and directory structure really doesn't matter, it's there just to help you can keep your environment clean.
To run a Perl script on Windows, from a command line, simply type perl <script name>. Make sure that you have a Perl executable installed on your system as Windows does not come with one by default, and make sure it is in your path. If the script you want to run is not in your current directory, make sure to specify the path to the script.
In the URL you gave it says:
Now because 'dot-T' files are just normal Perl scripts, you can run them as such -
perl t/Monger.t
Is it a typo in your post, you wrote /t as a directory to keep your test files in - it should be t/, so just a directory relative to where you are. (That's "just" a convention.)
Using tortoiseSVN client side hook script for pre-commit, we are trying to run some unit test cases using Test::Harness's runtests sub.
In TortoiseSVN's Setting->Hook Scripts->Configure Hook Scripts (for pre-commit), I provide a batch file name against the "Command Line to Execute:" heading.
This batch file contains, the following line
run.pl unittest.t
run.pl contents
#!/usr/bin/perl -w
use strict;
use warnings;
use Test::Harness;
# Run a single test suite
my #files = #ARGV;
runtests(#files);
So, when I try to commit any code, this script get invoked and failed with the following error message:
Could not execute (D:\Perl589\bin\perl.exe -w D:\t\unittest.t): open3: Can't call method "close" on an undefined value at D:/Perl589/lib/IPC/Open3.pm line 368.
Any idea how can we resolve this issue.
Does your Windows computer know what to do with scripts that ends in *.pl? That is, if you double click on a .pl file, does it run Perl? This is set in the registry. You set this up under the File Types tab in the Folder Options. In older version of Windows, this could be done via the Tools->Folder Options... menu. I'm not sure where this can be done in Vista and Windows 7.
Once you have the relationship between Perl and the *.pl files setup, you also have to edit your %PATHEXT% environment variable to include .PL in the list of suffixes that are considered executables.
Otherwise, you simply have to put the name of the Perl interpreter in your Batch file's hook script:
C:\Perl\bin\perl run.pl unittest.t
One more possibility is to use the pl2bat script that came with your Perl installation that turns Perl scripts into Batch files.
Doesn't work with other modules, but to give an example. I installed Text::CSV_XS with a CPAN setting:
'makepl_arg' => q[PREFIX=~/lib],
When I try running a test.pl script:
$ perl test.pl
#!/usr/bin/perl
use lib "/homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi";
use Text::CSV_XS;
print "test";
I get
Can't load '/homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.so' for module Text::CSV_XS: /homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.so: cannot open shared object file: No such file or directory at /www/common/perl/lib/5.8.2/i686-linux/DynaLoader.pm line 229.
at test.pl line 6
Compilation failed in require at test.pl line 6.
BEGIN failed--compilation aborted at test.pl line 6.
I traced the error back to DynaLoader.pm it happens at this line:
# Many dynamic extension loading problems will appear to come from
# this section of code: XYZ failed at line 123 of DynaLoader.pm.
# Often these errors are actually occurring in the initialisation
# C code of the extension XS file. Perl reports the error as being
# in this perl code simply because this was the last perl code
# it executed.
my $libref = dl_load_file($file, $module->dl_load_flags) or
croak("Can't load '$file' for module $module: ".dl_error());
CSV_XS.so exists in the above directory
When you installed the module, did you watch the output? Where did it say it installed the module? Look in lib. Do you see the next directory you expect?
Look in ~/lib to see where eveything ended up to verify that you have the right directory name in your use lib statement:
% find ~/lib -name CSV_XS.so
Once you see where it is installed, use that directory name in your use lib (or PERL5LIB or whatever).
I expect you have a lib/lib in there somehow. The PREFIX is just the, well, prefix, and the installer appends other directory portions to that base path. That includes lib, man, bin, etc.
Personally I would suggest to use local::lib. :)
Try this instead:
'makepl_arg' => q[PREFIX=~/]
PREFIX sets the base for all the directories you will be installing into (bin, lib, and so forth.)
You may also be running into shell expansion problems with your '~'. You can try to expand it yourself:
'makepl_arg' => q[PREFIX=/home/users/foobar]
It would also be helpful if you included the commands you used to get the error you are asking about.
It looks from the error message ("at /www/common ...") that your script is a CGI or mod_perl script. The web server is probably not running as the user 'foo', under whose home directory you've installed the module - that could result in the web server being unable to read that directory.
It may also be running in a "chroot jail", which would mean that the directory in which you've installed the module may not be visible to the script.
In other words, just because you can see the module, does not mean that the web server, and therefore your script, can do so. You should check the relevant file permissions, and if the server is chrooted, whether your module directory is mounted within the virtual file system.
Does the file in question (CSV_XS.so) exist?
Does it exist at the listed location?
If you do:
set |grep PERL
What is the output?
Have you successfully installed other local perl modules?
I strongly suggest installing your own perl in your own home directory, if you have space. Then you can keep everything under your control and keep your own module set, as well as escaping if the admins are keeping you on an older version of perl. (Not to mention preserving yourself if they upgrade some day and leave out all the modules you are relying on.)