mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-23 01:27:36 +01:00
Rewrite insert_with_markers()
to use flock()
when available, significant cleanup of the function too.
The call to `flock()` is an exclusive advisory lock, which in my testing only PHP respects (apache continues to read it). Not all filesystems support locking (remote NFS mounts for example) so this offers minimal benefit to those platforms, but offers much better protection against file corruption on systems which do support it. The call is blocking, so a second process will wait for the first to complete before writing if supported. See #31767 Built from https://develop.svn.wordpress.org/trunk@34740 git-svn-id: http://core.svn.wordpress.org/trunk@34704 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
a4c41f6ee4
commit
dc9203d753
@ -102,50 +102,68 @@ function extract_from_markers( $filename, $marker ) {
|
|||||||
* @return bool True on write success, false on failure.
|
* @return bool True on write success, false on failure.
|
||||||
*/
|
*/
|
||||||
function insert_with_markers( $filename, $marker, $insertion ) {
|
function insert_with_markers( $filename, $marker, $insertion ) {
|
||||||
if (!file_exists( $filename ) || is_writeable( $filename ) ) {
|
if ( ! is_writeable( $filename ) ) {
|
||||||
if (!file_exists( $filename ) ) {
|
|
||||||
$markerdata = '';
|
|
||||||
} else {
|
|
||||||
$markerdata = explode( "\n", implode( '', file( $filename ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !$f = @fopen( $filename, 'w' ) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
$foundit = false;
|
|
||||||
if ( $markerdata ) {
|
|
||||||
$state = true;
|
|
||||||
foreach ( $markerdata as $n => $markerline ) {
|
|
||||||
if (strpos($markerline, '# BEGIN ' . $marker) !== false)
|
|
||||||
$state = false;
|
|
||||||
if ( $state ) {
|
|
||||||
if ( $n + 1 < count( $markerdata ) )
|
|
||||||
fwrite( $f, "{$markerline}\n" );
|
|
||||||
else
|
|
||||||
fwrite( $f, "{$markerline}" );
|
|
||||||
}
|
|
||||||
if (strpos($markerline, '# END ' . $marker) !== false) {
|
|
||||||
fwrite( $f, "# BEGIN {$marker}\n" );
|
|
||||||
if ( is_array( $insertion ))
|
|
||||||
foreach ( $insertion as $insertline )
|
|
||||||
fwrite( $f, "{$insertline}\n" );
|
|
||||||
fwrite( $f, "# END {$marker}\n" );
|
|
||||||
$state = true;
|
|
||||||
$foundit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$foundit) {
|
|
||||||
fwrite( $f, "\n# BEGIN {$marker}\n" );
|
|
||||||
foreach ( $insertion as $insertline )
|
|
||||||
fwrite( $f, "{$insertline}\n" );
|
|
||||||
fwrite( $f, "# END {$marker}\n" );
|
|
||||||
}
|
|
||||||
fclose( $f );
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! is_array( $insertion ) ) {
|
||||||
|
$insertion = array( $insertion );
|
||||||
|
}
|
||||||
|
|
||||||
|
$start_marker = "# BEGIN {$marker}";
|
||||||
|
$end_marker = "# END {$marker}";
|
||||||
|
|
||||||
|
$fp = fopen( $filename, 'r+' );
|
||||||
|
if ( ! $fp ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to get a lock. If the filesystem supports locking, this will block until the lock is acquired.
|
||||||
|
flock( $fp, LOCK_EX );
|
||||||
|
|
||||||
|
$lines = array();
|
||||||
|
while ( ! feof( $fp ) ) {
|
||||||
|
$lines[] = rtrim( fgets( $fp ), "\r\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split out the existing file into the preceeding lines, and those that appear after the marker
|
||||||
|
$pre_lines = $post_lines = array();
|
||||||
|
$found_marker = $found_end_marker = false;
|
||||||
|
foreach ( $lines as $line ) {
|
||||||
|
if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) {
|
||||||
|
$found_marker = true;
|
||||||
|
continue;
|
||||||
|
} elseif ( ! $found_end_marker && false !== strpos( $line, $end_marker ) ) {
|
||||||
|
$found_end_marker = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ! $found_marker ) {
|
||||||
|
$pre_lines[] = $line;
|
||||||
|
} elseif ( $found_marker && $found_end_marker ) {
|
||||||
|
$post_lines[] = $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the new file data
|
||||||
|
$new_file_data = implode( "\n", array_merge(
|
||||||
|
$pre_lines,
|
||||||
|
array( $start_marker ),
|
||||||
|
$insertion,
|
||||||
|
array( $end_marker ),
|
||||||
|
$post_lines
|
||||||
|
) );
|
||||||
|
|
||||||
|
// Write to the start of the file, and truncate it to that length
|
||||||
|
fseek( $fp, 0 );
|
||||||
|
$bytes = fwrite( $fp, $new_file_data );
|
||||||
|
if ( $bytes ) {
|
||||||
|
ftruncate( $fp, $bytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
flock( $fp, LOCK_UN );
|
||||||
|
fclose( $fp );
|
||||||
|
|
||||||
|
return (bool) $bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '4.4-alpha-34739';
|
$wp_version = '4.4-alpha-34740';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
Loading…
Reference in New Issue
Block a user