[prev in list] [next in list] [prev in thread] [next in thread] 

List:       subversion-cvs
Subject:    svn commit: r9253 - in branches/1.0.x: . subversion/include subversion/libsvn_subr subversion/libsvn
From:       striker () tigris ! org
Date:       2004-03-31 21:48:34
Message-ID: 200403312148.i2VLmOv30239 () svn ! collab ! net
[Download RAW message or body]

Author: striker
Date: Wed Mar 31 15:48:02 2004
New Revision: 9253

Modified:
   branches/1.0.x/STATUS
   branches/1.0.x/subversion/include/svn_io.h
   branches/1.0.x/subversion/libsvn_subr/io.c
   branches/1.0.x/subversion/libsvn_wc/adm_files.c
   branches/1.0.x/subversion/libsvn_wc/adm_files.h
   branches/1.0.x/subversion/libsvn_wc/adm_ops.c
   branches/1.0.x/subversion/libsvn_wc/log.c
   branches/1.0.x/subversion/libsvn_wc/wc.h
Log:
Merge a change from trunk, remove from STATUS

  * r9085, r9101, r9109, r9130
    Issue 1509: unable to share working copy.
    Notes: Backport attached to the issue with conflicts removed.
    Votes:
      +1: striker, gstein, philip


Modified: branches/1.0.x/STATUS
==============================================================================
--- branches/1.0.x/STATUS	(original)
+++ branches/1.0.x/STATUS	Wed Mar 31 15:48:02 2004
@@ -83,9 +83,3 @@
             installer for 1.0.1 had to be set up manually.
     Votes:
       +1: josander
-
-  * r9085, r9101, r9109, r9130
-    Issue 1509: unable to share working copy.
-    Notes: Backport attached to the issue with conflicts removed.
-    Votes:
-      +1: striker, gstein, philip

