Port TestExtProcess to php
Esse commit está contido em:
@@ -22,7 +22,6 @@
|
||||
#include "hphp/test/ext/test_ext_curl.h"
|
||||
#include "hphp/test/ext/test_ext_memcached.h"
|
||||
#include "hphp/test/ext/test_ext_mysql.h"
|
||||
#include "hphp/test/ext/test_ext_process.h"
|
||||
#include "hphp/test/ext/test_ext_server.h"
|
||||
|
||||
#endif // incl_EXT_LIST_TEST_EXT_H_
|
||||
|
||||
@@ -1,452 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| HipHop for PHP |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hphp/test/ext/test_ext_process.h"
|
||||
#include "hphp/runtime/ext/ext_process.h"
|
||||
#include "hphp/runtime/ext/ext_file.h"
|
||||
#include "hphp/runtime/base/file/file.h"
|
||||
#include "hphp/runtime/base/util/string_buffer.h"
|
||||
#include "hphp/runtime/base/runtime_option.h"
|
||||
#include "hphp/util/light_process.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TestExtProcess::RunTests(const std::string &which) {
|
||||
bool ret = true;
|
||||
|
||||
RUN_TEST(test_pcntl_alarm);
|
||||
//RUN_TEST(test_pcntl_exec); // this has to run manually
|
||||
RUN_TEST(test_pcntl_fork);
|
||||
RUN_TEST(test_pcntl_getpriority);
|
||||
RUN_TEST(test_pcntl_setpriority);
|
||||
RUN_TEST(test_pcntl_signal);
|
||||
RUN_TEST(test_pcntl_wait);
|
||||
RUN_TEST(test_pcntl_waitpid);
|
||||
RUN_TEST(test_pcntl_wexitstatus);
|
||||
RUN_TEST(test_pcntl_wifexited);
|
||||
RUN_TEST(test_pcntl_wifsignaled);
|
||||
RUN_TEST(test_pcntl_wifstopped);
|
||||
RUN_TEST(test_pcntl_wstopsig);
|
||||
RUN_TEST(test_pcntl_wtermsig);
|
||||
RUN_TEST(test_pcntl_signal_dispatch);
|
||||
RUN_TEST(test_shell_exec);
|
||||
RUN_TEST(test_exec);
|
||||
RUN_TEST(test_passthru);
|
||||
RUN_TEST(test_system);
|
||||
RUN_TEST(test_proc_open);
|
||||
RUN_TEST(test_proc_terminate);
|
||||
RUN_TEST(test_proc_close);
|
||||
RUN_TEST(test_proc_open_env_inh);
|
||||
RUN_TEST(test_proc_get_status);
|
||||
RUN_TEST(test_proc_nice);
|
||||
RUN_TEST(test_escapeshellarg);
|
||||
RUN_TEST(test_escapeshellcmd);
|
||||
|
||||
LightProcess::Initialize(RuntimeOption::LightProcessFilePrefix,
|
||||
RuntimeOption::LightProcessCount,
|
||||
std::vector<int>());
|
||||
RUN_TEST(test_pcntl_alarm);
|
||||
//RUN_TEST(test_pcntl_exec); // this has to run manually
|
||||
RUN_TEST(test_pcntl_fork);
|
||||
RUN_TEST(test_pcntl_getpriority);
|
||||
RUN_TEST(test_pcntl_setpriority);
|
||||
RUN_TEST(test_pcntl_signal);
|
||||
RUN_TEST(test_pcntl_wait);
|
||||
RUN_TEST(test_pcntl_waitpid);
|
||||
RUN_TEST(test_pcntl_wexitstatus);
|
||||
RUN_TEST(test_pcntl_wifexited);
|
||||
RUN_TEST(test_pcntl_wifsignaled);
|
||||
RUN_TEST(test_pcntl_wifstopped);
|
||||
RUN_TEST(test_pcntl_wstopsig);
|
||||
RUN_TEST(test_pcntl_wtermsig);
|
||||
RUN_TEST(test_pcntl_signal_dispatch);
|
||||
RUN_TEST(test_shell_exec);
|
||||
RUN_TEST(test_exec);
|
||||
RUN_TEST(test_passthru);
|
||||
RUN_TEST(test_system);
|
||||
RUN_TEST(test_proc_open);
|
||||
RUN_TEST(test_proc_terminate);
|
||||
RUN_TEST(test_proc_close);
|
||||
RUN_TEST(test_proc_open_env_inh);
|
||||
RUN_TEST(test_proc_get_status);
|
||||
RUN_TEST(test_proc_nice);
|
||||
LightProcess::Close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TestExtProcess::test_pcntl_alarm() {
|
||||
//f_pcntl_alarm(1);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_exec() {
|
||||
f_pcntl_exec("/bin/sh",
|
||||
CREATE_VECTOR1("test/ext/test_pcntl_exec.sh"),
|
||||
CREATE_MAP1("name", "value"));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_fork() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(123);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_wait(ref(status));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_getpriority() {
|
||||
VS(f_pcntl_getpriority(), 0);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_setpriority() {
|
||||
VERIFY(f_pcntl_setpriority(0));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_signal() {
|
||||
f_pcntl_signal(k_SIGALRM, "test", true);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wait() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_wait(ref(status));
|
||||
VS(status, 0x1200);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_waitpid() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VS(status, 0x1200);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wexitstatus() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x80);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VS(f_pcntl_wexitstatus(status), 0x80);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wifexited() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VERIFY(f_pcntl_wifexited(status));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wifsignaled() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VERIFY(!f_pcntl_wifsignaled(status));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wifstopped() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VERIFY(!f_pcntl_wifstopped(status));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wstopsig() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VS(f_pcntl_wstopsig(status), 0x12);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_wtermsig() {
|
||||
int pid = f_pcntl_fork();
|
||||
if (pid == 0) {
|
||||
_exit(0x12);
|
||||
}
|
||||
Variant status;
|
||||
f_pcntl_waitpid(0, ref(status));
|
||||
VS(f_pcntl_wtermsig(status), 0);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_shell_exec() {
|
||||
Variant output = f_shell_exec("echo hello");
|
||||
VS(output, "hello\n");
|
||||
|
||||
string cur_cwd = Process::GetCurrentDirectory();
|
||||
f_chdir("/tmp/");
|
||||
VS(f_shell_exec("/bin/pwd"), "/tmp\n");
|
||||
f_chdir(String(cur_cwd));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_pcntl_signal_dispatch() {
|
||||
f_pcntl_signal_dispatch();
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_exec() {
|
||||
Variant output, ret;
|
||||
String last_line = f_exec("echo hello; echo world;", ref(output), ref(ret));
|
||||
VS(output, CREATE_VECTOR2("hello", "world"));
|
||||
VS(last_line, "world");
|
||||
VS(ret, 0);
|
||||
|
||||
string cur_cwd = Process::GetCurrentDirectory();
|
||||
f_chdir("/tmp/");
|
||||
VS(f_exec("/bin/pwd"), "/tmp");
|
||||
f_chdir(String(cur_cwd));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_passthru() {
|
||||
g_context->obStart();
|
||||
Variant ret;
|
||||
f_passthru("echo hello; echo world;", ref(ret));
|
||||
String output = g_context->obCopyContents();
|
||||
g_context->obEnd();
|
||||
|
||||
VS(output, "hello\nworld\n");
|
||||
VS(ret, 0);
|
||||
|
||||
|
||||
string cur_cwd = Process::GetCurrentDirectory();
|
||||
f_chdir("/tmp/");
|
||||
g_context->obStart();
|
||||
f_passthru("/bin/pwd");
|
||||
output = g_context->obCopyContents();
|
||||
g_context->obEnd();
|
||||
VS(output, "/tmp\n");
|
||||
f_chdir(String(cur_cwd));
|
||||
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_system() {
|
||||
g_context->obStart();
|
||||
Variant ret;
|
||||
String last_line = f_system("echo hello; echo world;", ref(ret));
|
||||
String output = g_context->obCopyContents();
|
||||
g_context->obEnd();
|
||||
|
||||
VS(output, "hello\nworld\n");
|
||||
VS(last_line, "world");
|
||||
VS(ret, 0);
|
||||
|
||||
string cur_cwd = Process::GetCurrentDirectory();
|
||||
f_chdir("/tmp/");
|
||||
VS(f_system("/bin/pwd"), "/tmp");
|
||||
f_chdir(String(cur_cwd));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_open_env_inh() {
|
||||
Array descriptorspec =
|
||||
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
|
||||
1, CREATE_VECTOR2("pipe", "w"),
|
||||
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
|
||||
|
||||
Variant pipes;
|
||||
|
||||
g_context->setenv("inherit_me", "please");
|
||||
Variant process = f_proc_open("echo $inherit_me", descriptorspec, ref(pipes));
|
||||
VERIFY(!same(process, false));
|
||||
|
||||
{
|
||||
File *f = pipes[1].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
StringBuffer sbuf;
|
||||
sbuf.read(f);
|
||||
f->close();
|
||||
VS(sbuf.detach(), "please\n");
|
||||
}
|
||||
|
||||
VS(f_proc_close(process.toObject()), 0);
|
||||
|
||||
// Ensure that PATH makes it through too
|
||||
process = f_proc_open("echo $PATH", descriptorspec, ref(pipes));
|
||||
VERIFY(!same(process, false));
|
||||
|
||||
{
|
||||
File *f = pipes[1].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
StringBuffer sbuf;
|
||||
sbuf.read(f);
|
||||
f->close();
|
||||
|
||||
VERIFY(sbuf.length() != 0);
|
||||
}
|
||||
|
||||
VS(f_proc_close(process.toObject()), 0);
|
||||
|
||||
// And check that the libc putenv() takes effect, even though we don't
|
||||
// want to use that in a threaded environment
|
||||
|
||||
putenv("ZOO=animals");
|
||||
process = f_proc_open("echo $ZOO", descriptorspec, ref(pipes));
|
||||
VERIFY(!same(process, false));
|
||||
|
||||
{
|
||||
File *f = pipes[1].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
StringBuffer sbuf;
|
||||
sbuf.read(f);
|
||||
f->close();
|
||||
VS(sbuf.detach(), "animals\n");
|
||||
}
|
||||
|
||||
VS(f_proc_close(process.toObject()), 0);
|
||||
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_open() {
|
||||
Array descriptorspec =
|
||||
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
|
||||
1, CREATE_VECTOR2("pipe", "w"),
|
||||
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
|
||||
String cwd = "/tmp";
|
||||
Array env = CREATE_MAP1("some_option", "aeiou");
|
||||
|
||||
Variant pipes;
|
||||
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes), cwd, env);
|
||||
VERIFY(!same(process, false));
|
||||
|
||||
{
|
||||
File *f = pipes[0].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
String s("<?php print(getenv('some_option')); ?>", AttachLiteral);
|
||||
f->write(s);
|
||||
f->close();
|
||||
}
|
||||
{
|
||||
File *f = pipes[1].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
StringBuffer sbuf;
|
||||
sbuf.read(f);
|
||||
f->close();
|
||||
VS(sbuf.detach(), "aeiou");
|
||||
}
|
||||
|
||||
VS(f_proc_close(process.toObject()), 0);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_terminate() {
|
||||
Array descriptorspec =
|
||||
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
|
||||
1, CREATE_VECTOR2("pipe", "w"),
|
||||
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
|
||||
Variant pipes;
|
||||
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes));
|
||||
VERIFY(!same(process, false));
|
||||
VERIFY(f_proc_terminate(process.toObject()));
|
||||
// still need to close it, not to leave a zombie behind
|
||||
f_proc_close(process.toObject());
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_close() {
|
||||
return test_proc_open();
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_get_status() {
|
||||
static const StaticString
|
||||
s_command("command"),
|
||||
s_pid("pid"),
|
||||
s_running("running"),
|
||||
s_signaled("signaled"),
|
||||
s_exitcode("exitcode"),
|
||||
s_termsig("termsig"),
|
||||
s_stopsig("stopsig");
|
||||
|
||||
Array descriptorspec =
|
||||
CREATE_MAP3(0, CREATE_VECTOR2("pipe", "r"),
|
||||
1, CREATE_VECTOR2("pipe", "w"),
|
||||
2, CREATE_VECTOR3("file", "/tmp/error-output.txt", "a"));
|
||||
Variant pipes;
|
||||
Variant process = f_proc_open(php_path, descriptorspec, ref(pipes));
|
||||
VERIFY(!same(process, false));
|
||||
Array ret = f_proc_get_status(process.toObject());
|
||||
VS(ret[s_command], php_path);
|
||||
VERIFY(ret[s_pid].toInt32() > 0);
|
||||
VERIFY(ret[s_running]);
|
||||
VERIFY(!ret[s_signaled]);
|
||||
VS(ret[s_exitcode], -1);
|
||||
VS(ret[s_termsig], 0);
|
||||
VS(ret[s_stopsig], 0);
|
||||
|
||||
{
|
||||
File *f = pipes[0].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
f->close();
|
||||
}
|
||||
{
|
||||
File *f = pipes[1].toObject().getTyped<File>();
|
||||
VERIFY(f->valid());
|
||||
f->close();
|
||||
}
|
||||
VS(f_proc_close(process.toObject()), 0);
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_proc_nice() {
|
||||
VERIFY(f_proc_nice(0));
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_escapeshellarg() {
|
||||
VS(f_escapeshellarg("\""), "'\"'");
|
||||
return Count(true);
|
||||
}
|
||||
|
||||
bool TestExtProcess::test_escapeshellcmd() {
|
||||
VS(f_escapeshellcmd("perl \""), "perl \\\"");
|
||||
return Count(true);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| HipHop for PHP |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef incl_HPHP_TEST_EXT_PROCESS_H_
|
||||
#define incl_HPHP_TEST_EXT_PROCESS_H_
|
||||
|
||||
// >>>>>> Generated by idl.php. Do NOT modify. <<<<<<
|
||||
|
||||
#include "hphp/test/ext/test_cpp_ext.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class TestExtProcess : public TestCppExt {
|
||||
public:
|
||||
virtual bool RunTests(const std::string &which);
|
||||
|
||||
bool test_pcntl_alarm();
|
||||
bool test_pcntl_exec();
|
||||
bool test_pcntl_fork();
|
||||
bool test_pcntl_getpriority();
|
||||
bool test_pcntl_setpriority();
|
||||
bool test_pcntl_signal();
|
||||
bool test_pcntl_wait();
|
||||
bool test_pcntl_waitpid();
|
||||
bool test_pcntl_wexitstatus();
|
||||
bool test_pcntl_wifexited();
|
||||
bool test_pcntl_wifsignaled();
|
||||
bool test_pcntl_wifstopped();
|
||||
bool test_pcntl_wstopsig();
|
||||
bool test_pcntl_wtermsig();
|
||||
bool test_pcntl_signal_dispatch();
|
||||
bool test_shell_exec();
|
||||
bool test_exec();
|
||||
bool test_passthru();
|
||||
bool test_system();
|
||||
bool test_proc_open();
|
||||
bool test_proc_terminate();
|
||||
bool test_proc_close();
|
||||
bool test_proc_open_env_inh();
|
||||
bool test_proc_get_status();
|
||||
bool test_proc_nice();
|
||||
bool test_escapeshellarg();
|
||||
bool test_escapeshellcmd();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // incl_HPHP_TEST_EXT_PROCESS_H_
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
function VS($x, $y) {
|
||||
var_dump($x === $y);
|
||||
if ($x !== $y) { echo "Failed: $y\n"; echo "Got: $x\n";
|
||||
var_dump(debug_backtrace()); }
|
||||
}
|
||||
function VERIFY($x) { VS($x != false, true); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(123);
|
||||
}
|
||||
pcntl_wait($status);
|
||||
|
||||
VS(pcntl_getpriority(), 0);
|
||||
VERIFY(pcntl_setpriority(0));
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_wait($status);
|
||||
VS($status, 0x1200);
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VS($status, 0x1200);
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x80);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VS(pcntl_wexitstatus($status), 0x80);
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VERIFY(pcntl_wifexited($status));
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VERIFY(!pcntl_wifsignaled($status));
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VERIFY(!pcntl_wifstopped($status));
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VS(pcntl_wstopsig($status), 0x12);
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == 0) {
|
||||
exit(0x12);
|
||||
}
|
||||
pcntl_waitpid(0, $status);
|
||||
VS(pcntl_wtermsig($status), 0);
|
||||
|
||||
$output = shell_exec("echo hello");
|
||||
VS($output, "hello\n");
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(shell_exec("/bin/pwd"), "/tmp\n");
|
||||
|
||||
pcntl_signal_dispatch();
|
||||
|
||||
$last_line = exec("echo hello; echo world;", $output, $ret);
|
||||
VS($output, array("hello", "world"));
|
||||
VS($last_line, "world");
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(exec("/bin/pwd"), "/tmp");
|
||||
|
||||
echo "heh\n";
|
||||
|
||||
passthru("echo hello; echo world;", $ret);
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
passthru("/bin/pwd");
|
||||
|
||||
$last_line = system("echo hello; echo world;", $ret);
|
||||
VS($last_line, "world");
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(system("/bin/pwd"), "/tmp");
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
|
||||
putenv("inherit_me=please");
|
||||
$process = proc_open('echo $inherit_me', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
|
||||
fpassthru($pipes[1]);
|
||||
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
// Ensure that PATH makes it through too
|
||||
$process = proc_open('echo $PATH', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
|
||||
VERIFY(strlen(fgets($pipes[1])) > 2);
|
||||
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
$cwd = "/tmp";
|
||||
$env = array("some_option" => "aeiou");
|
||||
|
||||
$process = proc_open("php", $descriptorspec, $pipes, $cwd, $env);
|
||||
VERIFY($process != false);
|
||||
|
||||
fprintf($pipes[0], "<?php print(getenv('some_option')); ?>");
|
||||
fclose($pipes[0]);
|
||||
fpassthru($pipes[1]);
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
$process = proc_open('php', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
VERIFY(proc_terminate($process));
|
||||
// still need to close it, not to leave a zombie behind
|
||||
proc_close($process);
|
||||
|
||||
$process = proc_open('php', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
$ret = proc_get_status($process);
|
||||
VS($ret['command'], 'php');
|
||||
VERIFY($ret['pid'] > 0);
|
||||
VERIFY($ret['running']);
|
||||
VERIFY(!$ret['signaled']);
|
||||
VS($ret['exitcode'], -1);
|
||||
VS($ret['termsig'], 0);
|
||||
VS($ret['stopsig'], 0);
|
||||
proc_close($process);
|
||||
|
||||
VERIFY(proc_nice(0));
|
||||
|
||||
VS(escapeshellarg("\""), "'\"'");
|
||||
|
||||
VS(escapeshellcmd("perl \""), "perl \\\"");
|
||||
@@ -0,0 +1,48 @@
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
heh
|
||||
hello
|
||||
world
|
||||
bool(true)
|
||||
/tmp
|
||||
hello
|
||||
world
|
||||
bool(true)
|
||||
bool(true)
|
||||
/tmp
|
||||
bool(true)
|
||||
bool(true)
|
||||
please
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
aeioubool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
function VS($x, $y) {
|
||||
var_dump($x === $y);
|
||||
if ($x !== $y) { echo "Failed: $y\n"; echo "Got: $x\n";
|
||||
var_dump(debug_backtrace()); }
|
||||
}
|
||||
function VERIFY($x) { VS($x != false, true); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
$output = shell_exec("echo hello");
|
||||
VS($output, "hello\n");
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(shell_exec("/bin/pwd"), "/tmp\n");
|
||||
|
||||
pcntl_signal_dispatch();
|
||||
|
||||
$last_line = exec("echo hello; echo world;", $output, $ret);
|
||||
VS($output, array("hello", "world"));
|
||||
VS($last_line, "world");
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(exec("/bin/pwd"), "/tmp");
|
||||
|
||||
echo "heh\n";
|
||||
|
||||
passthru("echo hello; echo world;", $ret);
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
passthru("/bin/pwd");
|
||||
|
||||
$last_line = system("echo hello; echo world;", $ret);
|
||||
VS($last_line, "world");
|
||||
VS($ret, 0);
|
||||
|
||||
chdir("/tmp/");
|
||||
VS(system("/bin/pwd"), "/tmp");
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
|
||||
putenv("inherit_me=please");
|
||||
$process = proc_open('echo $inherit_me', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
|
||||
fpassthru($pipes[1]);
|
||||
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
// Ensure that PATH makes it through too
|
||||
$process = proc_open('echo $PATH', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
|
||||
VERIFY(strlen(fgets($pipes[1])) > 2);
|
||||
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
$cwd = "/tmp";
|
||||
$env = array("some_option" => "aeiou");
|
||||
|
||||
$process = proc_open("php", $descriptorspec, $pipes, $cwd, $env);
|
||||
VERIFY($process != false);
|
||||
|
||||
fprintf($pipes[0], "<?php print(getenv('some_option')); ?>");
|
||||
fclose($pipes[0]);
|
||||
fpassthru($pipes[1]);
|
||||
VS(proc_close($process), 0);
|
||||
|
||||
$descriptorspec =
|
||||
array(array("pipe", "r"),
|
||||
array("pipe", "w"),
|
||||
array("file", "/tmp/error-output.txt", "a"));
|
||||
$process = proc_open('php', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
VERIFY(proc_terminate($process));
|
||||
// still need to close it, not to leave a zombie behind
|
||||
proc_close($process);
|
||||
|
||||
$process = proc_open('php', $descriptorspec, $pipes);
|
||||
VERIFY($process != false);
|
||||
$ret = proc_get_status($process);
|
||||
VS($ret['command'], 'php');
|
||||
VERIFY($ret['pid'] > 0);
|
||||
VERIFY($ret['running']);
|
||||
VERIFY(!$ret['signaled']);
|
||||
VS($ret['exitcode'], -1);
|
||||
VS($ret['termsig'], 0);
|
||||
VS($ret['stopsig'], 0);
|
||||
proc_close($process);
|
||||
|
||||
VERIFY(proc_nice(0));
|
||||
|
||||
VS(escapeshellarg("\""), "'\"'");
|
||||
|
||||
VS(escapeshellcmd("perl \""), "perl \\\"");
|
||||
@@ -0,0 +1,43 @@
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
heh
|
||||
hello
|
||||
world
|
||||
bool(true)
|
||||
/tmp
|
||||
hello
|
||||
world
|
||||
bool(true)
|
||||
bool(true)
|
||||
/tmp
|
||||
bool(true)
|
||||
bool(true)
|
||||
please
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
aeioubool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
@@ -0,0 +1 @@
|
||||
-v Server.LightProcessCount=5
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
pcntl_exec("/bin/sh",
|
||||
array(__DIR__."/test_pcntl_exec.sh"),
|
||||
array("name" => "value"));
|
||||
@@ -0,0 +1,3 @@
|
||||
=========================================
|
||||
TestExtProcess::test_pcntl_exec SUCCEEDED
|
||||
=========================================
|
||||
Referência em uma Nova Issue
Bloquear um usuário