2

Synopsis

I execute a shell command from Perl and when run from the command line it works, but when run in the debugger it does not work. Running it as a Win32::Daemon shows the same behaviour.

The Source Code

I execute a command either with backticks

print `$cmd`

or like this:

open FH, "$cmd |" or die "Couldn't execute $cmd: $!\n"; 
    while(defined(my $line = <FH>)) {
        chomp($line);
        print "$line\n";
    }
close FH;

The command reads like this:

$cmd = '"C:\path\to\sscep.exe" getca -f "C:\path\to\config\capi_sscep.cnf"'

Even creating a small test script that just executes this command does only work if run from command line.

The System

  • Windows x64
  • Active Perl v5.16.0, MSWin32-x64-multi-thread
  • Eclipse Juno 20120614-1722

What works

I works to open an administrator prompt (necessary for script execution) and to:

perl script.pl

Output gets printed to screen, $? is 0.

What does not work

Starting Eclipse and running a debug session with the same perl script.pl call. Also not working is adding a service and executing the command (created with Win32::Daemon). The daemon itself is working perfectly fine and starting the perl script as expected. Only the command does not get executed. $? is 13568 or 53 if shifted with $? >> 8, no output gets printed. The exit code does not belong to the program.

Further Details

The tool I am calling is called sscep and is extended by me. It uses the OpenSSL API and loads the capi engine (Windows CryptoAPI). But the command itself does at least print output before any serious action starts. I can happily provide the source code for this, but I doubt it will help.

I was able to narrow this further down: The problem only exists in the combination of the Perl program (CertNanny) and the binary (sscep). Calling dir inside CertNanny works, calling sscep in a test Perl script works, too. So what could possibly be done in Perl to break a single binary from being called...?

Any ideas where this problem might originate from or how I can possibly narrow it down?

javex
  • 7,198
  • 7
  • 41
  • 60
  • Try to get the exit code of your system call by `printf "%d", $? >> 8`. Then check if this code is documented for your program and what it actually means. Make sure your program is in `PATH` if you are not on the command line `print "$ENV{PATH}\n"` – matthias krull Jul 26 '12 at 14:53
  • I did check it, the return code does not belong to the program. My program does not need to be in `PATH` because I call it explicitly (see call above with absolute paths). – javex Jul 27 '12 at 08:10
  • I now also checked for any other data in `$?`, i.e. a signal (`$? & 127`) and a dump (`$? & 128`) but both report `0`. Furthermore, I tried to call the program without _any_ parameters so I know exactly where it would exit, but it doesn't. Also, I checked and there is no exit function that returns `53` nor is the number `53` _anywhere_ in my source code. So while the combination causes the error, the program does not get executed properly... – javex Jul 27 '12 at 15:09

1 Answers1

0

Here is what I believe the problem to be: when you run your program on the command line, the system() command goes through the shell (cmd.exe); when you run your program elsewhere, it does not. Unfortunately, the two methods handle command line arguments differently. Here is an article that seems like it should help you solve the problem.

In my experience, this sort of thing is a mess in Windows. I have had trouble with this issue in Perl, also.

dan1111
  • 6,576
  • 2
  • 18
  • 29
  • The thing is: This does work on other systems that are very similar, just not on mine. Furthermore, this is not a quoting issue since all paths are correctly quoted and nothing needs to be escaped, so your link doesn't help. Sorry. – javex Aug 22 '12 at 14:05