Reputation: 11087
I'm using php 5.2.9 on a production server, and it seems that the exec() function behaves "non-standard".
If i run exec("ls", $output, $return_var)
then $output
will contain the list of files in the current folder as expected, but $return_var
will be set to -1 instead of 0, as expected.
I'm using the $return_var
to determine wherever the command finished successfully, and on every other server tested this works as expected:)
Anyone ever hit a situation like this?
edit:
<?php
$command = "asd";
$t1 = time();
$output = Array();
$result = -5;
$r = exec($command, $output, $result);
$t2 = time();
echo "<pre>";
var_export(Array(
'command'=>$command,
'result'=>$result,
'output'=>implode("\n", $output),
'r'=>$r,
't2-t1'=>$t2-$t1,
));
echo "</pre>";
Whatever command i put in $command
, $result
will always be -1, even for nonexistent commands...this is very weird
Upvotes: 12
Views: 6907
Reputation: 11087
Seems like the problem got fixed by the server admin. I have no idea what he did, but it now works. The thing is that the server admin is pretty "strict" and maybe he got a little to restrictive with some system config. From the SSH shell for example i could not see where the php binaries were installed. I'm pretty sure that the SSH shell was chrooted, and also the webserver (either that or they were totally different servers, but i don't know how was that possible without using any kind of mount)...
Upvotes: 0
Reputation: 121689
I tried it out on two different Linux PC's (PHP 5.03 and PHP 5.2.10) - both worked just fine.
PHP 5.2.10 example:
array (
'command' => 'ls',
'result' => 0,
'output' => 'atmail
...
vhosts',
'r' => 'vhosts',
't2-t1' => 0,
)
I'd double-check for any security-related directives in your php.ini file, check file permissions in the directory you're trying to search, and see if you have SELinux and/or AppArmor running.
You might also consider an altenrative, like opendir()/readdir ().
IMHO .. PSM
Upvotes: 0
Reputation: 457
Can we get the output of strace'ing the PHP process? That will likely contain the answer we're looking for.
Also 5.2.14 is the newest of the 5.2 series. Any chance you could try it there? If you're on a shared hosting provider, you can still likely get it to run locally to see if the behavior changes.
Upvotes: 0
Reputation: 28840
Assuming the system returning $result == -1 is Unix-like based (I don't know how would behave Windows with the same code)
The PHP (5.2.9) exec() function does not call the C exec() primitive (which returns -1 if it could not replace/execute the process, which is not the case here). Instead it calls popen() that creates a pipe, performs a fork() and execute a shell with your command. The return_value, -1, is not the direct result from a C primitive, but rather is built by PHP internally, depending on the way your command was processed. In other terms, the "ls" command may have been well executed, while for instance PHP could not close properly the pipe.
Looking at the C code, in ext/standard/exec.c, there could be two reasons why the return code is -1, triggered by an error ; the 2nd one happens after the popen() call
fp = VCWD_POPEN(cmd_p, "r");
if (!fp) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd);
goto err;
}
// ...
err:
pclose_return = -1;
goto done;
However in this case, you wouldn't see the result, and the log would show an error.
Later, the return_value is set via the line
pclose_return = php_stream_close(stream);
Looking at _php_stream_free() (php_stream_close() is a macro replaced with _php_stream_free()), the most likely candidate that could return -1 is
ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC);
Which in turn calls indirectly the C primitive pclose(). According to the manual
The pclose() function returns -1 if wait4(2) returns an error, or some other error is detected.
There seem to be an error detected during the closing of the pipe, that does not prevent the resulting data to be set. To find the reason rigorously, one need to check the operating system setup and logs, the PHP configuration and compilation parameters.
I would recommend
Be aware that there were changes related to the PHP suhosin module in the version 5.3 that enhance by default the security when running PHP files.
Upvotes: 1
Reputation: 239302
Make sure you're not running in safe mode and that exec isn't listed in disable_functions
in php.ini.
Either of these situations would cause exec()
to fail, though I think a notice would be raised.
Upvotes: 0