I have downloaded an open-source terminal emulator from github and modified it a little. The class for running a process looks like this:
<?php
class CProcess {
const PROC_OK = true;
const PROC_FAILED = false;
private static $instance = null;
public static function factory() {
if (!isset(self::$instance)) {
self::$instance = new CProcess();
}
return self::$instance;
}
private $pipes;
private $process;
private $stdinref;
private $stdoutref;
private $stderref;
private function __construct() {
}
public function __destruct() {
return $this->close();
}
public function open($command) {
$spec = array(
array("pty"), // STDIN
array("pty"), // STDOUT
array("pty") // STDERR
);
if (!$this->process = proc_open($command, $spec, $this->pipes)) {
return self::PROC_FAILED;
}
$this->stdinref = &$this->pipes[0];
$this->stdoutref = &$this->pipes[1];
$this->stderref = &$this->pipes[2];
$this->setBlocking(0);
return self::PROC_OK;
}
public function isResource() {
return is_resource($this->process);
}
public function setBlocking($blocking = 1) {
return stream_set_blocking($this->stdoutref, $blocking);
}
public function getStatus() {
return proc_get_status($this->process);
}
public function get() {
$out = stream_get_contents($this->stdoutref);
return $out;
}
public function put($data) {
fwrite($this->stdinref, $data . "\n");
sleep(1);
fflush($this->stdinref);
}
public function close() {
if (is_resource($this->process)) {
fclose($this->stdinref);
fclose($this->stdoutref);
fclose($this->stderref);
return proc_close($this->process);
}
}
public function metaData() {
return stream_get_meta_data($this->stdoutref);
}
}
Now I want to authenticate a login/password pair using the following method:
public static function autenticate($login, $password) {
if (true === DEBUG_MODE) {
error_log("authenticate(): login={$login} password={$password}",0);
}
error_log("test");
self::$username = $login;
$process = CProcess::factory();
$cmd = "su " . escapeshellarg($login);
if (true === DEBUG_MODE) {
error_log("authenticate(): cmd={$cmd}", 0);
}
$rc = $process->open($cmd);
usleep(100000); // 500000
if ($rc === CProcess::PROC_FAILED) {
if (true === DEBUG_MODE) {
error_log("authenticate(): process_open() returns {$rc}", 0);
}
return false;
}
if (true === DEBUG_MODE) {
error_log("authenticate(): invoking process->put() with param={$password}");
}
$process->put($password);
if (true === DEBUG_MODE) {
error_log("authenticate(): process->put() returned its value");
}
usleep(100000);
return (bool) !$process->close();
}
The problem is that the script hangs when getting into $process->put($password);
. My browser just shows 'Waiting for localhost' and it lasts forever. In the put();
method of the class CProcess
I also tried PHP_EOL
instead of \\n
but the result was the same. What's wrong with this code?
The pipes your using should be more like, with read/write type options...
$spec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/error-output.log", "a") );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.