Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/process/Process.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 4c8ae668cc8c |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
56 private $input; | 56 private $input; |
57 private $starttime; | 57 private $starttime; |
58 private $lastOutputTime; | 58 private $lastOutputTime; |
59 private $timeout; | 59 private $timeout; |
60 private $idleTimeout; | 60 private $idleTimeout; |
61 private $options; | 61 private $options = array('suppress_errors' => true); |
62 private $exitcode; | 62 private $exitcode; |
63 private $fallbackStatus = array(); | 63 private $fallbackStatus = array(); |
64 private $processInformation; | 64 private $processInformation; |
65 private $outputDisabled = false; | 65 private $outputDisabled = false; |
66 private $stdout; | 66 private $stdout; |
85 | 85 |
86 /** | 86 /** |
87 * Exit codes translation table. | 87 * Exit codes translation table. |
88 * | 88 * |
89 * User-defined errors must use exit codes in the 64-113 range. | 89 * User-defined errors must use exit codes in the 64-113 range. |
90 * | |
91 * @var array | |
92 */ | 90 */ |
93 public static $exitCodes = array( | 91 public static $exitCodes = array( |
94 0 => 'OK', | 92 0 => 'OK', |
95 1 => 'General error', | 93 1 => 'General error', |
96 2 => 'Misuse of shell builtins', | 94 2 => 'Misuse of shell builtins', |
132 // 158 - not defined | 130 // 158 - not defined |
133 159 => 'Bad syscall', | 131 159 => 'Bad syscall', |
134 ); | 132 ); |
135 | 133 |
136 /** | 134 /** |
137 * Constructor. | 135 * @param string|array $commandline The command line to run |
138 * | |
139 * @param string $commandline The command line to run | |
140 * @param string|null $cwd The working directory or null to use the working dir of the current PHP process | 136 * @param string|null $cwd The working directory or null to use the working dir of the current PHP process |
141 * @param array|null $env The environment variables or null to use the same environment as the current PHP process | 137 * @param array|null $env The environment variables or null to use the same environment as the current PHP process |
142 * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input | 138 * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input |
143 * @param int|float|null $timeout The timeout in seconds or null to disable | 139 * @param int|float|null $timeout The timeout in seconds or null to disable |
144 * @param array $options An array of options for proc_open | 140 * @param array $options An array of options for proc_open |
145 * | 141 * |
146 * @throws RuntimeException When proc_open is not installed | 142 * @throws RuntimeException When proc_open is not installed |
147 */ | 143 */ |
148 public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) | 144 public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = null) |
149 { | 145 { |
150 if (!function_exists('proc_open')) { | 146 if (!function_exists('proc_open')) { |
151 throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); | 147 throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); |
152 } | 148 } |
153 | 149 |
168 $this->setInput($input); | 164 $this->setInput($input); |
169 $this->setTimeout($timeout); | 165 $this->setTimeout($timeout); |
170 $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR; | 166 $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR; |
171 $this->pty = false; | 167 $this->pty = false; |
172 $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled(); | 168 $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled(); |
173 $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options); | 169 if (null !== $options) { |
170 @trigger_error(sprintf('The $options parameter of the %s constructor is deprecated since Symfony 3.3 and will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED); | |
171 $this->options = array_replace($this->options, $options); | |
172 } | |
174 } | 173 } |
175 | 174 |
176 public function __destruct() | 175 public function __destruct() |
177 { | 176 { |
178 $this->stop(0); | 177 $this->stop(0); |
193 * The STDOUT and STDERR are also available after the process is finished | 192 * The STDOUT and STDERR are also available after the process is finished |
194 * via the getOutput() and getErrorOutput() methods. | 193 * via the getOutput() and getErrorOutput() methods. |
195 * | 194 * |
196 * @param callable|null $callback A PHP callback to run whenever there is some | 195 * @param callable|null $callback A PHP callback to run whenever there is some |
197 * output available on STDOUT or STDERR | 196 * output available on STDOUT or STDERR |
197 * @param array $env An array of additional env vars to set when running the process | |
198 * | 198 * |
199 * @return int The exit status code | 199 * @return int The exit status code |
200 * | 200 * |
201 * @throws RuntimeException When process can't be launched | 201 * @throws RuntimeException When process can't be launched |
202 * @throws RuntimeException When process stopped after receiving signal | 202 * @throws RuntimeException When process stopped after receiving signal |
203 * @throws LogicException In case a callback is provided and output has been disabled | 203 * @throws LogicException In case a callback is provided and output has been disabled |
204 */ | 204 * |
205 public function run($callback = null) | 205 * @final since version 3.3 |
206 { | 206 */ |
207 $this->start($callback); | 207 public function run($callback = null/*, array $env = array()*/) |
208 { | |
209 $env = 1 < func_num_args() ? func_get_arg(1) : null; | |
210 $this->start($callback, $env); | |
208 | 211 |
209 return $this->wait(); | 212 return $this->wait(); |
210 } | 213 } |
211 | 214 |
212 /** | 215 /** |
214 * | 217 * |
215 * This is identical to run() except that an exception is thrown if the process | 218 * This is identical to run() except that an exception is thrown if the process |
216 * exits with a non-zero exit code. | 219 * exits with a non-zero exit code. |
217 * | 220 * |
218 * @param callable|null $callback | 221 * @param callable|null $callback |
222 * @param array $env An array of additional env vars to set when running the process | |
219 * | 223 * |
220 * @return self | 224 * @return self |
221 * | 225 * |
222 * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled | 226 * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled |
223 * @throws ProcessFailedException if the process didn't terminate successfully | 227 * @throws ProcessFailedException if the process didn't terminate successfully |
224 */ | 228 * |
225 public function mustRun(callable $callback = null) | 229 * @final since version 3.3 |
230 */ | |
231 public function mustRun(callable $callback = null/*, array $env = array()*/) | |
226 { | 232 { |
227 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { | 233 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { |
228 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); | 234 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); |
229 } | 235 } |
230 | 236 $env = 1 < func_num_args() ? func_get_arg(1) : null; |
231 if (0 !== $this->run($callback)) { | 237 |
238 if (0 !== $this->run($callback, $env)) { | |
232 throw new ProcessFailedException($this); | 239 throw new ProcessFailedException($this); |
233 } | 240 } |
234 | 241 |
235 return $this; | 242 return $this; |
236 } | 243 } |
247 * the output in real-time while writing the standard input to the process. | 254 * the output in real-time while writing the standard input to the process. |
248 * It allows to have feedback from the independent process during execution. | 255 * It allows to have feedback from the independent process during execution. |
249 * | 256 * |
250 * @param callable|null $callback A PHP callback to run whenever there is some | 257 * @param callable|null $callback A PHP callback to run whenever there is some |
251 * output available on STDOUT or STDERR | 258 * output available on STDOUT or STDERR |
259 * @param array $env An array of additional env vars to set when running the process | |
252 * | 260 * |
253 * @throws RuntimeException When process can't be launched | 261 * @throws RuntimeException When process can't be launched |
254 * @throws RuntimeException When process is already running | 262 * @throws RuntimeException When process is already running |
255 * @throws LogicException In case a callback is provided and output has been disabled | 263 * @throws LogicException In case a callback is provided and output has been disabled |
256 */ | 264 */ |
257 public function start(callable $callback = null) | 265 public function start(callable $callback = null/*, array $env = array()*/) |
258 { | 266 { |
259 if ($this->isRunning()) { | 267 if ($this->isRunning()) { |
260 throw new RuntimeException('Process is already running'); | 268 throw new RuntimeException('Process is already running'); |
269 } | |
270 if (2 <= func_num_args()) { | |
271 $env = func_get_arg(1); | |
272 } else { | |
273 if (__CLASS__ !== static::class) { | |
274 $r = new \ReflectionMethod($this, __FUNCTION__); | |
275 if (__CLASS__ !== $r->getDeclaringClass()->getName() && (2 > $r->getNumberOfParameters() || 'env' !== $r->getParameters()[0]->name)) { | |
276 @trigger_error(sprintf('The %s::start() method expects a second "$env" argument since Symfony 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED); | |
277 } | |
278 } | |
279 $env = null; | |
261 } | 280 } |
262 | 281 |
263 $this->resetProcessData(); | 282 $this->resetProcessData(); |
264 $this->starttime = $this->lastOutputTime = microtime(true); | 283 $this->starttime = $this->lastOutputTime = microtime(true); |
265 $this->callback = $this->buildCallback($callback); | 284 $this->callback = $this->buildCallback($callback); |
266 $this->hasCallback = null !== $callback; | 285 $this->hasCallback = null !== $callback; |
267 $descriptors = $this->getDescriptors(); | 286 $descriptors = $this->getDescriptors(); |
268 $inheritEnv = $this->inheritEnv; | 287 $inheritEnv = $this->inheritEnv; |
269 | 288 |
270 $commandline = $this->commandline; | 289 if (is_array($commandline = $this->commandline)) { |
271 | 290 $commandline = implode(' ', array_map(array($this, 'escapeArgument'), $commandline)); |
272 $env = $this->env; | 291 |
273 $envBackup = array(); | 292 if ('\\' !== DIRECTORY_SEPARATOR) { |
293 // exec is mandatory to deal with sending a signal to the process | |
294 $commandline = 'exec '.$commandline; | |
295 } | |
296 } | |
297 | |
298 if (null === $env) { | |
299 $env = $this->env; | |
300 } else { | |
301 if ($this->env) { | |
302 $env += $this->env; | |
303 } | |
304 $inheritEnv = true; | |
305 } | |
306 | |
274 if (null !== $env && $inheritEnv) { | 307 if (null !== $env && $inheritEnv) { |
275 if ('\\' === DIRECTORY_SEPARATOR && !empty($this->options['bypass_shell']) && !$this->enhanceWindowsCompatibility) { | 308 $env += $this->getDefaultEnv(); |
276 throw new LogicException('The "bypass_shell" option must be false to inherit environment variables while enhanced Windows compatibility is off'); | 309 } elseif (null !== $env) { |
277 } | 310 @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED); |
278 | 311 } else { |
279 foreach ($env as $k => $v) { | 312 $env = $this->getDefaultEnv(); |
280 $envBackup[$k] = getenv($k); | |
281 putenv(false === $v || null === $v ? $k : "$k=$v"); | |
282 } | |
283 $env = null; | |
284 } | 313 } |
285 if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { | 314 if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { |
286 $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')'; | 315 $this->options['bypass_shell'] = true; |
287 foreach ($this->processPipes->getFiles() as $offset => $filename) { | 316 $commandline = $this->prepareWindowsCommandLine($commandline, $env); |
288 $commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename); | |
289 } | |
290 $commandline .= '"'; | |
291 | |
292 if (!isset($this->options['bypass_shell'])) { | |
293 $this->options['bypass_shell'] = true; | |
294 } | |
295 } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { | 317 } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { |
296 // last exit code is output on the fourth pipe and caught to work around --enable-sigchild | 318 // last exit code is output on the fourth pipe and caught to work around --enable-sigchild |
297 $descriptors[3] = array('pipe', 'w'); | 319 $descriptors[3] = array('pipe', 'w'); |
298 | 320 |
299 // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input | 321 // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input |
300 $commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;'; | 322 $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;'; |
301 $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code'; | 323 $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code'; |
302 | 324 |
303 // Workaround for the bug, when PTS functionality is enabled. | 325 // Workaround for the bug, when PTS functionality is enabled. |
304 // @see : https://bugs.php.net/69442 | 326 // @see : https://bugs.php.net/69442 |
305 $ptsWorkaround = fopen(__FILE__, 'r'); | 327 $ptsWorkaround = fopen(__FILE__, 'r'); |
306 } | 328 } |
307 | 329 if (defined('HHVM_VERSION')) { |
308 $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $env, $this->options); | 330 $envPairs = $env; |
309 | 331 } else { |
310 foreach ($envBackup as $k => $v) { | 332 $envPairs = array(); |
311 putenv(false === $v ? $k : "$k=$v"); | 333 foreach ($env as $k => $v) { |
312 } | 334 if (false !== $v) { |
335 $envPairs[] = $k.'='.$v; | |
336 } | |
337 } | |
338 } | |
339 | |
340 if (!is_dir($this->cwd)) { | |
341 @trigger_error('The provided cwd does not exist. Command is currently ran against getcwd(). This behavior is deprecated since Symfony 3.4 and will be removed in 4.0.', E_USER_DEPRECATED); | |
342 } | |
343 | |
344 $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); | |
313 | 345 |
314 if (!is_resource($this->process)) { | 346 if (!is_resource($this->process)) { |
315 throw new RuntimeException('Unable to launch a new process.'); | 347 throw new RuntimeException('Unable to launch a new process.'); |
316 } | 348 } |
317 $this->status = self::STATUS_STARTED; | 349 $this->status = self::STATUS_STARTED; |
333 * | 365 * |
334 * Be warned that the process is cloned before being started. | 366 * Be warned that the process is cloned before being started. |
335 * | 367 * |
336 * @param callable|null $callback A PHP callback to run whenever there is some | 368 * @param callable|null $callback A PHP callback to run whenever there is some |
337 * output available on STDOUT or STDERR | 369 * output available on STDOUT or STDERR |
370 * @param array $env An array of additional env vars to set when running the process | |
338 * | 371 * |
339 * @return $this | 372 * @return $this |
340 * | 373 * |
341 * @throws RuntimeException When process can't be launched | 374 * @throws RuntimeException When process can't be launched |
342 * @throws RuntimeException When process is already running | 375 * @throws RuntimeException When process is already running |
343 * | 376 * |
344 * @see start() | 377 * @see start() |
345 */ | 378 * |
346 public function restart(callable $callback = null) | 379 * @final since version 3.3 |
380 */ | |
381 public function restart(callable $callback = null/*, array $env = array()*/) | |
347 { | 382 { |
348 if ($this->isRunning()) { | 383 if ($this->isRunning()) { |
349 throw new RuntimeException('Process is already running'); | 384 throw new RuntimeException('Process is already running'); |
350 } | 385 } |
386 $env = 1 < func_num_args() ? func_get_arg(1) : null; | |
351 | 387 |
352 $process = clone $this; | 388 $process = clone $this; |
353 $process->start($callback); | 389 $process->start($callback, $env); |
354 | 390 |
355 return $process; | 391 return $process; |
356 } | 392 } |
357 | 393 |
358 /** | 394 /** |
796 * | 832 * |
797 * @return bool true if status is ready, false otherwise | 833 * @return bool true if status is ready, false otherwise |
798 */ | 834 */ |
799 public function isStarted() | 835 public function isStarted() |
800 { | 836 { |
801 return $this->status != self::STATUS_READY; | 837 return self::STATUS_READY != $this->status; |
802 } | 838 } |
803 | 839 |
804 /** | 840 /** |
805 * Checks if the process is terminated. | 841 * Checks if the process is terminated. |
806 * | 842 * |
808 */ | 844 */ |
809 public function isTerminated() | 845 public function isTerminated() |
810 { | 846 { |
811 $this->updateStatus(false); | 847 $this->updateStatus(false); |
812 | 848 |
813 return $this->status == self::STATUS_TERMINATED; | 849 return self::STATUS_TERMINATED == $this->status; |
814 } | 850 } |
815 | 851 |
816 /** | 852 /** |
817 * Gets the process status. | 853 * Gets the process status. |
818 * | 854 * |
901 * | 937 * |
902 * @return string The command to execute | 938 * @return string The command to execute |
903 */ | 939 */ |
904 public function getCommandLine() | 940 public function getCommandLine() |
905 { | 941 { |
906 return $this->commandline; | 942 return is_array($this->commandline) ? implode(' ', array_map(array($this, 'escapeArgument'), $this->commandline)) : $this->commandline; |
907 } | 943 } |
908 | 944 |
909 /** | 945 /** |
910 * Sets the command line to be executed. | 946 * Sets the command line to be executed. |
911 * | 947 * |
912 * @param string $commandline The command to execute | 948 * @param string|array $commandline The command to execute |
913 * | 949 * |
914 * @return self The current Process instance | 950 * @return self The current Process instance |
915 */ | 951 */ |
916 public function setCommandLine($commandline) | 952 public function setCommandLine($commandline) |
917 { | 953 { |
1087 } | 1123 } |
1088 | 1124 |
1089 /** | 1125 /** |
1090 * Sets the environment variables. | 1126 * Sets the environment variables. |
1091 * | 1127 * |
1092 * An environment variable value should be a string. | 1128 * Each environment variable value should be a string. |
1093 * If it is an array, the variable is ignored. | 1129 * If it is an array, the variable is ignored. |
1130 * If it is false or null, it will be removed when | |
1131 * env vars are otherwise inherited. | |
1094 * | 1132 * |
1095 * That happens in PHP when 'argv' is registered into | 1133 * That happens in PHP when 'argv' is registered into |
1096 * the $_ENV array for instance. | 1134 * the $_ENV array for instance. |
1097 * | 1135 * |
1098 * @param array $env The new environment variables | 1136 * @param array $env The new environment variables |
1124 /** | 1162 /** |
1125 * Sets the input. | 1163 * Sets the input. |
1126 * | 1164 * |
1127 * This content will be passed to the underlying process standard input. | 1165 * This content will be passed to the underlying process standard input. |
1128 * | 1166 * |
1129 * @param resource|scalar|\Traversable|null $input The content | 1167 * @param string|int|float|bool|resource|\Traversable|null $input The content |
1130 * | 1168 * |
1131 * @return self The current Process instance | 1169 * @return self The current Process instance |
1132 * | 1170 * |
1133 * @throws LogicException In case the process is running | 1171 * @throws LogicException In case the process is running |
1134 */ | 1172 */ |
1145 | 1183 |
1146 /** | 1184 /** |
1147 * Gets the options for proc_open. | 1185 * Gets the options for proc_open. |
1148 * | 1186 * |
1149 * @return array The current options | 1187 * @return array The current options |
1188 * | |
1189 * @deprecated since version 3.3, to be removed in 4.0. | |
1150 */ | 1190 */ |
1151 public function getOptions() | 1191 public function getOptions() |
1152 { | 1192 { |
1193 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); | |
1194 | |
1153 return $this->options; | 1195 return $this->options; |
1154 } | 1196 } |
1155 | 1197 |
1156 /** | 1198 /** |
1157 * Sets the options for proc_open. | 1199 * Sets the options for proc_open. |
1158 * | 1200 * |
1159 * @param array $options The new options | 1201 * @param array $options The new options |
1160 * | 1202 * |
1161 * @return self The current Process instance | 1203 * @return self The current Process instance |
1204 * | |
1205 * @deprecated since version 3.3, to be removed in 4.0. | |
1162 */ | 1206 */ |
1163 public function setOptions(array $options) | 1207 public function setOptions(array $options) |
1164 { | 1208 { |
1209 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED); | |
1210 | |
1165 $this->options = $options; | 1211 $this->options = $options; |
1166 | 1212 |
1167 return $this; | 1213 return $this; |
1168 } | 1214 } |
1169 | 1215 |
1171 * Gets whether or not Windows compatibility is enabled. | 1217 * Gets whether or not Windows compatibility is enabled. |
1172 * | 1218 * |
1173 * This is true by default. | 1219 * This is true by default. |
1174 * | 1220 * |
1175 * @return bool | 1221 * @return bool |
1222 * | |
1223 * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled. | |
1176 */ | 1224 */ |
1177 public function getEnhanceWindowsCompatibility() | 1225 public function getEnhanceWindowsCompatibility() |
1178 { | 1226 { |
1227 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED); | |
1228 | |
1179 return $this->enhanceWindowsCompatibility; | 1229 return $this->enhanceWindowsCompatibility; |
1180 } | 1230 } |
1181 | 1231 |
1182 /** | 1232 /** |
1183 * Sets whether or not Windows compatibility is enabled. | 1233 * Sets whether or not Windows compatibility is enabled. |
1184 * | 1234 * |
1185 * @param bool $enhance | 1235 * @param bool $enhance |
1186 * | 1236 * |
1187 * @return self The current Process instance | 1237 * @return self The current Process instance |
1238 * | |
1239 * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled. | |
1188 */ | 1240 */ |
1189 public function setEnhanceWindowsCompatibility($enhance) | 1241 public function setEnhanceWindowsCompatibility($enhance) |
1190 { | 1242 { |
1243 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED); | |
1244 | |
1191 $this->enhanceWindowsCompatibility = (bool) $enhance; | 1245 $this->enhanceWindowsCompatibility = (bool) $enhance; |
1192 | 1246 |
1193 return $this; | 1247 return $this; |
1194 } | 1248 } |
1195 | 1249 |
1196 /** | 1250 /** |
1197 * Returns whether sigchild compatibility mode is activated or not. | 1251 * Returns whether sigchild compatibility mode is activated or not. |
1198 * | 1252 * |
1199 * @return bool | 1253 * @return bool |
1254 * | |
1255 * @deprecated since version 3.3, to be removed in 4.0. Sigchild compatibility will always be enabled. | |
1200 */ | 1256 */ |
1201 public function getEnhanceSigchildCompatibility() | 1257 public function getEnhanceSigchildCompatibility() |
1202 { | 1258 { |
1259 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED); | |
1260 | |
1203 return $this->enhanceSigchildCompatibility; | 1261 return $this->enhanceSigchildCompatibility; |
1204 } | 1262 } |
1205 | 1263 |
1206 /** | 1264 /** |
1207 * Activates sigchild compatibility mode. | 1265 * Activates sigchild compatibility mode. |
1211 * the --enable-sigchild option | 1269 * the --enable-sigchild option |
1212 * | 1270 * |
1213 * @param bool $enhance | 1271 * @param bool $enhance |
1214 * | 1272 * |
1215 * @return self The current Process instance | 1273 * @return self The current Process instance |
1274 * | |
1275 * @deprecated since version 3.3, to be removed in 4.0. | |
1216 */ | 1276 */ |
1217 public function setEnhanceSigchildCompatibility($enhance) | 1277 public function setEnhanceSigchildCompatibility($enhance) |
1218 { | 1278 { |
1279 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED); | |
1280 | |
1219 $this->enhanceSigchildCompatibility = (bool) $enhance; | 1281 $this->enhanceSigchildCompatibility = (bool) $enhance; |
1220 | 1282 |
1221 return $this; | 1283 return $this; |
1222 } | 1284 } |
1223 | 1285 |
1228 * | 1290 * |
1229 * @return self The current Process instance | 1291 * @return self The current Process instance |
1230 */ | 1292 */ |
1231 public function inheritEnvironmentVariables($inheritEnv = true) | 1293 public function inheritEnvironmentVariables($inheritEnv = true) |
1232 { | 1294 { |
1295 if (!$inheritEnv) { | |
1296 @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED); | |
1297 } | |
1298 | |
1233 $this->inheritEnv = (bool) $inheritEnv; | 1299 $this->inheritEnv = (bool) $inheritEnv; |
1234 | 1300 |
1235 return $this; | 1301 return $this; |
1236 } | 1302 } |
1237 | 1303 |
1238 /** | 1304 /** |
1239 * Returns whether environment variables will be inherited or not. | 1305 * Returns whether environment variables will be inherited or not. |
1240 * | 1306 * |
1241 * @return bool | 1307 * @return bool |
1308 * | |
1309 * @deprecated since version 3.3, to be removed in 4.0. Environment variables will always be inherited. | |
1242 */ | 1310 */ |
1243 public function areEnvironmentVariablesInherited() | 1311 public function areEnvironmentVariablesInherited() |
1244 { | 1312 { |
1313 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Environment variables will always be inherited.', __METHOD__), E_USER_DEPRECATED); | |
1314 | |
1245 return $this->inheritEnv; | 1315 return $this->inheritEnv; |
1246 } | 1316 } |
1247 | 1317 |
1248 /** | 1318 /** |
1249 * Performs a check between the timeout definition and the time the process started. | 1319 * Performs a check between the timeout definition and the time the process started. |
1253 * | 1323 * |
1254 * @throws ProcessTimedOutException In case the timeout was reached | 1324 * @throws ProcessTimedOutException In case the timeout was reached |
1255 */ | 1325 */ |
1256 public function checkTimeout() | 1326 public function checkTimeout() |
1257 { | 1327 { |
1258 if ($this->status !== self::STATUS_STARTED) { | 1328 if (self::STATUS_STARTED !== $this->status) { |
1259 return; | 1329 return; |
1260 } | 1330 } |
1261 | 1331 |
1262 if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { | 1332 if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { |
1263 $this->stop(0); | 1333 $this->stop(0); |
1444 $result = $this->processPipes->readAndWrite($blocking, $close); | 1514 $result = $this->processPipes->readAndWrite($blocking, $close); |
1445 | 1515 |
1446 $callback = $this->callback; | 1516 $callback = $this->callback; |
1447 foreach ($result as $type => $data) { | 1517 foreach ($result as $type => $data) { |
1448 if (3 !== $type) { | 1518 if (3 !== $type) { |
1449 $callback($type === self::STDOUT ? self::OUT : self::ERR, $data); | 1519 $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data); |
1450 } elseif (!isset($this->fallbackStatus['signaled'])) { | 1520 } elseif (!isset($this->fallbackStatus['signaled'])) { |
1451 $this->fallbackStatus['exitcode'] = (int) $data; | 1521 $this->fallbackStatus['exitcode'] = (int) $data; |
1452 } | 1522 } |
1453 } | 1523 } |
1454 } | 1524 } |
1558 $this->fallbackStatus['termsig'] = $this->latestSignal; | 1628 $this->fallbackStatus['termsig'] = $this->latestSignal; |
1559 | 1629 |
1560 return true; | 1630 return true; |
1561 } | 1631 } |
1562 | 1632 |
1633 private function prepareWindowsCommandLine($cmd, array &$env) | |
1634 { | |
1635 $uid = uniqid('', true); | |
1636 $varCount = 0; | |
1637 $varCache = array(); | |
1638 $cmd = preg_replace_callback( | |
1639 '/"(?:( | |
1640 [^"%!^]*+ | |
1641 (?: | |
1642 (?: !LF! | "(?:\^[%!^])?+" ) | |
1643 [^"%!^]*+ | |
1644 )++ | |
1645 ) | [^"]*+ )"/x', | |
1646 function ($m) use (&$env, &$varCache, &$varCount, $uid) { | |
1647 if (!isset($m[1])) { | |
1648 return $m[0]; | |
1649 } | |
1650 if (isset($varCache[$m[0]])) { | |
1651 return $varCache[$m[0]]; | |
1652 } | |
1653 if (false !== strpos($value = $m[1], "\0")) { | |
1654 $value = str_replace("\0", '?', $value); | |
1655 } | |
1656 if (false === strpbrk($value, "\"%!\n")) { | |
1657 return '"'.$value.'"'; | |
1658 } | |
1659 | |
1660 $value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value); | |
1661 $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"'; | |
1662 $var = $uid.++$varCount; | |
1663 | |
1664 $env[$var] = $value; | |
1665 | |
1666 return $varCache[$m[0]] = '!'.$var.'!'; | |
1667 }, | |
1668 $cmd | |
1669 ); | |
1670 | |
1671 $cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')'; | |
1672 foreach ($this->processPipes->getFiles() as $offset => $filename) { | |
1673 $cmd .= ' '.$offset.'>"'.$filename.'"'; | |
1674 } | |
1675 | |
1676 return $cmd; | |
1677 } | |
1678 | |
1563 /** | 1679 /** |
1564 * Ensures the process is running or terminated, throws a LogicException if the process has a not started. | 1680 * Ensures the process is running or terminated, throws a LogicException if the process has a not started. |
1565 * | 1681 * |
1566 * @param string $functionName The function name that was called | 1682 * @param string $functionName The function name that was called |
1567 * | 1683 * |
1568 * @throws LogicException If the process has not run. | 1684 * @throws LogicException if the process has not run |
1569 */ | 1685 */ |
1570 private function requireProcessIsStarted($functionName) | 1686 private function requireProcessIsStarted($functionName) |
1571 { | 1687 { |
1572 if (!$this->isStarted()) { | 1688 if (!$this->isStarted()) { |
1573 throw new LogicException(sprintf('Process must be started before calling %s.', $functionName)); | 1689 throw new LogicException(sprintf('Process must be started before calling %s.', $functionName)); |
1577 /** | 1693 /** |
1578 * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`. | 1694 * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`. |
1579 * | 1695 * |
1580 * @param string $functionName The function name that was called | 1696 * @param string $functionName The function name that was called |
1581 * | 1697 * |
1582 * @throws LogicException If the process is not yet terminated. | 1698 * @throws LogicException if the process is not yet terminated |
1583 */ | 1699 */ |
1584 private function requireProcessIsTerminated($functionName) | 1700 private function requireProcessIsTerminated($functionName) |
1585 { | 1701 { |
1586 if (!$this->isTerminated()) { | 1702 if (!$this->isTerminated()) { |
1587 throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName)); | 1703 throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName)); |
1588 } | 1704 } |
1589 } | 1705 } |
1706 | |
1707 /** | |
1708 * Escapes a string to be used as a shell argument. | |
1709 * | |
1710 * @param string $argument The argument that will be escaped | |
1711 * | |
1712 * @return string The escaped argument | |
1713 */ | |
1714 private function escapeArgument($argument) | |
1715 { | |
1716 if ('\\' !== DIRECTORY_SEPARATOR) { | |
1717 return "'".str_replace("'", "'\\''", $argument)."'"; | |
1718 } | |
1719 if ('' === $argument = (string) $argument) { | |
1720 return '""'; | |
1721 } | |
1722 if (false !== strpos($argument, "\0")) { | |
1723 $argument = str_replace("\0", '?', $argument); | |
1724 } | |
1725 if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) { | |
1726 return $argument; | |
1727 } | |
1728 $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument); | |
1729 | |
1730 return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"'; | |
1731 } | |
1732 | |
1733 private function getDefaultEnv() | |
1734 { | |
1735 $env = array(); | |
1736 | |
1737 foreach ($_SERVER as $k => $v) { | |
1738 if (is_string($v) && false !== $v = getenv($k)) { | |
1739 $env[$k] = $v; | |
1740 } | |
1741 } | |
1742 | |
1743 foreach ($_ENV as $k => $v) { | |
1744 if (is_string($v)) { | |
1745 $env[$k] = $v; | |
1746 } | |
1747 } | |
1748 | |
1749 return $env; | |
1750 } | |
1590 } | 1751 } |