You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/09/05 08:27:00 UTC

svn commit: r1701348 [3/4] - in /subversion/branches/move-tracking-2: ./ build/ build/ac-macros/ build/generator/ subversion/ subversion/bindings/swig/include/ subversion/include/ subversion/include/private/ subversion/libsvn_auth_kwallet/ subversion/l...

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/atomic.c Sat Sep  5 06:26:58 2015
@@ -24,6 +24,7 @@
 #include <apr_time.h>
 #include "private/svn_atomic.h"
 
+
 /* Magic values for atomic initialization */
 #define SVN_ATOMIC_UNINITIALIZED 0
 #define SVN_ATOMIC_START_INIT    1
@@ -31,19 +32,20 @@
 #define SVN_ATOMIC_INITIALIZED   3
 
 
+/* Baton used by init_funct_t and init_once(). */
+typedef struct init_baton_t init_baton_t;
+
+/* Initialization function wrapper. Hides API details from init_once().
+   The implementation must return FALSE on failure. */
+typedef svn_boolean_t (*init_func_t)(init_baton_t *init_baton);
+
 /*
- * This is the actual atomic initialization driver.  The caller must
- * provide either ERR_INIT_FUNC and ERR_P, or STR_INIT_FUNC and
- * ERRSTR_P, but never both.
+ * This is the actual atomic initialization driver.
+ * Returns FALSE on failure.
  */
