Commit 497649ca 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().

(cherry picked from commit 6ae18006)

Conflicts:
	src/lib/utils/utils.php
parent bb1e36ad
......@@ -154,7 +154,7 @@ class FileStateMachine implements IStateMachine {
$state = serialize($state);
$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));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("FileStateMachine->SetState() written %d bytes on file: '%s'", $bytes, $filename));
......@@ -244,7 +244,7 @@ class FileStateMachine implements IStateMachine {
}
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));
}
else
......@@ -293,7 +293,7 @@ class FileStateMachine implements IStateMachine {
}
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));
}
else
......@@ -381,7 +381,7 @@ class FileStateMachine implements IStateMachine {
$settings[self::VERSION] = $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);
return $status;
}
......
......@@ -952,6 +952,27 @@ class Utils {
$pow = pow(1024, $base - $fBase);
return sprintf ("%.{$precision}f %s", $pow, $units[$fBase]);
}
/**
* 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