Modified: branches/1.0.x/subversion/include/svn_io.h
==============================================================================
--- branches/1.0.x/subversion/include/svn_io.h	(original)
+++ branches/1.0.x/subversion/include/svn_io.h	Wed Mar 31 15:48:02 2004
@@ -197,6 +197,9 @@
 /** Make a file as writable as the operating system allows.
  * @a path is the utf8-encoded path to the file.  If @a ignore_enoent is
  * @c TRUE, don't fail if the target file doesn't exist.
+ * @warning On Unix this function will do the equivlanet of chmod a+w path.
+ * If this is not what you want you should not use this function, but rather
+ * use apr_file_perms_set().
  */
 svn_error_t *svn_io_set_file_read_write (const char *path,
                                          svn_boolean_t ignore_enoent,

Modified: branches/1.0.x/subversion/libsvn_subr/io.c
==============================================================================
--- branches/1.0.x/subversion/libsvn_subr/io.c	(original)
+++ branches/1.0.x/subversion/libsvn_subr/io.c	Wed Mar 31 15:48:02 2004
@@ -1011,19 +1011,8 @@
   const char *path_apr;
 
 #ifdef WIN32
-  /* ### On Unix a read-only file can still be removed, because
-     removal is really an edit of the parent directory, not of the
-     file itself.  Windows apparently has different semantics, and so
-     when the svn_io_set_file_read_write() call below was temporarily
-     removed in revision 5663, Subversion stopped working on Windows.
-
-     Still, this chmod should probably should be controlled by a flag.
-     Certain callers, namely libsvn_wc when dealing with the read-only
-     files in .svn/, frequently have read-only files to remove; but
-     many others don't, and the chmod is a waste of time for them.
-
-     But see http://subversion.tigris.org/issues/show_bug.cgi?id=1294
-     for a more thorough discussion of long term solutions to this. */
+  /* Set the file writable but only on Windows, because Windows
+     will not allow us to remove files that are read-only. */
   SVN_ERR (svn_io_set_file_read_write (path, TRUE, pool));
 #endif /* WIN32 */
 
@@ -2062,6 +2051,7 @@
                            apr_pool_t *pool)
 {
   apr_file_t *format_file = NULL;
+  const char *path_tmp;
   const char *format_contents = apr_psprintf (pool, "%d\n", version);
 
   /* We only promise to handle non-negative integers. */
@@ -2069,17 +2059,29 @@
     return svn_error_createf (SVN_ERR_INCORRECT_PARAMS, NULL,
                               "Version %d is not non-negative", version);
 
-  /* Open (or create+open) PATH... */
-  SVN_ERR (svn_io_file_open (&format_file, path,
-                             APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
-  
+  /* Create a temporary file to write the data to */
+  SVN_ERR (svn_io_open_unique_file (&format_file, &path_tmp, path, ".tmp",
+                                    FALSE, pool));
+  		  
   /* ...dump out our version number string... */
   SVN_ERR (svn_io_file_write_full (format_file, format_contents,
                                    strlen (format_contents), NULL, pool));
   
   /* ...and close the file. */
   SVN_ERR (svn_io_file_close (format_file, pool));
-  
+
+#ifdef WIN32
+  /* make the destination writable, but only on Windows, because
+     Windows does not let us replace read-only files. */
+  SVN_ERR (svn_io_set_file_read_write (path, TRUE, pool));
+#endif /* WIN32 */
+
+  /* rename the temp file as the real destination */
+  SVN_ERR (svn_io_file_rename (path_tmp, path, pool));
+
+  /* And finally remove the perms to make it read only */
+  SVN_ERR (svn_io_set_file_read_only (path, FALSE, pool));
+ 
   return SVN_NO_ERROR;
 }
 

Modified: branches/1.0.x/subversion/libsvn_wc/adm_files.c
==============================================================================
--- branches/1.0.x/subversion/libsvn_wc/adm_files.c	(original)
+++ branches/1.0.x/subversion/libsvn_wc/adm_files.c	Wed Mar 31 15:48:02 2004
@@ -203,35 +203,6 @@
 
 
 
-/* Copy SRC to DST if SRC exists, else create DST empty. */
-static svn_error_t *
-maybe_copy_file (const char *src, const char *dst, apr_pool_t *pool)
-{
-  svn_node_kind_t kind;
-
-  /* First test if SRC exists. */
-  SVN_ERR (svn_io_check_path (src, &kind, pool));
-  if (kind == svn_node_none)
-    {
-      /* SRC doesn't exist, create DST empty. */
-      apr_file_t *f = NULL;
-      SVN_ERR (svn_io_file_open (&f,
-                                 dst,
-                                 (APR_WRITE | APR_CREATE),
-                                 APR_OS_DEFAULT,
-                                 pool));
-      SVN_ERR (svn_io_file_close (f, pool));
-    }
-  else /* SRC exists, so copy it to DST. */
-    {    
-      SVN_ERR (svn_io_copy_file (src, dst, FALSE, pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-
 /*** Syncing files in the adm area. ***/
 
 static svn_error_t *
@@ -256,10 +227,8 @@
   path = v_extend_with_adm_name (path, extension, 0, pool, ap);
   va_end (ap);
   
-  /* Remove read-only flag on destination. */
-  SVN_ERR (svn_io_set_file_read_write (path, TRUE, pool));
- 
   /* Rename. */
+  SVN_ERR (svn_wc__prep_file_for_replacement (path, TRUE, pool));
   SVN_ERR (svn_io_file_rename (tmp_path, path, pool));
   SVN_ERR (svn_io_set_file_read_only (path, FALSE, pool));
 
@@ -430,20 +399,15 @@
     {
       if (flags & APR_APPEND)
         {
-          const char *opath, *tmp_path;
-
-          va_start (ap, pool);
-          opath = v_extend_with_adm_name (path, extension, 0, pool, ap);
-          va_end (ap);
-
-          va_start (ap, pool);
-          tmp_path = v_extend_with_adm_name (path, extension, 1, pool, ap);
-          va_end (ap);
-
-          /* Copy the original thing to the tmp location. */
-          SVN_ERR (maybe_copy_file (opath, tmp_path, pool));
+          /* We don't handle append.  To do so we would need to copy the
+             contents into the apr_file_t once it has been opened. */
+          return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                   "APR_APPEND not supported for adm files");
         }
 
+      /* Need to own the temporary file, so don't reuse an existing one. */
+      flags |= APR_EXCL | APR_CREATE;
+
       /* Extend with tmp name. */
       va_start (ap, pool);
       path = v_extend_with_adm_name (path, extension, 1, pool, ap);
@@ -458,6 +422,14 @@
     }
 
   err = svn_io_file_open (handle, path, flags, protection, pool);
+  if ((flags & APR_WRITE) && err && APR_STATUS_IS_EEXIST(err->apr_err))
+    {
+      /* Exclusive open failed, delete and retry */
+      svn_error_clear (err);
+      SVN_ERR (svn_io_remove_file (path, pool));
+      err = svn_io_file_open (handle, path, flags, protection, pool);
+    }
+
   if (err)
     {
       /* Oddly enough, APR will set *HANDLE even if the open failed.
@@ -516,10 +488,8 @@
       path = v_extend_with_adm_name (path, extension, 0, pool, ap);
       va_end (ap);
       
-      /* Temporarily remove read-only flag on destination. */
-      SVN_ERR (svn_io_set_file_read_write (path, TRUE, pool));
-      
       /* Rename. */
+      SVN_ERR (svn_wc__prep_file_for_replacement (path, TRUE, pool));
       SVN_ERR (svn_io_file_rename (tmp_path, path, pool));
       SVN_ERR (svn_io_set_file_read_only (path, FALSE, pool));
       
@@ -562,8 +532,6 @@
   path = v_extend_with_adm_name (path, NULL, 0, pool, ap);
   va_end (ap);
       
-  /* Remove read-only flag on path. */
-  SVN_ERR(svn_io_set_file_read_write (path, FALSE, pool));
   SVN_ERR(svn_io_remove_file (path, pool));
 
   return SVN_NO_ERROR;
@@ -1163,6 +1131,30 @@
   /* Open a unique file;  use APR_DELONCLOSE. */  
   SVN_ERR (svn_io_open_unique_file (fp, &ignored_filename,
                                     path, ".tmp", delete_on_close, pool));
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__prep_file_for_replacement (const char *path,
+                                   svn_boolean_t ignore_enoent,
+                                   apr_pool_t *pool)
+{
+   /* On Unix a read-only file can still be removed or replaced because
+      this is really an edit of the parent directory, not of the file
+      itself.  Windows apparently has different semantics, and so
+      when the svn_io_set_file_read_write() call was temporarily
+      removed in revision 5663, Subversion stopped working on Windows. 
+      
+      However, the svn_io_set_file_read_write() call sets all write
+      permissions on Unix, which is undesireable.  Since it is unnecessary
+      to make the file writeable, do nothing to prep the file for replacement
+      on Unix. */
+
+#ifdef WIN32
+  return svn_io_set_file_read_write (path, ignore_enoent, pool);
+#endif /* WIN32 */
 
   return SVN_NO_ERROR;
 }

Modified: branches/1.0.x/subversion/libsvn_wc/adm_files.h
==============================================================================
--- branches/1.0.x/subversion/libsvn_wc/adm_files.h	(original)
+++ branches/1.0.x/subversion/libsvn_wc/adm_files.h	Wed Mar 31 15:48:02 2004
@@ -113,8 +113,8 @@
  *
  * When you open a file for writing with svn_wc__open_foo(), the file
  * is actually opened in the corresponding location in the tmp/
- * directory (and if you're appending as well, then the tmp file
- * starts out as a copy of the original file). 
+ * directory.  Opening with APR_APPEND is not supported.  You are
+ * guaranteed to be the owner of the new file.
  *
  * Somehow, this tmp file must eventually get renamed to its real
  * destination in the adm area.  You can do it either by passing the

Modified: branches/1.0.x/subversion/libsvn_wc/adm_ops.c
==============================================================================
--- branches/1.0.x/subversion/libsvn_wc/adm_ops.c	(original)
+++ branches/1.0.x/subversion/libsvn_wc/adm_ops.c	Wed Mar 31 15:48:02 2004
@@ -251,7 +251,7 @@
   SVN_ERR (svn_wc__open_adm_file (&log_fp,
                                   svn_wc_adm_access_path (adm_access),
                                   SVN_WC__ADM_LOG,
-                                  (APR_WRITE | APR_APPEND | APR_CREATE),
+                                  (APR_WRITE | APR_CREATE),
                                   pool));
 
   base_name = svn_path_is_child (svn_wc_adm_access_path (adm_access), path,
@@ -1196,7 +1196,7 @@
       if (kind == svn_node_file)
         {
           if ((working_props_kind == svn_node_file)
-              && (err = svn_io_set_file_read_write (thing, FALSE, pool)))
+              && (err = svn_wc__prep_file_for_replacement (thing, FALSE, pool)))
             return revert_error (err, fullpath, "restoring props", pool);
 
           if ((err = svn_io_copy_file (base_thing, thing, FALSE, pool)))
@@ -1207,9 +1207,6 @@
         }
       else if (working_props_kind == svn_node_file)
         {
-          if ((err = svn_io_set_file_read_write (thing, FALSE, pool)))
-            return revert_error (err, fullpath, "removing props", pool);
-
           if ((err = svn_io_remove_file (thing, pool)))
             return revert_error (err, fullpath, "removing props", pool);
         }
@@ -1685,25 +1682,21 @@
 
         /* Text base. */
         svn_thang = svn_wc__text_base_path (full_path, 0, pool);
-        SVN_ERR (svn_io_set_file_read_write (svn_thang, TRUE, pool));
         SVN_ERR (remove_file_if_present (svn_thang, pool));
 
         /* Working prop file. */
         SVN_ERR (svn_wc__prop_path (&svn_thang, full_path, adm_access, FALSE,
                                     pool));
-        SVN_ERR (svn_io_set_file_read_write (svn_thang, TRUE, pool));
         SVN_ERR (remove_file_if_present (svn_thang, pool));
 
         /* Prop base file. */
         SVN_ERR (svn_wc__prop_base_path (&svn_thang, full_path, adm_access,
                                          FALSE, pool));
-        SVN_ERR (svn_io_set_file_read_write (svn_thang, TRUE, pool));
         SVN_ERR (remove_file_if_present (svn_thang, pool));
 
         /* wc-prop file. */
         SVN_ERR (svn_wc__wcprop_path (&svn_thang, full_path, adm_access, FALSE,
                                       pool));
-        SVN_ERR (svn_io_set_file_read_write (svn_thang, TRUE, pool));
         SVN_ERR (remove_file_if_present (svn_thang, pool));
       }
 

Modified: branches/1.0.x/subversion/libsvn_wc/log.c
==============================================================================
--- branches/1.0.x/subversion/libsvn_wc/log.c	(original)
+++ branches/1.0.x/subversion/libsvn_wc/log.c	Wed Mar 31 15:48:02 2004
@@ -157,8 +157,7 @@
       }
 
     case svn_wc__xfer_mv:
-      /* Remove read-only flag on destination. */
-      SVN_ERR (svn_io_set_file_read_write (full_dest_path, TRUE, pool));
+      SVN_ERR (svn_wc__prep_file_for_replacement (full_dest_path, TRUE, pool));
 
       err = svn_io_file_rename (full_from_path,
                                 full_dest_path, pool);
@@ -952,9 +951,8 @@
               }                
           }
 
-        /* Make the tmp prop file the new pristine one.  Note that we
-           have to temporarily set the file permissions for writability. */
-        SVN_ERR (svn_io_set_file_read_write (basef, TRUE, pool));
+        /* Make the tmp prop file the new pristine one. */
+        SVN_ERR (svn_wc__prep_file_for_replacement (basef, TRUE, pool));
         SVN_ERR (svn_io_file_rename (tmpf, basef, pool));
         SVN_ERR (svn_io_set_file_read_only (basef, FALSE, pool));
       }

Modified: branches/1.0.x/subversion/libsvn_wc/wc.h
==============================================================================
--- branches/1.0.x/subversion/libsvn_wc/wc.h	(original)
+++ branches/1.0.x/subversion/libsvn_wc/wc.h	Wed Mar 31 15:48:02 2004
@@ -206,6 +206,12 @@
  */
 svn_error_t *svn_wc__adm_write_check (svn_wc_adm_access_t *adm_access);
 
+/* Carries out platform specific operations needed before a file is
+ * replaced via a rename or copy.  Currently it only runs 
+ * svn_io_set_file_read_write() on Windows. */
+svn_error_t *svn_wc__prep_file_for_replacement (const char *path,
+                                                svn_boolean_t ignore_enoent,
+                                                apr_pool_t *pool);
 
 #ifdef __cplusplus
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
For additional commands, e-mail: svn-help@subversion.tigris.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic