Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9fdc64b

Browse filesBrowse files
committed
bug #28689 [Process] fix locking of pipe files on Windows (nicolas-grekas)
This PR was merged into the 2.8 branch. Discussion ---------- [Process] fix locking of pipe files on Windows | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #28655 | License | MIT | Doc PR | - Commits ------- d64bd3b [Process] fix locking of pipe files on Windows
2 parents 270f496 + d64bd3b commit 9fdc64b
Copy full SHA for 9fdc64b

File tree

Expand file treeCollapse file tree

1 file changed

+26
-31
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+26
-31
lines changed

‎src/Symfony/Component/Process/Pipes/WindowsPipes.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Process/Pipes/WindowsPipes.php
+26-31Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class WindowsPipes extends AbstractPipes
2828
{
2929
private $files = array();
3030
private $fileHandles = array();
31+
private $lockHandles = array();
3132
private $readBytes = array(
3233
Process::STDOUT => 0,
3334
Process::STDERR => 0,
@@ -47,31 +48,33 @@ public function __construct($disableOutput, $input)
4748
Process::STDOUT => Process::OUT,
4849
Process::STDERR => Process::ERR,
4950
);
50-
$tmpCheck = false;
5151
$tmpDir = sys_get_temp_dir();
5252
$lastError = 'unknown reason';
5353
set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
5454
for ($i = 0;; ++$i) {
5555
foreach ($pipes as $pipe => $name) {
5656
$file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
57-
if (file_exists($file) && !unlink($file)) {
58-
continue 2;
59-
}
60-
$h = fopen($file, 'xb');
61-
if (!$h) {
62-
$error = $lastError;
63-
if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
64-
continue;
65-
}
57+
58+
if (!$h = fopen($file.'.lock', 'w')) {
6659
restore_error_handler();
67-
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
60+
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $lastError));
6861
}
69-
if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
62+
if (!flock($h, LOCK_EX | LOCK_NB)) {
7063
continue 2;
7164
}
72-
if (isset($this->files[$pipe])) {
73-
unlink($this->files[$pipe]);
65+
if (isset($this->lockHandles[$pipe])) {
66+
flock($this->lockHandles[$pipe], LOCK_UN);
67+
fclose($this->lockHandles[$pipe]);
7468
}
69+
$this->lockHandles[$pipe] = $h;
70+
71+
if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) {
72+
flock($this->lockHandles[$pipe], LOCK_UN);
73+
fclose($this->lockHandles[$pipe]);
74+
unset($this->lockHandles[$pipe]);
75+
continue 2;
76+
}
77+
$this->fileHandles[$pipe] = $h;
7578
$this->files[$pipe] = $file;
7679
}
7780
break;
@@ -85,7 +88,6 @@ public function __construct($disableOutput, $input)
8588
public function __destruct()
8689
{
8790
$this->close();
88-
$this->removeFiles();
8991
}
9092

9193
/**
@@ -145,8 +147,11 @@ public function readAndWrite($blocking, $close = false)
145147
$read[$type] = $data;
146148
}
147149
if ($close) {
150+
ftruncate($fileHandle, 0);
148151
fclose($fileHandle);
149-
unset($this->fileHandles[$type]);
152+
flock($this->lockHandles[$type], LOCK_UN);
153+
fclose($this->lockHandles[$type]);
154+
unset($this->fileHandles[$type], $this->lockHandles[$type]);
150155
}
151156
}
152157

@@ -167,10 +172,13 @@ public function areOpen()
167172
public function close()
168173
{
169174
parent::close();
170-
foreach ($this->fileHandles as $handle) {
175+
foreach ($this->fileHandles as $type => $handle) {
176+
ftruncate($handle, 0);
171177
fclose($handle);
178+
flock($this->lockHandles[$type], LOCK_UN);
179+
fclose($this->lockHandles[$type]);
172180
}
173-
$this->fileHandles = array();
181+
$this->fileHandles = $this->lockHandles = array();
174182
}
175183

176184
/**
@@ -185,17 +193,4 @@ public static function create(Process $process, $input)
185193
{
186194
return new static($process->isOutputDisabled(), $input);
187195
}
188-
189-
/**
190-
* Removes temporary files.
191-
*/
192-
private function removeFiles()
193-
{
194-
foreach ($this->files as $filename) {
195-
if (file_exists($filename)) {
196-
@unlink($filename);
197-
}
198-
}
199-
$this->files = array();
200-
}
201196
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.