-static void
-init_once(svn_atomic__err_init_func_t err_init_func,
-          svn_error_t **err_p,
-          svn_atomic__str_init_func_t str_init_func,
-          const char **errstr_p,
-          volatile svn_atomic_t *global_status,
-          void *baton,
-          apr_pool_t* pool)
+static svn_boolean_t
+init_once(volatile svn_atomic_t *global_status,
+          init_func_t init_func, init_baton_t *init_baton)
 {
   /* !! Don't use localizable strings in this function, because these
      !! might cause deadlocks. This function can be used to initialize
@@ -53,44 +55,25 @@ init_once(svn_atomic__err_init_func_t er
      doesn't have statically-initialized mutexes, we implement a poor
      man's spinlock using svn_atomic_cas. */
 
-  svn_error_t *err = SVN_NO_ERROR;
-  const char *errstr = NULL;
   svn_atomic_t status = svn_atomic_cas(global_status,
                                        SVN_ATOMIC_START_INIT,
                                        SVN_ATOMIC_UNINITIALIZED);
 
-#ifdef SVN_DEBUG
-  /* Check that the parameters are valid. */
-  assert(!err_init_func != !str_init_func);
-  assert(!err_init_func == !err_p);
-  assert(!str_init_func == !errstr_p);
-#endif /* SVN_DEBUG */
-
   for (;;)
     {
       switch (status)
         {
         case SVN_ATOMIC_UNINITIALIZED:
-          if (err_init_func)
-            err = err_init_func(baton, pool);
-          else
-            errstr = str_init_func(baton);
-          if (err || errstr)
-            {
-              status = svn_atomic_cas(global_status,
-                                      SVN_ATOMIC_INIT_FAILED,
-                                      SVN_ATOMIC_START_INIT);
-            }
-          else
-            {
-              status = svn_atomic_cas(global_status,
-                                      SVN_ATOMIC_INITIALIZED,
-                                      SVN_ATOMIC_START_INIT);
-            }
-
-          /* Take another spin through the switch to report either
-             failure or success. */
-          continue;
+          {
+            const svn_boolean_t result = init_func(init_baton);
+            const svn_atomic_t init_state = (result
+                                             ? SVN_ATOMIC_INITIALIZED
+                                             : SVN_ATOMIC_INIT_FAILED);
+
+            svn_atomic_cas(global_status, init_state,
+                           SVN_ATOMIC_START_INIT);
+            return result;
+          }
 
         case SVN_ATOMIC_START_INIT:
           /* Wait for the init function to complete. */
@@ -101,19 +84,10 @@ init_once(svn_atomic__err_init_func_t er
           continue;
 
         case SVN_ATOMIC_INIT_FAILED:
-          if (err_init_func)
-            *err_p = svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, err,
-                                      "Couldn't perform atomic initialization");
-          else
-            *errstr_p = errstr;
-          return;
+          return FALSE;
 
         case SVN_ATOMIC_INITIALIZED:
-          if (err_init_func)
-            *err_p = SVN_NO_ERROR;
-          else
-            *errstr_p = NULL;
-          return;
+          return TRUE;
 
         default:
           /* Something went seriously wrong with the atomic operations. */
@@ -123,15 +97,61 @@ init_once(svn_atomic__err_init_func_t er
 }
 
 
+/* This baton structure is used by the two flavours of init-once APIs
+   to hide their differences from the init_once() driver. Each private
+   API uses only selected parts of the baton.
+
+   No part of this structure changes unless a wrapped init function is
+   actually invoked by init_once().
+*/
+struct init_baton_t
+{
+  /* Used only by svn_atomic__init_once()/err_init_func_wrapper() */
+  svn_atomic__err_init_func_t err_init_func;
+  svn_error_t *err;
+  apr_pool_t *pool;
+
+  /* Used only by svn_atomic__init_no_error()/str_init_func_wrapper() */
+  svn_atomic__str_init_func_t str_init_func;
+  const char *errstr;
+
+  /* Used by both pairs of functions */
+  void *baton;
+};
+
+/* Wrapper for the svn_atomic__init_once init function. */
+static svn_boolean_t err_init_func_wrapper(init_baton_t *init_baton)
+{
+  init_baton->err = init_baton->err_init_func(init_baton->baton,
+                                              init_baton->pool);
+  return (init_baton->err == SVN_NO_ERROR);
+}
+
 svn_error_t *
 svn_atomic__init_once(volatile svn_atomic_t *global_status,
                       svn_atomic__err_init_func_t err_init_func,
                       void *baton,
                       apr_pool_t* pool)
 {
-  svn_error_t *err;
-  init_once(err_init_func, &err, NULL, NULL, global_status, baton, pool);
-  return err;
+  init_baton_t init_baton;
+  init_baton.err_init_func = err_init_func;
+  init_baton.err = NULL;
+  init_baton.pool = pool;
+  init_baton.baton = baton;
+
+  if (init_once(global_status, err_init_func_wrapper, &init_baton))
+    return SVN_NO_ERROR;
+
+  return svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, init_baton.err,
+                          "Couldn't perform atomic initialization");
+}
+
+
+/* Wrapper for the svn_atomic__init_no_error init function. */
+static svn_boolean_t str_init_func_wrapper(init_baton_t *init_baton)
+{
+  init_baton->errstr = init_baton->str_init_func(init_baton->baton);
+  return (init_baton->errstr == NULL);
 }
 
 const char *
@@ -139,7 +159,18 @@ svn_atomic__init_once_no_error(volatile
                                svn_atomic__str_init_func_t str_init_func,
                                void *baton)
 {
-  const char *errstr;
-  init_once(NULL, NULL, str_init_func, &errstr, global_status, baton, NULL);
-  return errstr;
+  init_baton_t init_baton;
+  init_baton.str_init_func = str_init_func;
+  init_baton.errstr = NULL;
+  init_baton.baton = baton;
+
+  if (init_once(global_status, str_init_func_wrapper, &init_baton))
+    return NULL;
+
+  /* Our init function wrapper may not have been called; make sure
+     that we return generic error message in that case. */
+  if (!init_baton.errstr)
+    return "Couldn't perform atomic initialization";
+  else
+    return init_baton.errstr;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.c Sat Sep  5 06:26:58 2015
@@ -880,3 +880,33 @@ svn_auth__make_session_auth(svn_auth_bat
 
   return SVN_NO_ERROR;
 }
+
+
+static svn_error_t *
+dummy_first_creds(void **credentials,
+                  void **iter_baton,
+                  void *provider_baton,
+                  apr_hash_t *parameters,
+                  const char *realmstring,
+                  apr_pool_t *pool)
+{
+  *credentials = NULL;
+  *iter_baton = NULL;
+  return SVN_NO_ERROR;
+}
+
+void
+svn_auth__get_dummmy_simple_provider(svn_auth_provider_object_t **provider,
+                                     apr_pool_t *pool)
+{
+  static const svn_auth_provider_t vtable = {
+    SVN_AUTH_CRED_SIMPLE,
+    dummy_first_creds,
+    NULL, NULL
+  };
+
+  svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+  po->vtable = &vtable;
+  *provider = po;
+}

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.h?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/auth.h Sat Sep  5 06:26:58 2015
@@ -157,6 +157,15 @@ svn_auth__get_gpg_agent_simple_provider
      apr_pool_t *pool);
 #endif /* !defined(WIN32) || defined(DOXYGEN) */
 
+/**
+ * Set @a *provider to a dummy provider of type @c
+ * svn_auth_cred_simple_t that never returns or stores any
+ * credentials.
+ */
+void
+svn_auth__get_dummmy_simple_provider(svn_auth_provider_object_t **provider,
+                                     apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c Sat Sep  5 06:26:58 2015
@@ -339,7 +339,9 @@ prefix_pool_get_internal(apr_uint32_t *p
   value = apr_hash_get(prefix_pool->map, prefix, prefix_len);
   if (value != NULL)
     {
-      *prefix_idx = value - prefix_pool->values;
+      const apr_size_t index = value - prefix_pool->values;
+      SVN_ERR_ASSERT(index < prefix_pool->values_used);
+      *prefix_idx = (apr_uint32_t) index;
       return SVN_NO_ERROR;
     }
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/config_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/config_auth.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/config_auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/config_auth.c Sat Sep  5 06:26:58 2015
@@ -144,7 +144,7 @@ svn_config_write_auth_data(apr_hash_t *h
             apr_psprintf(pool, _("Error writing hash to '%s'"),
                          svn_dirent_local_style(auth_path, pool)));
   SVN_ERR(svn_stream_close(stream));
-  SVN_ERR(svn_io_file_rename(tmp_path, auth_path, pool));
+  SVN_ERR(svn_io_file_rename2(tmp_path, auth_path, FALSE, pool));
 
   /* To be nice, remove the realmstring from the hash again, just in
      case the caller wants their hash unchanged.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/deprecated.c Sat Sep  5 06:26:58 2015
@@ -889,6 +889,14 @@ svn_io_stat_dirent(const svn_io_dirent2_
                                 scratch_pool));
 }
 
+svn_error_t *
+svn_io_file_rename(const char *from_path, const char *to_path,
+                   apr_pool_t *pool)
+{
+  return svn_error_trace(svn_io_file_rename2(from_path, to_path,
+                                             FALSE, pool));
+}
+
 /*** From constructors.c ***/
 svn_log_changed_path_t *
 svn_log_changed_path_dup(const svn_log_changed_path_t *changed_path,
@@ -1497,14 +1505,16 @@ svn_auth_get_keychain_ssl_client_cert_pw
 #endif /* DARWIN */
 
 #if !defined(WIN32)
-#ifdef SVN_HAVE_GPG_AGENT
 void
 svn_auth_get_gpg_agent_simple_provider(svn_auth_provider_object_t **provider,
                                        apr_pool_t *pool)
 {
+#ifdef SVN_HAVE_GPG_AGENT
   svn_auth__get_gpg_agent_simple_provider(provider, pool);
-}
+#else
+  svn_auth__get_dummmy_simple_provider(provider, pool);
 #endif /* SVN_HAVE_GPG_AGENT */
+}
 #endif /* !WIN32 */
 
 svn_error_t *

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c Sat Sep  5 06:26:58 2015
@@ -142,6 +142,23 @@
 #endif
 
 #ifdef WIN32
+
+#if _WIN32_WINNT < 0x600 /* Does the SDK assume Windows Vista+? */
+typedef struct _FILE_RENAME_INFO {
+  BOOL   ReplaceIfExists;
+  HANDLE RootDirectory;
+  DWORD  FileNameLength;
+  WCHAR  FileName[1];
+} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
+
+typedef struct _FILE_DISPOSITION_INFO {
+  BOOL DeleteFile;
+} FILE_DISPOSITION_INFO, *PFILE_DISPOSITION_INFO;
+
+#define FileRenameInfo 3
+#define FileDispositionInfo 4
+#endif /* WIN32 < Vista */
+
 /* One-time initialization of the late bound Windows API functions. */
 static volatile svn_atomic_t win_dynamic_imports_state = 0;
 
@@ -152,7 +169,13 @@ typedef DWORD (WINAPI *GETFINALPATHNAMEB
                DWORD cchFilePath,
                DWORD dwFlags);
 
+typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile,
+                                                    int FileInformationClass,
+                                                    LPVOID lpFileInformation,
+                                                    DWORD dwBufferSize);
+
 static GETFINALPATHNAMEBYHANDLE get_final_path_name_by_handle_proc = NULL;
+static SetFileInformationByHandle_t set_file_information_by_handle_proc = NULL;
 
 /* Forward declaration. */
 static svn_error_t * io_win_read_link(svn_string_t **dest,
@@ -750,7 +773,7 @@ svn_io_copy_link(const char *src,
                                     ".tmp", pool));
 
   /* Move the tmp-link to link. */
-  return svn_io_file_rename(dst_tmp, dst, pool);
+  return svn_io_file_rename2(dst_tmp, dst, FALSE, pool);
 
 #else
   return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
@@ -919,7 +942,7 @@ svn_io_copy_file(const char *src,
   if (copy_perms)
     SVN_ERR(svn_io_copy_perms(src, dst_tmp, pool));
 
-  return svn_error_trace(svn_io_file_rename(dst_tmp, dst, pool));
+  return svn_error_trace(svn_io_file_rename2(dst_tmp, dst, FALSE, pool));
 }
 
 #if !defined(WIN32) && !defined(__OS2__)
@@ -1504,7 +1527,7 @@ reown_file(const char *path,
   SVN_ERR(svn_io_open_unique_file3(NULL, &unique_name,
                                    svn_dirent_dirname(path, pool),
                                    svn_io_file_del_none, pool, pool));
-  SVN_ERR(svn_io_file_rename(path, unique_name, pool));
+  SVN_ERR(svn_io_file_rename2(path, unique_name, FALSE, pool));
   SVN_ERR(svn_io_copy_file(unique_name, path, TRUE, pool));
   return svn_error_trace(svn_io_remove_file2(unique_name, FALSE, pool));
 }
@@ -1861,11 +1884,18 @@ io_win_file_attrs_set(const char *fname,
 
 static svn_error_t *win_init_dynamic_imports(void *baton, apr_pool_t *pool)
 {
-    get_final_path_name_by_handle_proc = (GETFINALPATHNAMEBYHANDLE)
-      GetProcAddress(GetModuleHandleA("kernel32.dll"),
-                     "GetFinalPathNameByHandleW");
+  HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
 
-    return SVN_NO_ERROR;
+  if (kernel32)
+    {
+      get_final_path_name_by_handle_proc = (GETFINALPATHNAMEBYHANDLE)
+        GetProcAddress(kernel32, "GetFinalPathNameByHandleW");
+
+      set_file_information_by_handle_proc = (SetFileInformationByHandle_t)
+        GetProcAddress(kernel32, "SetFileInformationByHandle");
+    }
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t * io_win_read_link(svn_string_t **dest,
@@ -1937,6 +1967,120 @@ static svn_error_t * io_win_read_link(sv
       }
 }
 
+/* Wrapper around Windows API function SetFileInformationByHandle() that
+ * returns APR status instead of boolean flag. */
+static apr_status_t
+win32_set_file_information_by_handle(HANDLE hFile,
+                                     int FileInformationClass,
+                                     LPVOID lpFileInformation,
+                                     DWORD dwBufferSize)
+{
+  svn_error_clear(svn_atomic__init_once(&win_dynamic_imports_state,
+                                        win_init_dynamic_imports,
+                                        NULL, NULL));
+
+  if (!set_file_information_by_handle_proc)
+    {
+      return SVN_ERR_UNSUPPORTED_FEATURE;
+    }
+
+  if (!set_file_information_by_handle_proc(hFile, FileInformationClass,
+                                           lpFileInformation,
+                                           dwBufferSize))
+    {
+      return apr_get_os_error();
+    }
+
+  return APR_SUCCESS;
+}
+
+svn_error_t *
+svn_io__win_delete_file_on_close(apr_file_t *file,
+                                 const char *path,
+                                 apr_pool_t *pool)
+{
+  FILE_DISPOSITION_INFO disposition_info;
+  HANDLE hFile;
+  apr_status_t status;
+
+  apr_os_file_get(&hFile, file);
+
+  disposition_info.DeleteFile = TRUE;
+
+  status = win32_set_file_information_by_handle(hFile, FileDispositionInfo,
+                                                &disposition_info,
+                                                sizeof(disposition_info));
+
+  if (status)
+    {
+      return svn_error_wrap_apr(status, _("Can't remove file '%s'"),
+                                svn_dirent_local_style(path, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io__win_rename_open_file(apr_file_t *file,
+                             const char *from_path,
+                             const char *to_path,
+                             apr_pool_t *pool)
+{
+  WCHAR *w_final_abspath;
+  size_t path_len;
+  size_t rename_size;
+  FILE_RENAME_INFO *rename_info;
+  HANDLE hFile;
+  apr_status_t status;
+
+  apr_os_file_get(&hFile, file);
+
+  SVN_ERR(svn_io__utf8_to_unicode_longpath(
+            &w_final_abspath, svn_dirent_local_style(to_path,pool),
+            pool));
+
+  path_len = wcslen(w_final_abspath);
+  rename_size = sizeof(*rename_info) + sizeof(WCHAR) * path_len;
+
+  /* The rename info struct doesn't need hacks for long paths,
+     so no ugly escaping calls here */
+  rename_info = apr_pcalloc(pool, rename_size);
+  rename_info->ReplaceIfExists = TRUE;
+  rename_info->FileNameLength = path_len;
+  memcpy(rename_info->FileName, w_final_abspath, path_len * sizeof(WCHAR));
+
+  status = win32_set_file_information_by_handle(hFile, FileRenameInfo,
+                                                rename_info,
+                                                rename_size);
+
+  if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
+    {
+      /* Set the destination file writable because Windows will not allow
+         us to rename when final_abspath is read-only. */
+      SVN_ERR(svn_io_set_file_read_write(to_path, TRUE, pool));
+
+      status = win32_set_file_information_by_handle(hFile,
+                                                    FileRenameInfo,
+                                                    rename_info,
+                                                    rename_size);
+   }
+
+  WIN32_RETRY_LOOP(status,
+                   win32_set_file_information_by_handle(hFile,
+                                                        FileRenameInfo,
+                                                        rename_info,
+                                                        rename_size));
+
+  if (status)
+    {
+      return svn_error_wrap_apr(status, _("Can't move '%s' to '%s'"),
+                                svn_dirent_local_style(from_path, pool),
+                                svn_dirent_local_style(to_path, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 #endif /* WIN32 */
 
 svn_error_t *
@@ -3874,7 +4018,7 @@ svn_io_write_atomic(const char *final_pa
     err = svn_io_copy_perms(copy_perms_path, tmp_path, scratch_pool);
 
   if (!err)
-    err = svn_io_file_rename(tmp_path, final_path, scratch_pool);
+    err = svn_io_file_rename2(tmp_path, final_path, TRUE, scratch_pool);
 
   if (err)
     {
@@ -3888,21 +4032,6 @@ svn_io_write_atomic(const char *final_pa
                                                       scratch_pool));
     }
 
-#ifdef SVN_ON_POSIX
-  {
-    /* On POSIX, the file name is stored in the file's directory entry.
-       Hence, we need to fsync() that directory as well.
-       On other operating systems, we'd only be asking for trouble
-       by trying to open and fsync a directory. */
-    apr_file_t *file;
-
-    SVN_ERR(svn_io_file_open(&file, dirname, APR_READ, APR_OS_DEFAULT,
-                             scratch_pool));
-    SVN_ERR(svn_io_file_flush_to_disk(file, scratch_pool));
-    SVN_ERR(svn_io_file_close(file, scratch_pool));
-  }
-#endif
-
   return SVN_NO_ERROR;
 }
 
@@ -4030,13 +4159,22 @@ svn_io_stat(apr_finfo_t *finfo, const ch
 static apr_status_t
 win32_file_rename(const WCHAR *from_path_w,
                   const WCHAR *to_path_w,
-                  apr_pool_t *pool)
+                  svn_boolean_t flush_to_disk)
 {
   /* APR calls MoveFileExW() with MOVEFILE_COPY_ALLOWED, while we rely
    * that rename is atomic operation. Call MoveFileEx directly on Windows
    * without MOVEFILE_COPY_ALLOWED flag to workaround it.
    */
-  if (!MoveFileExW(from_path_w, to_path_w, MOVEFILE_REPLACE_EXISTING))
+
+  DWORD flags = MOVEFILE_REPLACE_EXISTING;
+
+  if (flush_to_disk)
+    {
+      /* Do not return until the file has actually been moved on the disk. */
+      flags |= MOVEFILE_WRITE_THROUGH;
+    }
+
+  if (!MoveFileExW(from_path_w, to_path_w, flags))
       return apr_get_os_error();
 
   return APR_SUCCESS;
@@ -4044,8 +4182,8 @@ win32_file_rename(const WCHAR *from_path
 #endif
 
 svn_error_t *
-svn_io_file_rename(const char *from_path, const char *to_path,
-                   apr_pool_t *pool)
+svn_io_file_rename2(const char *from_path, const char *to_path,
+                    svn_boolean_t flush_to_disk, apr_pool_t *pool)
 {
   apr_status_t status = APR_SUCCESS;
   const char *from_path_apr, *to_path_apr;
@@ -4060,7 +4198,7 @@ svn_io_file_rename(const char *from_path
 #if defined(WIN32)
   SVN_ERR(svn_io__utf8_to_unicode_longpath(&from_path_w, from_path_apr, pool));
   SVN_ERR(svn_io__utf8_to_unicode_longpath(&to_path_w, to_path_apr, pool));
-  status = win32_file_rename(from_path_w, to_path_w, pool);
+  status = win32_file_rename(from_path_w, to_path_w, flush_to_disk);
 
   /* If the target file is read only NTFS reports EACCESS and
      FAT/FAT32 reports EEXIST */
@@ -4071,10 +4209,12 @@ svn_io_file_rename(const char *from_path
          allow renaming when from_path is read only. */
       SVN_ERR(svn_io_set_file_read_write(to_path, TRUE, pool));
 
-      status = win32_file_rename(from_path_w, to_path_w, pool);
+      status = win32_file_rename(from_path_w, to_path_w, flush_to_disk);
     }
-  WIN32_RETRY_LOOP(status, win32_file_rename(from_path_w, to_path_w, pool));
+  WIN32_RETRY_LOOP(status, win32_file_rename(from_path_w, to_path_w,
+                                             flush_to_disk));
 #elif defined(__OS2__)
+  status = apr_file_rename(from_path_apr, to_path_apr, pool);
   /* If the target file is read only NTFS reports EACCESS and
      FAT/FAT32 reports EEXIST */
   if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
@@ -4095,6 +4235,34 @@ svn_io_file_rename(const char *from_path
                               svn_dirent_local_style(from_path, pool),
                               svn_dirent_local_style(to_path, pool));
 
+#if defined(SVN_ON_POSIX)
+  if (flush_to_disk)
+    {
+      /* On POSIX, the file name is stored in the file's directory entry.
+         Hence, we need to fsync() that directory as well.
+         On other operating systems, we'd only be asking for trouble
+         by trying to open and fsync a directory. */
+      const char *dirname;
+      apr_file_t *file;
+
+      dirname = svn_dirent_dirname(to_path, pool);
+      SVN_ERR(svn_io_file_open(&file, dirname, APR_READ, APR_OS_DEFAULT,
+                               pool));
+      SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+      SVN_ERR(svn_io_file_close(file, pool));
+    }
+#elif !defined(WIN32)
+  /* Flush the target of the rename to disk. */
+  if (flush_to_disk)
+    {
+      apr_file_t *file;
+      SVN_ERR(svn_io_file_open(&file, to_path, APR_WRITE,
+                               APR_OS_DEFAULT, pool));
+      SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+      SVN_ERR(svn_io_file_close(file, pool));
+    }
+#endif
+
   return SVN_NO_ERROR;
 }
 
@@ -4103,8 +4271,8 @@ svn_error_t *
 svn_io_file_move(const char *from_path, const char *to_path,
                  apr_pool_t *pool)
 {
-  svn_error_t *err = svn_error_trace(svn_io_file_rename(from_path, to_path,
-                                                        pool));
+  svn_error_t *err = svn_error_trace(svn_io_file_rename2(from_path, to_path,
+                                                         FALSE, pool));
 
   if (err && APR_STATUS_IS_EXDEV(err->apr_err))
     {
@@ -4544,7 +4712,7 @@ svn_io_write_version_file(const char *pa
 #endif /* WIN32 || __OS2__ */
 
   /* rename the temp file as the real destination */
-  SVN_ERR(svn_io_file_rename(path_tmp, path, pool));
+  SVN_ERR(svn_io_file_rename2(path_tmp, path, FALSE, pool));
 
   /* And finally remove the perms to make it read only */
   return svn_io_set_file_read_only(path, FALSE, pool);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/stream.c Sat Sep  5 06:26:58 2015
@@ -1710,6 +1710,114 @@ svn_stream_from_string(const svn_string_
   return stream;
 }
 
+/* Baton structure for buffering read stream wrappers.
+ *
+ * We read from INNER and append the data to BUFFER.  From BUFFER, we serve
+ * read requests. Old buffer contents gets discarded once it is no longer
+ * needed.
+ */
+struct buffering_stream_wrapper_baton
+{
+  /* Our data source. */
+  svn_stream_t *inner;
+
+  /* Contains the data pre-read from INNER. Some of this may already have
+   * been delivered. */
+  svn_stringbuf_t *buffer;
+
+  /* Current read position relative to the start of BUFFER->DATA. */
+  apr_size_t buffer_pos;
+};
+
+/* Implements svn_stream_t.read_fn for buffering read stream wrappers. */
+static svn_error_t *
+read_handler_buffering_wrapper(void *baton,
+                               char *buffer,
+                               apr_size_t *len)
+{
+  struct buffering_stream_wrapper_baton *btn = baton;
+  apr_size_t left_to_read = btn->buffer->len - btn->buffer_pos;
+
+  /* This is the "normal" and potential incomplete read function.
+   * So, we only need to replenish our buffers if we ran completely dry. */
+  if (left_to_read == 0)
+    {
+      apr_size_t count = btn->buffer->blocksize;
+
+      /* Read from the INNER stream. */
+      SVN_ERR(svn_stream_read2(btn->inner, btn->buffer->data, &count));
+      btn->buffer->len = count;
+      btn->buffer_pos = 0;
+
+      /* We may now have more data that we could return. */
+      left_to_read = btn->buffer->len;
+    }
+
+  /* Cap the read request to what we can deliver from the buffer. */
+  if (left_to_read < *len)
+    *len = left_to_read;
+
+  /* Copy the data from the buffer and move the read pointer accordingly. */
+  memcpy(buffer, btn->buffer->data + btn->buffer_pos, *len);
+  btn->buffer_pos += *len;
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_stream_t.data_available_fn for buffering read stream
+ * wrappers. */
+static svn_error_t *
+data_available_handler_buffering_wrapper(void *baton,
+                                         svn_boolean_t *data_available)
+{
+  /* If we still have some unread data, this becomes easy to answer. */
+  struct buffering_stream_wrapper_baton *btn = baton;
+  if (btn->buffer->len > btn->buffer_pos)
+    {
+      *data_available = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  /* Otherwise, because we would always read from the inner streams' current
+   * position to fill the buffer, asking the inner stream when the buffer is
+   * exhausted gives the correct answer. */
+  return svn_error_trace(svn_stream_data_available(btn->inner,
+                                                   data_available));
+}
+
+/* Implements svn_stream_t.is_buffered_fn for buffering read stream wrappers.
+ */
+static svn_boolean_t
+is_buffered_handler_buffering_wrapper(void *baton)
+{
+  return TRUE;
+}
+
+svn_stream_t *
+svn_stream_wrap_buffered_read(svn_stream_t *inner,
+                              apr_pool_t *result_pool)
+{
+  svn_stream_t *stream;
+  struct buffering_stream_wrapper_baton *baton;
+
+  /* Create the wrapper stream state.
+   * The buffer is empty and we are at position 0. */
+  baton = apr_pcalloc(result_pool, sizeof(*baton));
+  baton->inner = inner;
+  baton->buffer = svn_stringbuf_create_ensure(SVN__STREAM_CHUNK_SIZE,
+                                              result_pool);
+  baton->buffer_pos = 0;
+
+  /* Create the wrapper stream object and set up the vtable. */
+  stream = svn_stream_create(baton, result_pool);
+  svn_stream_set_read2(stream, read_handler_buffering_wrapper, NULL);
+  svn_stream_set_data_available(stream,
+                                data_available_handler_buffering_wrapper);
+  svn_stream__set_is_buffered(stream, is_buffered_handler_buffering_wrapper);
+
+  return stream;
+}
+
 
 svn_error_t *
 svn_stream_for_stdin(svn_stream_t **in, apr_pool_t *pool)
@@ -2005,48 +2113,6 @@ struct install_baton_t
 
 #ifdef WIN32
 
-#if _WIN32_WINNT < 0x600 /* Does the SDK assume Windows Vista+? */
-typedef struct _FILE_RENAME_INFO {
-  BOOL   ReplaceIfExists;
-  HANDLE RootDirectory;
-  DWORD  FileNameLength;
-  WCHAR  FileName[1];
-} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
-
-typedef struct _FILE_DISPOSITION_INFO {
-  BOOL DeleteFile;
-} FILE_DISPOSITION_INFO, *PFILE_DISPOSITION_INFO;
-
-#define FileRenameInfo 3
-#define FileDispositionInfo 4
-
-typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile,
-                                                    int FileInformationClass,
-                                                    LPVOID lpFileInformation,
-                                                    DWORD dwBufferSize);
-
-static volatile SetFileInformationByHandle_t SetFileInformationByHandle_p = 0;
-#define SetFileInformationByHandle (*SetFileInformationByHandle_p)
-
-static volatile svn_atomic_t SetFileInformationByHandle_a = 0;
-
-
-static svn_error_t *
-find_SetFileInformationByHandle(void *baton, apr_pool_t *scratch_pool)
-{
-  HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
-
-  if (kernel32)
-    {
-      SetFileInformationByHandle_p =
-                    (SetFileInformationByHandle_t)
-                      GetProcAddress(kernel32, "SetFileInformationByHandle");
-    }
-
-  return SVN_NO_ERROR;
-}
-#endif /* WIN32 < Vista */
-
 /* Create and open a tempfile in DIRECTORY. Return its handle and path */
 static svn_error_t *
 create_tempfile(HANDLE *hFile,
@@ -2204,105 +2270,47 @@ svn_stream__install_stream(svn_stream_t
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(final_abspath));
 #ifdef WIN32
-
-#if _WIN32_WINNT < 0x600
-  SVN_ERR(svn_atomic__init_once(&SetFileInformationByHandle_a,
-                                find_SetFileInformationByHandle,
-                                NULL, scratch_pool));
-
-  if (!SetFileInformationByHandle_p)
-    SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
-  else
-#endif /* WIN32 < Windows Vista */
+  err = svn_io__win_rename_open_file(ib->baton_apr.file,  ib->tmp_path,
+                                     final_abspath, scratch_pool);
+  if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
     {
-      WCHAR *w_final_abspath;
-      size_t path_len;
-      size_t rename_size;
-      FILE_RENAME_INFO *rename_info;
-      HANDLE hFile;
-
-      apr_os_file_get(&hFile, ib->baton_apr.file);
-
-      SVN_ERR(svn_io__utf8_to_unicode_longpath(&w_final_abspath,
-                                               svn_dirent_local_style(
-                                                          final_abspath,
-                                                          scratch_pool),
-                                               scratch_pool));
-      path_len = wcslen(w_final_abspath);
-      rename_size = sizeof(*rename_info) + sizeof(WCHAR) * path_len;
-
-      /* The rename info struct doesn't need hacks for long paths,
-         so no ugly escaping calls here */
-      rename_info = apr_pcalloc(scratch_pool, rename_size);
-      rename_info->ReplaceIfExists = TRUE;
-      rename_info->FileNameLength = path_len;
-      memcpy(rename_info->FileName, w_final_abspath, path_len * sizeof(WCHAR));
+      svn_error_t *err2;
 
-      if (!SetFileInformationByHandle(hFile, FileRenameInfo, rename_info,
-                                      rename_size))
-        {
-          svn_boolean_t retry = FALSE;
-          err = svn_error_wrap_apr(apr_get_os_error(), NULL);
+      err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                    scratch_pool),
+                                         scratch_pool);
 
-          /* ### rhuijben: I wouldn't be surprised if we later find out that we
-                           have to fall back to close+rename on some specific
-                           error values here, to support some non standard NAS
-                           and filesystem scenarios. */
-
-          if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
-            {
-              svn_error_t *err2;
+      if (err2)
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        svn_error_clear(err);
 
-              err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
-                                                            scratch_pool),
-                                                 scratch_pool);
+      err = svn_io__win_rename_open_file(ib->baton_apr.file, ib->tmp_path,
+                                         final_abspath, scratch_pool);
+    }
 
-              if (err2)
-                return svn_error_trace(svn_error_compose_create(err, err2));
-              else
-                svn_error_clear(err);
-
-              retry = TRUE;
-              err = NULL;
-            }
-          else if (err && (APR_STATUS_IS_EACCES(err->apr_err)
-                           || APR_STATUS_IS_EEXIST(err->apr_err)))
-            {
-              svn_error_clear(err);
-              retry = TRUE;
-              err = NULL;
-
-              /* Set the destination file writable because Windows will not allow
-                 us to rename when final_abspath is read-only. */
-              SVN_ERR(svn_io_set_file_read_write(final_abspath, TRUE,
-                                                 scratch_pool));
-            }
-
-          if (retry)
-            {
-              if (!SetFileInformationByHandle(hFile, FileRenameInfo,
-                                              rename_info, rename_size))
-                {
-                  err = svn_error_wrap_apr(
-                                apr_get_os_error(),
-                                _("Can't move '%s' to '%s'"),
-                                svn_dirent_local_style(ib->tmp_path,
-                                                       scratch_pool),
-                                svn_dirent_local_style(final_abspath,
-                                                       scratch_pool));
-                }
-            }
-        }
-      else
-        err = NULL;
+  /* ### rhuijben: I wouldn't be surprised if we later find out that we
+                   have to fall back to close+rename on some specific
+                   error values here, to support some non standard NAS
+                   and filesystem scenarios. */
+  if (err && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
+    {
+      /* Rename open files is not supported on this platform: fallback to
+         svn_io_file_rename2(). */
+      svn_error_clear(err);
+      err = SVN_NO_ERROR;
 
+      SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+    }
+  else
+    {
       return svn_error_compose_create(err,
                                       svn_io_file_close(ib->baton_apr.file,
                                                         scratch_pool));
     }
 #endif
 
-  err = svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool);
+  err = svn_io_file_rename2(ib->tmp_path, final_abspath, FALSE, scratch_pool);
 
   /* A missing directory is too common to not cover here. */
   if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
@@ -2320,7 +2328,7 @@ svn_stream__install_stream(svn_stream_t
         /* We could create a directory: retry install */
         svn_error_clear(err);
 
-      SVN_ERR(svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool));
+      SVN_ERR(svn_io_file_rename2(ib->tmp_path, final_abspath, FALSE, scratch_pool));
     }
   else
     SVN_ERR(err);
@@ -2359,37 +2367,22 @@ svn_stream__install_delete(svn_stream_t
   struct install_baton_t *ib = install_stream->baton;
 
 #ifdef WIN32
-  BOOL done;
-
-#if _WIN32_WINNT < 0x600
-
-  SVN_ERR(svn_atomic__init_once(&SetFileInformationByHandle_a,
-                                find_SetFileInformationByHandle,
-                                NULL, scratch_pool));
+  svn_error_t *err;
 
-  if (!SetFileInformationByHandle_p)
-    done = FALSE;
-  else
-#endif /* WIN32 < Windows Vista */
+  /* Mark the file as delete on close to avoid having to reopen
+     the file as part of the delete handling. */
+  err = svn_io__win_delete_file_on_close(ib->baton_apr.file,  ib->tmp_path,
+                                         scratch_pool);
+  if (err == SVN_NO_ERROR)
     {
-      FILE_DISPOSITION_INFO disposition_info;
-      HANDLE hFile;
-
-      apr_os_file_get(&hFile, ib->baton_apr.file);
-
-      disposition_info.DeleteFile = TRUE;
-
-      /* Mark the file as delete on close to avoid having to reopen
-         the file as part of the delete handling. */
-      done = SetFileInformationByHandle(hFile, FileDispositionInfo,
-                                        &disposition_info,
-                                        sizeof(disposition_info));
+      SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+      return SVN_NO_ERROR; /* File is already gone */
     }
 
-   SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
-
-   if (done)
-     return SVN_NO_ERROR; /* File is already gone */
+  /* Deleting file on close may be unsupported, so ignore errors and
+     fallback to svn_io_remove_file2(). */
+  svn_error_clear(err);
+  SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
 #endif
 
   return svn_error_trace(svn_io_remove_file2(ib->tmp_path, FALSE,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/subst.c Sat Sep  5 06:26:58 2015
@@ -1649,7 +1649,7 @@ detranslate_special_file(const char *src
                            cancel_func, cancel_baton, scratch_pool));
 
   /* Do the atomic rename from our temporary location. */
-  return svn_error_trace(svn_io_file_rename(dst_tmp, dst, scratch_pool));
+  return svn_error_trace(svn_io_file_rename2(dst_tmp, dst, FALSE, scratch_pool));
 }
 
 /* Creates a special file DST from the "normal form" located in SOURCE.
@@ -1691,17 +1691,16 @@ create_special_file_from_stream(svn_stre
                                                    ".tmp", pool);
 
       /* If we had an error, check to see if it was because symlinks are
-         not supported on the platform.  If so, fall back
-         to using the internal representation. */
-      if (err)
+         not supported on the platform.  If so, fall back to using the
+         internal representation. */
+      if (err && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
         {
-          if (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
-            {
-              svn_error_clear(err);
-              create_using_internal_representation = TRUE;
-            }
-          else
-            return err;
+          svn_error_clear(err);
+          create_using_internal_representation = TRUE;
+        }
+      else if (err)
+        {
+          return svn_error_trace(err);
         }
     }
   else
@@ -1733,7 +1732,7 @@ create_special_file_from_stream(svn_stre
     }
 
   /* Do the atomic rename from our temporary location. */
-  return svn_error_trace(svn_io_file_rename(dst_tmp, dst, pool));
+  return svn_error_trace(svn_io_file_rename2(dst_tmp, dst, FALSE, pool));
 }
 
 
@@ -1824,7 +1823,7 @@ svn_subst_copy_and_translate4(const char
     }
 
   /* Now that dst_tmp contains the translated data, do the atomic rename. */
-  SVN_ERR(svn_io_file_rename(dst_tmp, dst, pool));
+  SVN_ERR(svn_io_file_rename2(dst_tmp, dst, FALSE, pool));
 
   /* Preserve the source file's permission bits. */
   SVN_ERR(svn_io_copy_perms(src, dst, pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/xml.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/xml.c Sat Sep  5 06:26:58 2015
@@ -34,6 +34,7 @@
 #include "svn_ctype.h"
 
 #include "private/svn_utf_private.h"
+#include "private/svn_subr_private.h"
 
 #ifdef SVN_HAVE_OLD_EXPAT
 #include <xmlparse.h>

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/copy.c Sat Sep  5 06:26:58 2015
@@ -1104,8 +1104,8 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
     {
       svn_error_t *err;
 
-      err = svn_error_trace(svn_io_file_rename(src_abspath, dst_abspath,
-                                               scratch_pool));
+      err = svn_error_trace(svn_io_file_rename2(src_abspath, dst_abspath,
+                                                FALSE, scratch_pool));
 
       /* Let's try if we can keep wc.db consistent even when the move
          fails. Deleting the target is a wc.db only operation, while

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/node.c Sat Sep  5 06:26:58 2015
@@ -906,7 +906,8 @@ svn_wc__rename_wc(svn_wc_context_t *wc_c
     {
       SVN_ERR(svn_wc__db_drop_root(wc_ctx->db, wcroot_abspath, scratch_pool));
 
-      SVN_ERR(svn_io_file_rename(from_abspath, dst_abspath, scratch_pool));
+      SVN_ERR(svn_io_file_rename2(from_abspath, dst_abspath, FALSE,
+                                  scratch_pool));
     }
   else
     return svn_error_createf(

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/upgrade.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/upgrade.c Sat Sep  5 06:26:58 2015
@@ -1434,7 +1434,7 @@ rename_pristine_file(void *baton,
       const char *new_abspath
         = apr_pstrcat(pool, abspath, PRISTINE_STORAGE_EXT, SVN_VA_NULL);
 
-      SVN_ERR(svn_io_file_rename(abspath, new_abspath, pool));
+      SVN_ERR(svn_io_file_rename2(abspath, new_abspath, FALSE, pool));
     }
   return SVN_NO_ERROR;
 }
@@ -2513,7 +2513,7 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   /* Renaming the db file is what makes the pre-wcng into a wcng */
   db_from = svn_wc__adm_child(data.root_abspath, SDB_FILE, scratch_pool);
   db_to = svn_wc__adm_child(local_abspath, SDB_FILE, scratch_pool);
-  SVN_ERR(svn_io_file_rename(db_from, db_to, scratch_pool));
+  SVN_ERR(svn_io_file_rename2(db_from, db_to, FALSE, scratch_pool));
 
   /* Now we have a working wcng, tidy up the droppings */
   SVN_ERR(svn_wc__db_open(&db, NULL /* ### config */, FALSE, FALSE,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_pristine.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc_db_pristine.c Sat Sep  5 06:26:58 2015
@@ -569,7 +569,8 @@ maybe_transfer_one_pristine(svn_wc__db_w
 
   /* Move the file to its target location.  (If it is already there, it is
    * an orphan file and it doesn't matter if we overwrite it.) */
-  err = svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool);
+  err = svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE,
+                            scratch_pool);
 
   /* Maybe the directory doesn't exist yet? */
   if (err && APR_STATUS_IS_ENOENT(err->apr_err))
@@ -587,7 +588,8 @@ maybe_transfer_one_pristine(svn_wc__db_w
         /* We could create a directory: retry install */
         svn_error_clear(err);
 
-      SVN_ERR(svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool));
+      SVN_ERR(svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE,
+                                  scratch_pool));
     }
   else
     SVN_ERR(err);
@@ -709,7 +711,7 @@ remove_file(const char *file_abspath,
   SVN_ERR(svn_io_open_unique_file3(NULL, &temp_abspath, temp_dir_abspath,
                                    svn_io_file_del_none,
                                    scratch_pool, scratch_pool));
-  err = svn_io_file_rename(file_abspath, temp_abspath, scratch_pool);
+  err = svn_io_file_rename2(file_abspath, temp_abspath, FALSE, scratch_pool);
   if (err && ignore_enoent && APR_STATUS_IS_ENOENT(err->apr_err))
     svn_error_clear(err);
   else

Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/workqueue.c Sat Sep  5 06:26:58 2015
@@ -257,7 +257,8 @@ install_committed_file(svn_boolean_t *ov
 
   if (! same)
     {
-      SVN_ERR(svn_io_file_rename(tmp_wfile, file_abspath, scratch_pool));
+      SVN_ERR(svn_io_file_rename2(tmp_wfile, file_abspath, FALSE,
+                                  scratch_pool));
       *overwrote_working = TRUE;
     }
 
@@ -1127,9 +1128,9 @@ run_prej_install(work_item_baton_t *wqb,
                                   scratch_pool, scratch_pool));
 
   /* ... and atomically move it into place.  */
-  SVN_ERR(svn_io_file_rename(tmp_prejfile_abspath,
-                             prejfile_abspath,
-                             scratch_pool));
+  SVN_ERR(svn_io_file_rename2(tmp_prejfile_abspath,
+                              prejfile_abspath, FALSE,
+                              scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/svn.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/svn.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/svn.c Sat Sep  5 06:26:58 2015
@@ -415,7 +415,39 @@ const apr_getopt_option_t svn_cl__option
                           "                             "
                           "current revision (recommended when tagging)")},
   {"show-item", opt_show_item, 1,
-                       N_("print only the item identified by ARG")},
+                       N_("print only the item identified by ARG:\n"
+                          "                             "
+                          "   'kind'       node kind of TARGET\n"
+                          "                             "
+                          "   'url'        URL of TARGET in the repository\n"
+                          "                             "
+                          "   'relative-url'\n"
+                          "                             "
+                          "                repository-relative URL of TARGET\n"
+                          "                             "
+                          "   'repos-root-url'\n"
+                          "                             "
+                          "                root URL of repository\n"
+                          "                             "
+                          "   'repos-uuid' UUID of repository\n"
+                          "                             "
+                          "   'revision'   specified or implied revision\n"
+                          "                             "
+                          "   'last-changed-revision'\n"
+                          "                             "
+                          "                last change of TARGET at or before\n"
+                          "                             "
+                          "                'revision'\n"
+                          "                             "
+                          "   'last-changed-date'\n"
+                          "                             "
+                          "                date of 'last-changed-revision'\n"
+                          "                             "
+                          "   'last-changed-author'\n"
+                          "                             "
+                          "                author of 'last-changed-revision'\n"
+                          "                             "
+                          "   'wc-root'    root of TARGET's working copy")},
 
   /* Long-opt Aliases
    *
@@ -726,23 +758,12 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "usage: info [TARGET[@REV]...]\n"
      "\n"
      "  Print information about each TARGET (default: '.').\n"
-     "  TARGET may be either a working-copy path or URL.  If specified, REV\n"
-     "  determines in which revision the target is first looked up.\n"
+     "  TARGET may be either a working-copy path or a URL.  If specified, REV\n"
+     "  determines in which revision the target is first looked up; the default\n"
+     "  is HEAD for a URL or BASE for a WC path.\n"
      "\n"
      "  With --show-item, print only the value of one item of information\n"
-     "  about TARGET. One of the following items can be selected:\n"
-     "     kind                  the kind of TARGET\n"
-     "     url                   the URL of TARGET in the repository\n"
-     "     relative-url          the repository-relative URL\n"
-     "     repos-root-url        the repository root URL\n"
-     "     repos-uuid            the repository UUID\n"
-     "     revision              the revision of TARGET (defaults to BASE\n"
-     "                           for working copy paths and HEAD for URLs)\n"
-     "     last-changed-revision the most recent revision in which TARGET\n"
-     "                           was changed\n"
-     "     last-changed-date     the date of the last-changed revision\n"
-     "     last-changed-author   the author of the last-changed revision\n"
-     "     wc-root               the root of TARGET's working copy"),
+     "  about TARGET.\n"),
     {'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
      opt_changelist, opt_include_externals, opt_show_item, opt_no_newline}
   },

Modified: subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c Sat Sep  5 06:26:58 2015
@@ -1548,6 +1548,7 @@ subcommand_load_revprops(apr_getopt_t *o
 
   /* Read the stream from STDIN.  Users can redirect a file. */
   SVN_ERR(svn_stream_for_stdin(&stdin_stream, pool));
+  stdin_stream = svn_stream_wrap_buffered_read(stdin_stream, pool);
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
@@ -2112,6 +2113,7 @@ subcommand_info(apr_getopt_t *os, void *
   svn_fs_t *fs;
   int fs_format;
   const char *uuid;
+  svn_revnum_t head_rev;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -2124,6 +2126,9 @@ subcommand_info(apr_getopt_t *os, void *
 
   SVN_ERR(svn_fs_get_uuid(fs, &uuid, pool));
   SVN_ERR(svn_cmdline_printf(pool, _("UUID: %s\n"), uuid));
+
+  SVN_ERR(svn_fs_youngest_rev(&head_rev, fs, pool));
+  SVN_ERR(svn_cmdline_printf(pool, _("Revisions: %ld\n"), head_rev));
   {
     int repos_format, minor;
     svn_version_t *repos_version, *fs_version;

Modified: subversion/branches/move-tracking-2/subversion/svnfsfs/load-index-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnfsfs/load-index-cmd.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnfsfs/load-index-cmd.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnfsfs/load-index-cmd.c Sat Sep  5 06:26:58 2015
@@ -54,13 +54,15 @@ str_to_item_type(unsigned *type,
                            _("Unknown item type '%s'"), str);
 }
 
-/* Parse the hex string given as const char * at IDX in TOKENS and return
- * its value in *VALUE_P.  Check for index overflows and non-hex chars.
+/* Parse the string given as const char * at IDX in TOKENS and return its
+ * value in *VALUE_P.  Assume that the string an integer with base RADIX.
+ * Check for index overflows and non-hex chars.
  */
 static svn_error_t *
 token_to_i64(apr_int64_t *value_p,
              apr_array_header_t *tokens,
-             int idx)
+             int idx,
+             int radix)
 {
   const char *hex;
   char *end;
@@ -75,7 +77,7 @@ token_to_i64(apr_int64_t *value_p,
 
   /* hex -> int conversion */
   hex = APR_ARRAY_IDX(tokens, idx, const char *);
-  value = apr_strtoi64(hex, &end, 16);
+  value = apr_strtoi64(hex, &end, radix);
 
   /* Has the whole token be parsed without error? */
   if (errno || *end != '\0')
@@ -102,11 +104,13 @@ parse_index_line(svn_fs_fs__p2l_entry_t
   apr_int64_t value;
 
   /* Parse the hex columns. */
-  SVN_ERR(token_to_i64(&value, tokens, 0));
+  SVN_ERR(token_to_i64(&value, tokens, 0, 16));
   result->offset = (apr_off_t)value;
-  SVN_ERR(token_to_i64(&value, tokens, 1));
+  SVN_ERR(token_to_i64(&value, tokens, 1, 16));
   result->size = (apr_off_t)value;
-  SVN_ERR(token_to_i64(&value, tokens, 4));
+
+  /* Parse the rightmost colum that we care of. */
+  SVN_ERR(token_to_i64(&value, tokens, 4, 10));
   result->item.number = (apr_uint64_t)value;
 
   /* We now know that there were at least 5 columns.
@@ -183,6 +187,7 @@ subcommand__load_index(apr_getopt_t *os,
   svn_stream_t *input;
 
   SVN_ERR(svn_stream_for_stdin(&input, pool));
+  input = svn_stream_wrap_buffered_read(input, pool);
   SVN_ERR(load_index(opt_state->repository_path, input, pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnfsfs/stats-cmd.c Sat Sep  5 06:26:58 2015
@@ -47,10 +47,10 @@ print_two_power(int i,
    */
   const char *si_prefixes = " kMGTPEZY";
 
-  int number = (1 << (i % 10));
-  int thousands = i / 10;
+  int number = (i >= 0) ? (1 << (i % 10)) : 0;
+  int thousands = (i >= 0) ? (i / 10) : 0;
 
-  char si_prefix = ((thousands >= 0) && (thousands < strlen(si_prefixes)))
+  char si_prefix = (thousands < strlen(si_prefixes))
                  ? si_prefixes[thousands]
                  : '?';
 
@@ -343,7 +343,7 @@ print_stats(svn_fs_fs__stats_t *stats,
             apr_pool_t *pool)
 {
   /* print results */
-  printf("\nGlobal statistics:\n");
+  printf("\n\nGlobal statistics:\n");
   printf(_("%20s bytes in %12s revisions\n"
            "%20s bytes in %12s changes\n"
            "%20s bytes in %12s node revision records\n"

Modified: subversion/branches/move-tracking-2/subversion/svnserve/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/cyrus_auth.c?rev=1701348&r1=1701347&r2=1701348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnserve/cyrus_auth.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnserve/cyrus_auth.c Sat Sep  5 06:26:58 2015
@@ -199,7 +199,7 @@ static svn_error_t *try_auth(svn_ra_svn_
 
   while (result == SASL_CONTINUE)
     {
-      svn_ra_svn_item_t *item;
+      svn_ra_svn__item_t *item;
 
       arg = svn_string_ncreate(out, outlen, pool);
       /* Encode what we send to the client. */
@@ -213,7 +213,7 @@ static svn_error_t *try_auth(svn_ra_svn_
       if (item->kind != SVN_RA_SVN_STRING)
         return SVN_NO_ERROR;
 
-      in = item->u.string;
+      in = &item->u.string;
       if (use_base64)
         in = svn_base64_decode_string(in, pool);