1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2025-02-16 11:02:40 +01:00

Change from fopen/flock to dio_open/dio_fcntl in file_write

8chan uses NFS and flock() does not work over NFS. See http://0pointer.de/blog/projects/locking.html for more information.

Without proper file locking, race conditions are possible in ?/settings and other pages. The one in ?/settings is particularly bad, too many successive writes can cause a PHP file with bad syntax to be written which breaks an entire board and many scripts that call openBoard().

You need to install the dio.so module if you merge this commit.
This commit is contained in:
8chan 2015-02-25 17:12:25 -08:00
parent 1258d793c0
commit 3312e38f07
2 changed files with 7 additions and 8 deletions

View File

@ -15,6 +15,7 @@ Basic requirements:
A computer running a Unix or Unix-like OS(infinity has been specifically tested with and is known to work under Ubuntu 14.x), Apache, MySQL, and PHP
* Make sure Apache has read/write access to the directory infinity resides in.
* `install.php` is not maintained. Don't use it.
* As of February 22, 2015, you need the [DirectIO module (dio.so)](http://php.net/manual/en/ref.dio.php).
Step 1. Create infinity's database from the included install.sql file. Enter mysql and create an empty database named 'infinity'. Then cd into the infinity base directory and run:
```

View File

@ -549,29 +549,27 @@ function file_write($path, $data, $simple = false, $skip_purge = false) {
}
}
if (!$fp = fopen($path, $simple ? 'w' : 'c'))
if (!$fp = dio_open($path, O_WRONLY | O_CREAT, 0644))
error('Unable to open file for writing: ' . $path);
// File locking
if (!$simple && !flock($fp, LOCK_EX)) {
if (dio_fcntl($fp, F_SETLKW, array('type' => F_WRLCK)) === -1) {
error('Unable to lock file: ' . $path);
}
// Truncate file
if (!$simple && !ftruncate($fp, 0))
if (!dio_truncate($fp, 0))
error('Unable to truncate file: ' . $path);
// Write data
if (($bytes = fwrite($fp, $data)) === false)
if (($bytes = dio_write($fp, $data)) === false)
error('Unable to write to file: ' . $path);
// Unlock
if (!$simple)
flock($fp, LOCK_UN);
dio_fcntl($fp, F_SETLK, array('type' => F_UNLCK));
// Close
if (!fclose($fp))
error('Unable to close file: ' . $path);
dio_close($fp);
/**
* Create gzipped file.