diff --git a/cmpUtil.php b/cmpUtil.php index 5272429..cd64e18 100644 --- a/cmpUtil.php +++ b/cmpUtil.php @@ -250,6 +250,208 @@ } + + function cmpSysExec($cmaRaw, $opt = []) { + $ttr = array( + "\t" => "\\\t", "\$" => "\\\$", + "\\" => "\\\\", "\"" => "\\\"", + " " => "\\ " , "`" => "\\`", + "#" => "\\#" , "&" => "\\&", + "(" => "\\(" , ")" => "\\)", + "*" => "\\*" , "|" => "\\|", + "[" => "\\[" , "]" => "\\]", + "{" => "\\{" , "}" => "\\}", + ";" => "\\;" , "'" => "\\'", + "<" => "\\<" , ">" => "\\>", + "?" => "\\?" , "!" => "\\!" + ); + + $cmaEsc = array(); + + for($i = 0; $i < count($cmaRaw); $i++) { + if(@$cmaRaw[$i][0] == "asis") { + $cmaEsc[] = $cmaRaw[$i][1]; + continue; + } + + $cmaEsc[] = strtr($cmaRaw[$i], $ttr); + } + + $cmdStr = join(" ", $cmaEsc); + if(!@$opt["silent"]) { + $this->d("cmpSysExec: " . $cmdStr); + } + + $fdsAll = array( + 0 => array("pipe", "r"), // stdin + 1 => array("pipe", "w"), // stdout + 2 => array("pipe", "w") // stderr + ); + + $workDir = "/tmp"; + + if(@$opt["workDir"]) + $workDir = $opt["workDir"]; + + $envAll = null; + + $ppsAll = array(); + + $prcRes = proc_open($cmdStr, $fdsAll, $ppsAll, $workDir, $envAll); + + if(!is_resource($prcRes)) { + $this->e("Can't create process"); + return null; + } + + $blk = 1; + + if(isset($opt["blocking"])) { + $blk = $opt["blocking"]; + } + + stream_set_blocking($ppsAll[1], $blk); + stream_set_blocking($ppsAll[2], $blk); + + $retVal = 255; + $out = ""; + $err = ""; + + if($blk) { + if(@$opt["stdin"]) { + fwrite($ppsAll[0], $opt["stdin"]); + fclose($ppsAll[0]); + } + + $out = stream_get_contents($ppsAll[1], 1048576); + $err = stream_get_contents($ppsAll[2], 1048576); + + fclose($ppsAll[1]); + fclose($ppsAll[2]); + } + else { + // $this->d("Nonblock"); + + do { + if(!@$opt["stdInEventAdd"]) + break; + + if(!is_callable(@$opt["stdInEventAdd"]["call"])) { + $this->d("Invalid callable stdInEventAdd"); + break; + } + + if(!@$opt["silent"]) + $this->d("Call stdInEventAdd"); + + ($opt["stdInEventAdd"]["call"]) ( + $ppsAll[0], + $opt["stdInEventAdd"] + ); + } while(0); + + do { + if(!@$opt["stdOutEventAdd"]) + break; + + if(!is_callable(@$opt["stdOutEventAdd"]["call"])) { + $this->d("Invalid callable stdOutEventAdd"); + break; + } + + if(!@$opt["silent"]) + $this->d("Call stdOutEventAdd"); + + ($opt["stdOutEventAdd" ]["call"]) ( + $ppsAll[1], + $opt["stdOutEventAdd"] + ); + } while(0); + + do { + if(!@$opt["stdErrEventAdd"]) + break; + + if(!is_callable(@$opt["stdErrEventAdd"]["call"])) { + $this->d("Invalid callable stdErrEventAdd"); + break; + } + + if(!@$opt["silent"]) + $this->d("Call stdErrEventAdd"); + + ($opt["stdErrEventAdd"]["call"]) ( + $ppsAll[2], + $opt["stdErrEventAdd"] + ); + } while(0); + + do { + if(!@$opt["eventWait"]) + break; + + if(!@$opt["silent"]) + $this->d("Call eventWait"); + + if(!is_callable(@$opt["eventWait"]["call"])) { + $this->d("Invalid callable eventWait"); + break; + } + + ($opt["eventWait"]["call"])(); + } while(0); + } + + + $retVal = proc_close($prcRes); + + + if(!@$opt["return"] || @$opt["return"] == "full") { + return array( + "retval" => $retVal, + "stdout" => $out, + "stderr" => $err + ); + } + + $val = 0; + + if(@$opt["retval"]) + $val = $opt["retval"]; + + if(!@$opt["noerror"]) { + if($retVal !== $val) { + if(!@$opt["silent"]) { + $this->d($err); + $this->d("Return code: " . $retVal); + } + + return null; + } + + if($err) { + $this->d($err); + } + } + + + switch(@$opt["return"]) { + case "retval": + return $retVal; + + case "outstr": + return $out; + + case "outarr": + default: + return explode("\n", $out); + } + + return explode("\n", $out); + } + + + function getGitStatus() { $ret = $this->fgExec("git status");