IO
[m6w6/atick] / lib / atick / IO / Process.php
1 <?php
2
3 namespace atick\IO;
4
5 use atick\IO;
6
7 class Process implements IO
8 {
9 /**
10 * Process handle
11 * @var resource
12 */
13 protected $process;
14
15 /**
16 * Process' stdio pipes
17 * @var array
18 */
19 protected $pipes;
20
21 /**
22 * @param string $command
23 * @param string $cwd
24 * @param array $env
25 * @throws \RuntimeException
26 */
27 function __construct($command, $cwd = null, array $env = null) {
28 $this->process = proc_open($command, [["pipe","r"],["pipe","w"],["pipe","w"]], $this->pipes, $cwd, $env);
29
30 if (!is_resource($this->process) || !($status = proc_get_status($this->process))) {
31 throw new \RuntimeException("Could not open proc '$command': " . error_get_last()["message"]);
32 }
33
34 stream_set_blocking($this->pipes[1], false);
35 stream_set_blocking($this->pipes[2], false);
36 }
37
38 /**
39 * Cleanup pipes and proc handle
40 */
41 function __destruct() {
42 foreach ($this->pipes as $fd) {
43 if (is_resource($fd)) {
44 fclose($fd);
45 }
46 }
47 proc_close($this->process);
48 }
49
50 /**
51 * @inheritdoc
52 * @return resource
53 */
54 function getOutput() {
55 return $this->pipes[1];
56 }
57
58 /**
59 * @inheritdoc
60 * @return resource
61 */
62 function getInput() {
63 return $this->pipes[0];
64 }
65
66 /**
67 * @inheritdoc
68 * @param resource $fd
69 * @return resource
70 */
71 function __invoke($fd) {
72 if ($fd) {
73 copy($fd, $this->getInput());
74 }
75 return $this->getOutput();
76 }
77 }