|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-08-03 13:09 UTC] david dot gausmann at measx dot com
Description:
------------
The command, which shall be executed via proc_open, must be put in double quotes.
This bug was on functions like system, exec, ...
It seems not to be fixed on proc_open.
Reproduce code:
---------------
--- script1.php ---
<?php
//Works fine
echo "1.\r\n";
system('"C:\php\php.exe" "C:\php\script2.php"');
//FAILS!
echo "2.\r\n";
$arPipes = array();
$rProcess = proc_open('"C:\php\php.exe" "C:\php\script2.php"',
array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $arPipes);
if($rProcess !== false)
{
$nExitCode = -1;
do
{
while(!feof($arPipes[1]))
{
echo fread($arPipes[1], 1024);
flush();
}
$array = proc_get_status($rProcess);
if(!$array)
break;
} while($array['running']);
fclose($arPipes[0]);
fclose($arPipes[1]);
fclose($arPipes[2]);
proc_close($rProcess);
}
//Works fine (double quotes added)
echo "3.\r\n";
$arPipes = array();
$rProcess = proc_open('""C:\php\php.exe" "C:\php\script2.php""',
array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $arPipes);
if($rProcess !== false)
{
$nExitCode = -1;
do
{
while(!feof($arPipes[1]))
{
echo fread($arPipes[1], 1024);
flush();
}
$array = proc_get_status($rProcess);
if(!$array)
break;
} while($array['running']);
fclose($arPipes[0]);
fclose($arPipes[1]);
fclose($arPipes[2]);
proc_close($rProcess);
}
?>
---script2.php---
<?php
echo "Lorem ipsum\r\n";
exit(0);
?>
Expected result:
----------------
1.
Lorem ipsum
2.
Lorem ipsum
3.
The third call of proc_open should fail, the second one should work.
Actual result:
--------------
1.
Lorem ipsum
2.
3.
Lorem ipsum
The second call of proc_open should fails, but the third one works.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 07 19:00:02 2025 UTC |
Something similar fails for me... but even worse! $Command = '"c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile"' $DescriptorSpecification = array ( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ); $Resource = proc_open($Command, $DescriptorSpecification, $Pipes, null, $_ENV); I get the error: 'c:\program' is not recognized as an internal or external command, operable program or batch file. This works on exec() so not sure what's going on.This is the same problem as mine: $Command = '""c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile""'; $DescriptorSpecification = array ( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ); $Resource = proc_open($Command, $DescriptorSpecification, $Pipes, null, $_ENV); Works fine (because it has the nasty double quotes around everything).@xandrani at googlemail dot com '"c:\program files\doxygen\bin\doxygen.exe" "C:\fred\doxyfile"' works fine with proc_open. For the initial comment and other: <?php echo PHP_EOL; error_reporting(E_ALL|E_NOTICE); $cmd = '"c:\\Program Files (x86)\\wcat\\wcutil.exe"'; $des = array ( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ); $resource = proc_open($cmd, $des, $pipes, null, $_ENV); var_dump(stream_get_contents($pipes[0])); var_dump(stream_get_contents($pipes[1])); var_dump(stream_get_contents($pipes[2])); echo PHP_EOL; echo "exec: " . PHP_EOL; echo exec($cmd, $ret); echo PHP_EOL; print_r($ret); echo PHP_EOL; gives me: string(0) "" string(441) "Usage: wcutil [-s] [-d] [-x] [filename(*)] -s(imple) Do not display CSV headers or average. -x(ml) Xml output. -d(rophighlow) Drop highest and lowest path runs. Column details: file - output filename tps - transactions per second kcpt - kilocycles per transaction (aka 'path') bpt - bytes per transaction cpu - percent CPU utilization err - count of any errors " string(0) "" exec: Array ( [0] => Usage: wcutil [-s] [-d] [-x] [filename(*)] [1] => -s(imple) Do not display CSV headers or average. [2] => -x(ml) Xml output. [3] => -d(rophighlow) Drop highest and lowest path runs. [4] => [5] => Column details: [6] => file - output filename [7] => tps - transactions per second [8] => kcpt - kilocycles per transaction (aka 'path') [9] => bpt - bytes per transaction [10] => cpu - percent CPU utilization [11] => err - count of any errors [12] => ) which is correct. Using 5.3.5 and 5.3-svn or trunk, on Windows 7/2003/2008. Please try again and let me know if it still fails, using this exact sample (can be other command), or repost an example to reproduce it. I will also need to know which windows version you use.This bug is still present in PHP 5.4. According to my previous example I've replaced the command line by the php interpreter and the reference to a script: $cmd = '"d:\php-5.4.0\php.exe" "C:\xampp\htdocs\Neuer Ordner\script2.php"'; If I execute your script with the command line above I will get the following output: ------------------------------------- D:\php-5.4.0>php -f C:\xampp\htdocs\testx.php string(0) "" string(0) "" string(93) "Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträger bezeichnung ist falsch. " exec: Lorem ipsum Array ( [0] => Lorem ipsum ) ------------------------------------- If I move the file "script2.php" to an other location (without any spaces in it's path) then it works if I remove the double quotes from the parameter. So the error only occurs if the parameters use double quotes, too. In your example no parameters were used, so the error doesn't occured. I've tested this with PHP 5.4 on Windows XP SP3.I have same problem too, php 5.4.17 on Windows 7 SP1 x64. I tried bypass_shell and it was ok: array("bypass_shell" => TRUE) http://php.net/manual/en/function.proc-open.php It seems that CMD.exe has trick. Check: CMD.exe /? or http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en- us/cmd.mspx?mfr=true --- Starts a new instance of the Windows command interpreter CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF] [[/S] [/C | /K] string] ... If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters: 1. If all of the following conditions are met, then quote characters on the command line are preserved: - no /S switch - exactly two quote characters - no special characters between the two quote characters, where special is one of: &<>()@^| - there are one or more whitespace characters between the two quote characters - the string between the two quote characters is the name of an executable file. 2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character. --- Check the bypass_shell code around CreateProcess. ext\standard\proc_open.c if (bypass_shell) { newprocok = CreateProcess(NULL, command, &security, &security, TRUE, dwCreateFlags, env.envp, cwd, &si, &pi); } else { spprintf(&command_with_cmd, 0, "%s /c %s", COMSPEC_NT, command); newprocok = CreateProcess(NULL, command_with_cmd, &security, &security, TRUE, dwCreateFlags, env.envp, cwd, &si, &pi); efree(command_with_cmd); } --- We simulate the form "%s /c %s". The result depends on the place where we have double quotes. CMD /C "C:\Program Files\Internet Explorer\iexplore.exe" http://php.net -> Ok CMD /C "C:\Program Files\Internet Explorer\iexplore.exe" "http://php.net" 'C:\Program' is not recognized as an internal or external command, operable program or batch file. -> ERR CMD /C ""C:\Program Files\Internet Explorer\iexplore.exe" "http://php.net"" -> Ok --- Workarounds for now: - Enclose entire command with double quotes. - array("bypass_shell" => TRUE)