/**
 * 返回导致子进程终止其执行的数。
 * @return int
 */
public function getTermSignal()
{// 返回 子进程 终止其执行的数
    $this->requireProcessIsTerminated(__FUNCTION__);// 确认 进程 函数 已经终止,否则 抛出异常

    if ($this->isSigchildEnabled()) {// 确认是否 子进程
        throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
    }

    $this->updateStatus(false);// 阻塞 非阻塞 连接池 连接等待

    return $this->processInformation['termsig'];// 返回 终止 异常数据
}

/**
 * 检查子进程信号是否已停止
 * @return bool
 */
public function hasBeenStopped()
{
    $this->requireProcessIsTerminated(__FUNCTION__);// 如果停止通过

    $this->updateStatus(false);// 状态 检查 通过

    return $this->processInformation['stopped'];// 进程停止信息
}

/**
 * 返回导致子进程停止其执行的数。
 * @return int
 */
public function getStopSignal()
{
    $this->requireProcessIsTerminated(__FUNCTION__);

    $this->updateStatus(false);

    return $this->processInformation['stopsig'];
}// 停止的 情况

/**
 * 检查是否正在运行
 * @return bool
 */
public function isRunning()
{
    if (self::STATUS_STARTED !== $this->status) {
        return false;
    }// 是否跑起来了

    $this->updateStatus(false);// 检测是否是关闭状态

    return $this->processInformation['running'];// 返回提示语句
}

/**
 * 检查是否已开始
 * @return bool
 */
public function isStarted()
{
    return $this->status != self::STATUS_READY;// 直接根据 启动标志位进行 返回检测
}

/**
 * 检查是否已终止
 * @return bool
 */
public function isTerminated()
{
    $this->updateStatus(false);// 如果没有关闭

    return $this->status == self::STATUS_TERMINATED;// 进行 终止 检测
}

/**
 * 获取当前的状态
 * @return string
 */
public function getStatus()
{
    $this->updateStatus(false);// 获取当前状态

    return $this->status;// 返回当前状态信息
}

/**
 * 终止进程
 */
public function stop()
{// 终止进程
    if ($this->isRunning()) {// 是否运行
        if ('\\' === DS && !$this->isSigchildEnabled()) {
            exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode);// 返回 linux 命令
            if ($exitCode > 0) {// 如果执行状态
                throw new \RuntimeException('Unable to kill the process');// 异常情况
            }
        } else {
            $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid {$this->getPid()}`);// 产看 pid 信息
            foreach ($pids as $pid) {// 循环遍历
                if (is_numeric($pid)) {// 数字进程
                    posix_kill($pid, 9); // 杀死进程
                }
            }
        }
    }

    $this->updateStatus(false);// 更新状态
    if ($this->processInformation['running']) {// 如果还在运行中
        $this->close();// 关闭
    }

    return $this->exitcode;// 返回退出代码
}

/**
 * 添加一行输出
 * @param string $line
 */
public function addOutput($line)
{
    $this->lastOutputTime = microtime(true);
    $this->stdout .= $line;
}// 添加输出信息 并且 更新最后的输出时间

/**
 * 添加一行错误输出
 * @param string $line
 */
public function addErrorOutput($line)
{
    $this->lastOutputTime = microtime(true);
    $this->stderr .= $line;// 行信息
}// 添加一行错误输出

/**
 * 获取被执行的指令
 * @return string
 */
public function getCommandLine()
{
    return $this->commandline;
}// 获取执行的指令

/**
 * 设置指令
 * @param string $commandline
 * @return self
 */
public function setCommandLine($commandline)
{
    $this->commandline = $commandline;

    return $this;
}// 设置指令

/**
 * 获取超时时间
 * @return float|null
 */
public function getTimeout()
{
    return $this->timeout;
}// 获取超时 时间

/**
 * 获取idle超时时间
 * @return float|null
 */
public function getIdleTimeout()
{
    return $this->idleTimeout;
}// 获取 idle 超时时间

/**
 * 设置超时时间
 * @param int|float|null $timeout
 * @return self
 */
public function setTimeout($timeout)
{
    $this->timeout = $this->validateTimeout($timeout);

    return $this;
}// 设置 超时 时间

/**
 * 设置idle超时时间
 * @param int|float|null $timeout
 * @return self
 */
public function setIdleTimeout($timeout)
{
    if (null !== $timeout && $this->outputDisabled) {
        throw new \LogicException('Idle timeout can not be set while the output is disabled.');
    }

    $this->idleTimeout = $this->validateTimeout($timeout);

    return $this;
}// 设置 idle 超时 时间

/**
 * 设置TTY
 * @param bool $tty
 * @return self
 */
public function setTty($tty)
{
    if ('\\' === DS && $tty) {// 如果是 \\ 并且 需要设置 tty 这样的话,证明在 window平台下
        throw new \RuntimeException('TTY mode is not supported on Windows platform.');
    }
    if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) {// tty 必须可以读取
        throw new \RuntimeException('TTY mode requires /dev/tty to be readable.');
    }

    $this->tty = (bool)$tty;// 把当前的 tty 进行 数据类型强制转化

    return $this;// 返回当前类
}

/**
 * 检查是否是tty模式
 * @return bool
 */
public function isTty()// 是否 tty 模式
{
    return $this->tty;
}

/**
 * 设置pty模式
 * @param bool $bool
 * @return self
 */
public function setPty($bool)// 设置 pty 模式
{
    $this->pty = (bool)$bool;

    return $this;
}

/**
 * 是否是pty模式
 * @return bool
 */
public function isPty()// 是否 pty 模式
{
    return $this->pty;
}

/**
 * 获取工作目录
 * @return string|null
 */
public function getWorkingDirectory()// 获取当前工作目录, 让我想起来了 linux pwd 命令
{
    if (null === $this->cwd) {
        return getcwd() ?: null;
    }

    return $this->cwd;
}

/**
 * 设置工作目录
 * @param string $cwd
 * @return self
 */
public function setWorkingDirectory($cwd)// 设置目录
{
    $this->cwd = $cwd;

    return $this;
}

/**
 * 获取环境变量
 * @return array
 */
public function getEnv()// 获取环境变量
{
    return $this->env;
}

/**
 * 设置环境变量
 * @param array $env
 * @return self
 */
public function setEnv(array $env)// 设置环境变量
{
    $env = array_filter($env, function ($value) {
        return !is_array($value);
    });

    $this->env = [];
    foreach ($env as $key => $value) {
        $this->env[(binary)$key] = (binary)$value;
    }

    return $this;
}// 过滤参数 并且 设置 数据