Commit 6ae18006 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #108 in ZP/z-push from feature/ZP-794-safe_put_contents to develop

* commit '50dc9a5c':
  ZP-794 filestatemachine: use Utils::SafePutContents().
  ZP-794 add Utils::SafePutContents().
parents 6f24c497 50dc9a5c
...@@ -154,7 +154,7 @@ class FileStateMachine implements IStateMachine { ...@@ -154,7 +154,7 @@ class FileStateMachine implements IStateMachine {
$state = serialize($state); $state = serialize($state);
$filename = $this->getFullFilePath($devid, $type, $key, $counter); $filename = $this->getFullFilePath($devid, $type, $key, $counter);
if (($bytes = file_put_contents($filename, $state)) === false) if (($bytes = Utils::SafePutContents($filename, $state)) === false)
throw new FatalMisconfigurationException(sprintf("FileStateMachine->SetState(): Could not write state '%s'",$filename)); throw new FatalMisconfigurationException(sprintf("FileStateMachine->SetState(): Could not write state '%s'",$filename));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->SetState() written %d bytes on file: '%s'", $bytes, $filename)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->SetState() written %d bytes on file: '%s'", $bytes, $filename));
...@@ -233,7 +233,7 @@ class FileStateMachine implements IStateMachine { ...@@ -233,7 +233,7 @@ class FileStateMachine implements IStateMachine {
} }
if ($changed) { if ($changed) {
$bytes = file_put_contents($this->userfilename, serialize($users)); $bytes = Utils::SafePutContents($this->userfilename, serialize($users));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->LinkUserDevice(): wrote %d bytes to users file", $bytes)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->LinkUserDevice(): wrote %d bytes to users file", $bytes));
} }
else else
...@@ -282,7 +282,7 @@ class FileStateMachine implements IStateMachine { ...@@ -282,7 +282,7 @@ class FileStateMachine implements IStateMachine {
} }
if ($changed) { if ($changed) {
$bytes = file_put_contents($this->userfilename, serialize($users)); $bytes = Utils::SafePutContents($this->userfilename, serialize($users));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->UnLinkUserDevice(): wrote %d bytes to users file", $bytes)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->UnLinkUserDevice(): wrote %d bytes to users file", $bytes));
} }
else else
...@@ -370,7 +370,7 @@ class FileStateMachine implements IStateMachine { ...@@ -370,7 +370,7 @@ class FileStateMachine implements IStateMachine {
$settings[self::VERSION] = $version; $settings[self::VERSION] = $version;
ZLog::Write(LOGLEVEL_INFO, sprintf("FileStateMachine->SetStateVersion() saving supported state version, value '%d'", $version)); ZLog::Write(LOGLEVEL_INFO, sprintf("FileStateMachine->SetStateVersion() saving supported state version, value '%d'", $version));
$status = file_put_contents($this->settingsfilename, serialize($settings)); $status = Utils::SafePutContents($this->settingsfilename, serialize($settings));
Utils::FixFileOwner($this->settingsfilename); Utils::FixFileOwner($this->settingsfilename);
return $status; return $status;
} }
......
...@@ -929,6 +929,27 @@ class Utils { ...@@ -929,6 +929,27 @@ class Utils {
} }
return substr($email, 0, $pos); return substr($email, 0, $pos);
} }
/**
* Safely write data to disk, using an unique tmp file (concurrent write),
* and using rename for atomicity
*
* If you use SafePutContents, you can safely use file_get_contents
* (you will always read a fully written file)
*
* @param string $filename
* @param string $data
* @return boolean|int
*/
public static function SafePutContents($filename, $data) {
//put the 'tmp' as a prefix (and not suffix) so all glob call will not see temp files
$tmp = dirname($filename).DIRECTORY_SEPARATOR.'tmp-'.getmypid().'-'.basename($filename);
if (($res = file_put_contents($tmp, $data)) !== false)
if (rename($tmp, $filename) !== true)
$res = false;
return $res;
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment