? drupal-818818-37-D7.patch
? drupal-818818-H-D7.patch
Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.217
diff -u -p -r1.217 file.inc
--- includes/file.inc	1 Jul 2010 00:44:04 -0000	1.217
+++ includes/file.inc	2 Jul 2010 22:32:39 -0000
@@ -677,8 +677,38 @@ function file_unmanaged_copy($source, $d
   }
   // Make sure the .htaccess files are present.
   file_ensure_htaccess();
+
+  // Perform the replace operation. copy() is not atomic but rename() is.
+  // Since there could be mutiple processes writing to the same file the best
+  // option is to create a temp file in the same directory and then rename it
+  // to the final filename.
+  $result = FALSE;
+  if ($replace == FILE_EXISTS_REPLACE) {
+    // Get temp filename
+    $temp_name = drupal_tempnam(drupal_dirname($destination), 'file');
+    // Place new contents in temp file
+    if ($temp_name && @copy($source, $temp_name)) {
+      // Try the rename opperation
+      if (!$result = @rename($temp_name, $destination)) {
+        // Unlink and try again for windows since rename on windows does not
+        // replace the file if it already exists.
+        @unlink($destination);
+        $result = @rename($temp_name, $destination);
+      }
+    }
+    else {
+      $result = FALSE;
+    }
+    // Cleanup tempname if rename/copy failed
+    if (!$result && $temp_name) {
+      @unlink($temp_name);
+    }
+  }
   // Perform the copy operation.
-  if (!@copy($source, $destination)) {
+  else {
+    $result = @copy($source, $destination);
+  }
+  if ($result === FALSE) {
     drupal_set_message(t('The specified file %file could not be copied.', array('%file' => $source)), 'error');
     return FALSE;
   }
