public function wait(bool $throwExceptionOnError=true) : PhoreProcResult
    {

        if ($this->proc === null)
            $this->exec();

        $buf = null;
        if ($buf === null) {
            $buf = [];
            foreach ($this->listener as $chanId => $listener) {
                $buf[$chanId] = "";
            }
        }

        while(true) {
            $allPipesClosed = true;
            $noData = true;
            foreach ($buf as $chanId => &$buffer) {
                if ( ! feof($this->pipes[$chanId])) {
                    $allPipesClosed = false;
                    $dataRead = fread($this->pipes[$chanId], 1024 * 32);
                    $dataReadLen = strlen($dataRead);
                    if ($dataReadLen > 0) {
                        $noData = false;
                        if ($this->listener[$chanId] !== null) {
                            ($this->listener[$chanId])($dataRead, $dataReadLen, $this);
                        } else {
                            $buffer .= $dataRead;
                        }
                    }
                }
            }
            if ($allPipesClosed) {
                break;
            }
            if ($noData) {
                usleep(500);
            }
        }

        foreach ($this->listener as $chanId => $listener) {
            if ($listener === null)
                continue;
            $listener(null, null, $this);
            fclose($this->pipes[$chanId]);
        }
        fclose($this->pipes[0]);


        $exitStatus = proc_close($this->proc);
        $errmsg = "";
        if (isset ($buf[2]))
            $errmsg = $buf[2];
        if ($exitStatus !== 0) {
            throw new PhoreExecException("Command '$this->cmd' returned with exit-code $exitStatus: $errmsg", $exitStatus);
        }
        return new PhoreProcResult($exitStatus, $buf);
    }