comparison vendor/psy/psysh/src/Psy/Output/ProcOutputPager.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of Psy Shell.
5 *
6 * (c) 2012-2017 Justin Hileman
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Psy\Output;
13
14 use Symfony\Component\Console\Output\StreamOutput;
15
16 /**
17 * ProcOutputPager class.
18 *
19 * A ProcOutputPager instance wraps a regular StreamOutput's stream. Rather
20 * than writing directly to the stream, it shells out to a pager process and
21 * gives that process the stream as stdout. This means regular *nix commands
22 * like `less` and `more` can be used to page large amounts of output.
23 */
24 class ProcOutputPager extends StreamOutput implements OutputPager
25 {
26 private $proc;
27 private $pipe;
28 private $stream;
29 private $cmd;
30
31 /**
32 * Constructor.
33 *
34 * @param StreamOutput $output
35 * @param string $cmd Pager process command (default: 'less -R -S -F -X')
36 */
37 public function __construct(StreamOutput $output, $cmd = 'less -R -S -F -X')
38 {
39 $this->stream = $output->getStream();
40 $this->cmd = $cmd;
41 }
42
43 /**
44 * Writes a message to the output.
45 *
46 * @param string $message A message to write to the output
47 * @param bool $newline Whether to add a newline or not
48 *
49 * @throws \RuntimeException When unable to write output (should never happen)
50 */
51 public function doWrite($message, $newline)
52 {
53 $pipe = $this->getPipe();
54 if (false === @fwrite($pipe, $message . ($newline ? PHP_EOL : ''))) {
55 // @codeCoverageIgnoreStart
56 // should never happen
57 throw new \RuntimeException('Unable to write output.');
58 // @codeCoverageIgnoreEnd
59 }
60
61 fflush($pipe);
62 }
63
64 /**
65 * Close the current pager process.
66 */
67 public function close()
68 {
69 if (isset($this->pipe)) {
70 fclose($this->pipe);
71 }
72
73 if (isset($this->proc)) {
74 $exit = proc_close($this->proc);
75 if ($exit !== 0) {
76 throw new \RuntimeException('Error closing output stream');
77 }
78 }
79
80 unset($this->pipe, $this->proc);
81 }
82
83 /**
84 * Get a pipe for paging output.
85 *
86 * If no active pager process exists, fork one and return its input pipe.
87 */
88 private function getPipe()
89 {
90 if (!isset($this->pipe) || !isset($this->proc)) {
91 $desc = array(array('pipe', 'r'), $this->stream, fopen('php://stderr', 'w'));
92 $this->proc = proc_open($this->cmd, $desc, $pipes);
93
94 if (!is_resource($this->proc)) {
95 throw new \RuntimeException('Error opening output stream');
96 }
97
98 $this->pipe = $pipes[0];
99 }
100
101 return $this->pipe;
102 }
103 }