subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danie...@apache.org
Subject svn commit: r1703735 [5/8] - in /subversion/branches/patch-exec: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ notes/ subversion/ subversion/bindings/swig/include/ subversion/include/ subversion/include/pr...
Date Fri, 18 Sep 2015 01:38:50 GMT
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/io.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/io.c Fri Sep 18 01:38:47 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,
@@ -555,10 +578,8 @@ svn_io_open_uniquely_named(apr_file_t **
                 continue;
 
 #ifdef WIN32
-              apr_err_2 = APR_TO_OS_ERROR(apr_err);
-
-              if (apr_err_2 == ERROR_ACCESS_DENIED ||
-                  apr_err_2 == ERROR_SHARING_VIOLATION)
+              if (apr_err == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED) ||
+                  apr_err == APR_FROM_OS_ERROR(ERROR_SHARING_VIOLATION))
                 {
                   /* The file is in use by another process or is hidden;
                      create a new name, but don't do this 99999 times in
@@ -750,7 +771,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 +940,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 +1525,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 +1882,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 +1965,130 @@ 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);
+   }
+
+  /* Windows returns Vista+ client accessing network share stored on Windows
+     Server 2003 returns ERROR_ACCESS_DENIED. The same happens when Vista+
+     client access Windows Server 2008 with disabled SMBv2 protocol.
+
+     So return SVN_ERR_UNSUPPORTED_FEATURE in this case like we do when
+     SetFileInformationByHandle() is not available and let caller to
+     handle it.
+
+     See "Access denied error on checkout-commit after updating to 1.9.X"
+     discussion on dev@s.a.o:
+     http://svn.haxx.se/dev/archive-2015-09/0054.shtml */
+  if (status == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED))
+    {
+      status = SVN_ERR_UNSUPPORTED_FEATURE;
+    }
+
+  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 *
@@ -2120,7 +2272,6 @@ svn_io_is_file_executable(svn_boolean_t
 
 
 /*** File locking. ***/
-#if !defined(WIN32) && !defined(__OS2__)
 /* Clear all outstanding locks on ARG, an open apr_file_t *. */
 static apr_status_t
 file_clear_locks(void *arg)
@@ -2135,7 +2286,6 @@ file_clear_locks(void *arg)
 
   return 0;
 }
-#endif
 
 svn_error_t *
 svn_io_lock_open_file(apr_file_t *lockfile_handle,
@@ -2193,13 +2343,14 @@ svn_io_lock_open_file(apr_file_t *lockfi
         }
     }
 
-/* On Windows and OS/2 file locks are automatically released when
-   the file handle closes */
-#if !defined(WIN32) && !defined(__OS2__)
+  /* On Windows, a process may not release file locks before closing the
+     handle, and in this case the outstanding locks are unlocked by the OS.
+     However, this is not recommended, because the actual unlocking may be
+     postponed depending on available system resources.  We explicitly unlock
+     the file as a part of the pool cleanup handler. */
   apr_pool_cleanup_register(pool, lockfile_handle,
                             file_clear_locks,
                             apr_pool_cleanup_null);
-#endif
 
   return SVN_NO_ERROR;
 }
@@ -2223,11 +2374,7 @@ svn_io_unlock_open_file(apr_file_t *lock
     return svn_error_wrap_apr(apr_err, _("Can't unlock file '%s'"),
                               try_utf8_from_internal_style(fname, pool));
 
-/* On Windows and OS/2 file locks are automatically released when
-   the file handle closes */
-#if !defined(WIN32) && !defined(__OS2__)
   apr_pool_cleanup_kill(pool, lockfile_handle, file_clear_locks);
-#endif
 
   return SVN_NO_ERROR;
 }
@@ -3847,11 +3994,12 @@ svn_io_write_unique(const char **tmp_pat
 }
 
 svn_error_t *
-svn_io_write_atomic(const char *final_path,
-                    const void *buf,
-                    apr_size_t nbytes,
-                    const char *copy_perms_path,
-                    apr_pool_t *scratch_pool)
+svn_io_write_atomic2(const char *final_path,
+                     const void *buf,
+                     apr_size_t nbytes,
+                     const char *copy_perms_path,
+                     svn_boolean_t flush_to_disk,
+                     apr_pool_t *scratch_pool)
 {
   apr_file_t *tmp_file;
   const char *tmp_path;
@@ -3864,7 +4012,7 @@ svn_io_write_atomic(const char *final_pa
 
   err = svn_io_file_write_full(tmp_file, buf, nbytes, NULL, scratch_pool);
 
-  if (!err)
+  if (!err && flush_to_disk)
     err = svn_io_file_flush_to_disk(tmp_file, scratch_pool);
 
   err = svn_error_compose_create(err,
@@ -3874,7 +4022,8 @@ 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, flush_to_disk,
+                              scratch_pool);
 
   if (err)
     {
@@ -3888,21 +4037,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 +4164,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 +4187,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 +4203,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 +4214,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 +4240,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 +4276,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))
     {
@@ -4264,8 +4437,8 @@ svn_io_dir_remove_nonrecursive(const cha
   {
     svn_boolean_t retry = TRUE;
 
-    if (APR_TO_OS_ERROR(status) == ERROR_DIR_NOT_EMPTY)
-      {
+    if (status == APR_FROM_OS_ERROR(ERROR_DIR_NOT_EMPTY))
+    {
         apr_status_t empty_status = dir_is_empty(dirname_apr, pool);
 
         if (APR_STATUS_IS_ENOTEMPTY(empty_status))
@@ -4544,7 +4717,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);
@@ -4941,7 +5114,7 @@ temp_file_create(apr_file_t **new_file,
 
       /* Generate a number that should be unique for this application and
          usually for the entire computer to reduce the number of cycles
-         through this loop. (A bit of calculation is much cheaper then
+         through this loop. (A bit of calculation is much cheaper than
          disk io) */
       unique_nr = baseNr + 3 * i;
 
@@ -4972,10 +5145,8 @@ temp_file_create(apr_file_t **new_file,
               if (!apr_err_2 && finfo.filetype == APR_DIR)
                 continue;
 
-              apr_err_2 = APR_TO_OS_ERROR(apr_err);
-
-              if (apr_err_2 == ERROR_ACCESS_DENIED ||
-                  apr_err_2 == ERROR_SHARING_VIOLATION)
+              if (apr_err == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED) ||
+                  apr_err == APR_FROM_OS_ERROR(ERROR_SHARING_VIOLATION))
                 {
                   /* The file is in use by another process or is hidden;
                      create a new name, but don't do this 99999 times in

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/stream.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/stream.c Fri Sep 18 01:38:47 2015
@@ -200,6 +200,9 @@ svn_stream_skip(svn_stream_t *stream, ap
     {
       svn_read_fn_t read_fn = stream->read_full_fn ? stream->read_full_fn
                                                    : stream->read_fn;
+      if (read_fn == NULL)
+        return svn_error_create(SVN_ERR_STREAM_NOT_SUPPORTED, NULL, NULL);
+
       return svn_error_trace(skip_default_handler(stream->baton, len,
                                                   read_fn));
     }
@@ -1055,10 +1058,12 @@ svn_stream_open_unique(svn_stream_t **st
 }
 
 
-svn_stream_t *
-svn_stream_from_aprfile2(apr_file_t *file,
-                         svn_boolean_t disown,
-                         apr_pool_t *pool)
+/* Helper function that creates a stream from an APR file. */
+static svn_stream_t *
+make_stream_from_apr_file(apr_file_t *file,
+                          svn_boolean_t disown,
+                          svn_boolean_t supports_seek,
+                          apr_pool_t *pool)
 {
   struct baton_apr *baton;
   svn_stream_t *stream;
@@ -1072,9 +1077,14 @@ svn_stream_from_aprfile2(apr_file_t *fil
   stream = svn_stream_create(baton, pool);
   svn_stream_set_read2(stream, read_handler_apr, read_full_handler_apr);
   svn_stream_set_write(stream, write_handler_apr);
-  svn_stream_set_skip(stream, skip_handler_apr);
-  svn_stream_set_mark(stream, mark_handler_apr);
-  svn_stream_set_seek(stream, seek_handler_apr);
+
+  if (supports_seek)
+    {
+      svn_stream_set_skip(stream, skip_handler_apr);
+      svn_stream_set_mark(stream, mark_handler_apr);
+      svn_stream_set_seek(stream, seek_handler_apr);
+    }
+
   svn_stream_set_data_available(stream, data_available_handler_apr);
   svn_stream__set_is_buffered(stream, is_buffered_handler_apr);
   stream->file = file;
@@ -1085,6 +1095,14 @@ svn_stream_from_aprfile2(apr_file_t *fil
   return stream;
 }
 
+svn_stream_t *
+svn_stream_from_aprfile2(apr_file_t *file,
+                         svn_boolean_t disown,
+                         apr_pool_t *pool)
+{
+  return make_stream_from_apr_file(file, disown, TRUE, pool);
+}
+
 apr_file_t *
 svn_stream__aprfile(svn_stream_t *stream)
 {
@@ -1712,16 +1730,23 @@ svn_stream_from_string(const svn_string_
 
 
 svn_error_t *
-svn_stream_for_stdin(svn_stream_t **in, apr_pool_t *pool)
+svn_stream_for_stdin2(svn_stream_t **in,
+                      svn_boolean_t buffered,
+                      apr_pool_t *pool)
 {
   apr_file_t *stdin_file;
   apr_status_t apr_err;
 
-  apr_err = apr_file_open_stdin(&stdin_file, pool);
+  apr_uint32_t flags = buffered ? APR_BUFFERED : 0;
+  apr_err = apr_file_open_flags_stdin(&stdin_file, flags, pool);
   if (apr_err)
     return svn_error_wrap_apr(apr_err, "Can't open stdin");
 
-  *in = svn_stream_from_aprfile2(stdin_file, TRUE, pool);
+  /* STDIN may or may not support positioning requests, but generally
+     it does not, or the behavior is implementation-specific.  Hence,
+     we cannot safely advertise mark(), seek() and non-default skip()
+     support. */
+  *in = make_stream_from_apr_file(stdin_file, TRUE, FALSE, pool);
 
   return SVN_NO_ERROR;
 }
@@ -1737,7 +1762,11 @@ svn_stream_for_stdout(svn_stream_t **out
   if (apr_err)
     return svn_error_wrap_apr(apr_err, "Can't open stdout");
 
-  *out = svn_stream_from_aprfile2(stdout_file, TRUE, pool);
+  /* STDOUT may or may not support positioning requests, but generally
+     it does not, or the behavior is implementation-specific.  Hence,
+     we cannot safely advertise mark(), seek() and non-default skip()
+     support. */
+  *out = make_stream_from_apr_file(stdout_file, TRUE, FALSE, pool);
 
   return SVN_NO_ERROR;
 }
@@ -1753,7 +1782,11 @@ svn_stream_for_stderr(svn_stream_t **err
   if (apr_err)
     return svn_error_wrap_apr(apr_err, "Can't open stderr");
 
-  *err = svn_stream_from_aprfile2(stderr_file, TRUE, pool);
+  /* STDERR may or may not support positioning requests, but generally
+     it does not, or the behavior is implementation-specific.  Hence,
+     we cannot safely advertise mark(), seek() and non-default skip()
+     support. */
+  *err = make_stream_from_apr_file(stderr_file, TRUE, FALSE, pool);
 
   return SVN_NO_ERROR;
 }
@@ -2005,48 +2038,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,
@@ -2115,6 +2106,8 @@ create_tempfile(HANDLE *hFile,
   return SVN_NO_ERROR;
 }
 
+#endif /* WIN32 */
+
 /* Implements svn_close_fn_t */
 static svn_error_t *
 install_close(void *baton)
@@ -2127,8 +2120,6 @@ install_close(void *baton)
   return SVN_NO_ERROR;
 }
 
-#endif /* WIN32 */
-
 svn_error_t *
 svn_stream__create_for_install(svn_stream_t **install_stream,
                                const char *tmp_abspath,
@@ -2151,8 +2142,8 @@ svn_stream__create_for_install(svn_strea
   /* Wrap as a standard APR file to allow sharing implementation.
 
      But do note that some file functions (such as retrieving the name)
-     don't work on this wrapper. */
-  /* ### Buffered, or not? */
+     don't work on this wrapper.
+     Use buffered mode to match svn_io_open_unique_file3() behavior. */
   status = apr_os_file_put(&file, &hInstall,
                            APR_WRITE | APR_BINARY | APR_BUFFERED,
                            result_pool);
@@ -2183,12 +2174,8 @@ svn_stream__create_for_install(svn_strea
 
   ib->tmp_path = tmp_path;
 
-#ifdef WIN32
   /* Don't close the file on stream close; flush instead */
   svn_stream_set_close(*install_stream, install_close);
-#else
-  /* ### Install pool cleanup handler for tempfile? */
-#endif
 
   return SVN_NO_ERROR;
 }
@@ -2204,105 +2191,48 @@ 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));
-
-      if (!SetFileInformationByHandle(hFile, FileRenameInfo, rename_info,
-                                      rename_size))
-        {
-          svn_boolean_t retry = FALSE;
-          err = svn_error_wrap_apr(apr_get_os_error(), 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 (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
-            {
-              svn_error_t *err2;
-
-              err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
-                                                            scratch_pool),
-                                                 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;
+      svn_error_t *err2;
 
-              /* 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));
-            }
+      err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                    scratch_pool),
+                                         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));
-                }
-            }
-        }
+      if (err2)
+        return svn_error_trace(svn_error_compose_create(err, err2));
       else
-        err = NULL;
+        svn_error_clear(err);
+
+      err = svn_io__win_rename_open_file(ib->baton_apr.file, ib->tmp_path,
+                                         final_abspath, 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 (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;
+    }
+  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);
+  /* Close temporary file. */
+  SVN_ERR(svn_io_file_close(ib->baton_apr.file, 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 +2250,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);
@@ -2335,19 +2265,12 @@ svn_stream__install_get_info(apr_finfo_t
                              apr_pool_t *scratch_pool)
 {
   struct install_baton_t *ib = install_stream->baton;
-
-#ifdef WIN32
-  /* On WIN32 the file is still open, so we can obtain the information
-     from the handle without race conditions */
   apr_status_t status;
 
   status = apr_file_info_get(finfo, wanted, ib->baton_apr.file);
 
   if (status)
     return svn_error_wrap_apr(status, NULL);
-#else
-  SVN_ERR(svn_io_stat(finfo, ib->tmp_path, wanted, scratch_pool));
-#endif
 
   return SVN_NO_ERROR;
 }
@@ -2359,39 +2282,25 @@ 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);
 #endif
 
+  SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+
   return svn_error_trace(svn_io_remove_file2(ib->tmp_path, FALSE,
                                              scratch_pool));
 }

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/subst.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/subst.c Fri Sep 18 01:38:47 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/patch-exec/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c Fri Sep 18 01:38:47 2015
@@ -46,6 +46,7 @@
 
 #include "private/svn_sqlite.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_utf_private.h"
 
 #include "sysinfo.h"
 #include "svn_private_config.h"
@@ -126,7 +127,7 @@ const apr_array_header_t *
 svn_sysinfo__linked_libs(apr_pool_t *pool)
 {
   svn_version_ext_linked_lib_t *lib;
-  apr_array_header_t *array = apr_array_make(pool, 5, sizeof(*lib));
+  apr_array_header_t *array = apr_array_make(pool, 6, sizeof(*lib));
 
   lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
   lib->name = "APR";
@@ -157,6 +158,11 @@ svn_sysinfo__linked_libs(apr_pool_t *poo
 #endif
 
   lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+  lib->name = "Utf8proc";
+  lib->compiled_version = apr_pstrdup(pool, svn_utf__utf8proc_compiled_version());
+  lib->runtime_version = apr_pstrdup(pool, svn_utf__utf8proc_runtime_version());
+
+  lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
   lib->name = "ZLib";
   lib->compiled_version = apr_pstrdup(pool, svn_zlib__compiled_version());
   lib->runtime_version = apr_pstrdup(pool, svn_zlib__runtime_version());

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/utf.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/utf.c Fri Sep 18 01:38:47 2015
@@ -860,7 +860,6 @@ svn_utf_string_from_utf8(const svn_strin
                          const svn_string_t *src,
                          apr_pool_t *pool)
 {
-  svn_stringbuf_t *dbuf;
   xlate_handle_node_t *node;
   svn_error_t *err;
 
@@ -870,10 +869,15 @@ svn_utf_string_from_utf8(const svn_strin
     {
       err = check_utf8(src->data, src->len, pool);
       if (! err)
-        err = convert_to_stringbuf(node, src->data, src->len,
-                                   &dbuf, pool);
-      if (! err)
-        *dest = svn_stringbuf__morph_into_string(dbuf);
+        {
+          svn_stringbuf_t *dbuf;
+
+          err = convert_to_stringbuf(node, src->data, src->len,
+                                     &dbuf, pool);
+
+          if (! err)
+            *dest = svn_stringbuf__morph_into_string(dbuf);
+        }
     }
   else
     {
@@ -991,7 +995,6 @@ svn_utf_cstring_from_utf8_string(const c
                                  const svn_string_t *src,
                                  apr_pool_t *pool)
 {
-  svn_stringbuf_t *dbuf;
   xlate_handle_node_t *node;
   svn_error_t *err;
 
@@ -1001,10 +1004,14 @@ svn_utf_cstring_from_utf8_string(const c
     {
       err = check_utf8(src->data, src->len, pool);
       if (! err)
-        err = convert_to_stringbuf(node, src->data, src->len,
-                                   &dbuf, pool);
-      if (! err)
-        *dest = dbuf->data;
+        {
+          svn_stringbuf_t *dbuf;
+
+          err = convert_to_stringbuf(node, src->data, src->len,
+                                     &dbuf, pool);
+          if (! err)
+            *dest = dbuf->data;
+        }
     }
   else
     {

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc.c Fri Sep 18 01:38:47 2015
@@ -37,7 +37,19 @@
 #undef strlen
 
 
-const char *svn_utf__utf8proc_version(void)
+
+const char *
+svn_utf__utf8proc_compiled_version(void)
+{
+  static const char utf8proc_version[] =
+                                  APR_STRINGIFY(UTF8PROC_VERSION_MAJOR) "."
+                                  APR_STRINGIFY(UTF8PROC_VERSION_MINOR) "."
+                                  APR_STRINGIFY(UTF8PROC_VERSION_PATCH);
+  return utf8proc_version;
+}
+
+const char *
+svn_utf__utf8proc_runtime_version(void)
 {
   /* Unused static function warning removal hack. */
   SVN_UNUSED(utf8proc_NFD);

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc/utf8proc.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc/utf8proc.h?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc/utf8proc.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/utf8proc/utf8proc.h Fri Sep 18 01:38:47 2015
@@ -51,6 +51,27 @@
 #ifndef UTF8PROC_H
 #define UTF8PROC_H
 
+/** @name API version
+ *  
+ * The utf8proc API version MAJOR.MINOR.PATCH, following
+ * semantic-versioning rules (http://semver.org) based on API
+ * compatibility.
+ *
+ * This is also returned at runtime by @ref utf8proc_version; however, the
+ * runtime version may append a string like "-dev" to the version number
+ * for prerelease versions.
+ *
+ * @note The shared-library version number in the Makefile may be different,
+ *       being based on ABI compatibility rather than API compatibility.
+ */
+/** @{ */
+/** The MAJOR version number (increased when backwards API compatibility is broken). */
+#define UTF8PROC_VERSION_MAJOR 1
+/** The MINOR version number (increased when new functionality is added in a backwards-compatible manner). */
+#define UTF8PROC_VERSION_MINOR 1
+/** The PATCH version (increased for fixes that do not change the API). */
+#define UTF8PROC_VERSION_PATCH 5
+/** @} */
 
 /*
  * Define UTF8PROC_INLINE and include utf8proc.c to embed a static
@@ -70,34 +91,34 @@
 
 #include <stdlib.h>
 #include <sys/types.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <apr.h>
+#ifdef _MSC_VER
+typedef apr_int8_t int8_t;
+typedef apr_uint8_t uint8_t;
+typedef apr_int16_t int16_t;
+typedef apr_uint16_t uint16_t;
+typedef apr_int32_t int32_t;
+typedef apr_uint32_t uint32_t;
+#endif
+#endif
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#elif !defined(__cplusplus)
+typedef uint8_t bool;
+enum { false, true };
+#endif
+
 #ifdef _MSC_VER
-# if _MSC_VER >= 1600
-#   include <stdint.h>
-# else
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-# endif
-# if _MSC_VER >= 1800
-#   include <stdbool.h>
-# else
-typedef unsigned char bool;
-enum {false, true};
-# endif
 # ifdef _WIN64
 #   define ssize_t __int64
 # else
 #   define ssize_t int
 # endif
-#elif defined(HAVE_STDBOOL_H) && defined(HAVE_INTTYPES_H)
-#include <stdbool.h>
-#include <inttypes.h>
-#else
-#include <apr.h>
-typedef uint8_t bool;
-enum {false, true};
 #endif
 #include <limits.h>
 

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/x509parse.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/x509parse.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/x509parse.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/x509parse.c Fri Sep 18 01:38:47 2015
@@ -691,8 +691,7 @@ x509_get_ext(apr_array_header_t *dnsname
           else
             {
               /* We found a dNSName entry */
-              x509_buf *dnsname = apr_palloc(dnsnames->pool,
-                                             sizeof(x509_buf));
+              x509_buf *dnsname = apr_palloc(dnsnames->pool, sizeof(*dnsname));
               dnsname->tag = ASN1_IA5_STRING; /* implicit based on dNSName */
               dnsname->len = len;
               dnsname->p = *p;

Modified: subversion/branches/patch-exec/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/xml.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/xml.c Fri Sep 18 01:38:47 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/patch-exec/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/adm_crawler.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/adm_crawler.c Fri Sep 18 01:38:47 2015
@@ -1016,6 +1016,7 @@ svn_wc__internal_transmit_text_deltas(co
   svn_checksum_t *local_sha1_checksum;  /* calc'd SHA1 of LOCAL_STREAM */
   svn_wc__db_install_data_t *install_data = NULL;
   svn_error_t *err;
+  svn_error_t *err2;
   svn_stream_t *base_stream;  /* delta source */
   svn_stream_t *local_stream;  /* delta target: LOCAL_ABSPATH transl. to NF */
 
@@ -1112,7 +1113,15 @@ svn_wc__internal_transmit_text_deltas(co
                         scratch_pool, scratch_pool);
 
   /* Close the two streams to force writing the digest */
-  err = svn_error_compose_create(err, svn_stream_close(base_stream));
+  err2 = svn_stream_close(base_stream);
+  if (err2)
+    {
+      /* Set verify_checksum to NULL if svn_stream_close() returns error
+         because checksum will be uninitialized in this case. */
+      verify_checksum = NULL;
+      err = svn_error_compose_create(err, err2);
+    }
+
   err = svn_error_compose_create(err, svn_stream_close(local_stream));
 
   /* If we have an error, it may be caused by a corrupt text base,

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/copy.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/copy.c Fri Sep 18 01:38:47 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/patch-exec/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/entries.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/entries.c Fri Sep 18 01:38:47 2015
@@ -1800,7 +1800,7 @@ write_entry(struct write_baton **entry_n
      normal         replace+copied        base       base+work
      add+copied     replace+copied        work       work+work
 
-     although obviously the node is a directory rather then a file.
+     although obviously the node is a directory rather than a file.
      There are then more conversion states where the parent is
      replaced.
 

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/node.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/node.c Fri Sep 18 01:38:47 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/patch-exec/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/update_editor.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/update_editor.c Fri Sep 18 01:38:47 2015
@@ -1863,13 +1863,14 @@ add_directory(const char *path,
   SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
 
   SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
-  SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
-                                  NULL, eb, pb, db->pool, scratch_pool));
   *child_baton = db;
 
   if (db->skip_this)
     return SVN_NO_ERROR;
 
+  SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
+                                  NULL, eb, pb, db->pool, scratch_pool));
+
   SVN_ERR(mark_directory_edited(db, pool));
 
   if (strcmp(eb->target_abspath, db->local_abspath) == 0)
@@ -3066,13 +3067,13 @@ add_file(const char *path,
   SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));
 
   SVN_ERR(make_file_baton(&fb, pb, path, TRUE, pool));
-  SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
-                                  NULL, eb, pb, fb->pool, pool));
   *file_baton = fb;
 
   if (fb->skip_this)
     return SVN_NO_ERROR;
 
+  SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
+                                  NULL, eb, pb, fb->pool, pool));
   SVN_ERR(mark_file_edited(fb, pool));
 
   /* The file_pool can stick around for a *long* time, so we want to
@@ -3551,15 +3552,23 @@ lazy_open_target(svn_stream_t **stream,
                  apr_pool_t *scratch_pool)
 {
   struct handler_baton *hb = baton;
+  svn_wc__db_install_data_t *install_data;
 
+  /* By convention return value is undefined on error, but we rely
+     on HB->INSTALL_DATA value in window_handler() and abort
+     INSTALL_STREAM if is not NULL on error.
+     So we store INSTALL_DATA to local variable first, to leave
+     HB->INSTALL_DATA unchanged on error. */
   SVN_ERR(svn_wc__db_pristine_prepare_install(stream,
-                                              &hb->install_data,
+                                              &install_data,
                                               &hb->new_text_base_sha1_checksum,
                                               NULL,
                                               hb->fb->edit_baton->db,
                                               hb->fb->dir_baton->local_abspath,
                                               result_pool, scratch_pool));
 
+  hb->install_data = install_data;
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/upgrade.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/upgrade.c Fri Sep 18 01:38:47 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/patch-exec/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.c Fri Sep 18 01:38:47 2015
@@ -6698,8 +6698,14 @@ svn_wc__db_op_mark_resolved_internal(svn
 
   conflict_data = svn_sqlite__column_blob(stmt, 2, &conflict_len,
                                           scratch_pool);
-  conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
   SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+  if (!conflict_data)
+    return SVN_NO_ERROR;
+
+  conflicts = svn_skel__parse(conflict_data, conflict_len, scratch_pool);
+  
 
   SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
                                         db, wcroot->abspath,
@@ -6731,8 +6737,6 @@ svn_wc__db_op_mark_resolved_internal(svn
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
-  SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -6799,6 +6803,75 @@ clear_moved_to(svn_wc__db_wcroot_t *wcro
   return SVN_NO_ERROR;
 }
 
+/* Helper function for op_revert_txn. Raises move tree conflicts on
+   descendants to ensure database stability on a non recursive revert
+   of an ancestor that contains a possible move related tree conflict.
+ */
+static svn_error_t *
+revert_maybe_raise_moved_away(svn_wc__db_wcroot_t * wcroot,
+                              svn_wc__db_t *db,
+                              const char *local_relpath,
+                              int op_depth_below,
+                              apr_pool_t *scratch_pool)
+{
+  svn_skel_t *conflict;
+  svn_wc_operation_t operation;
+  svn_boolean_t tree_conflicted;
+  const apr_array_header_t *locations;
+  svn_wc_conflict_reason_t reason;
+  svn_wc_conflict_action_t action;
+
+  SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL, wcroot,
+                                            local_relpath,
+                                            scratch_pool, scratch_pool));
+
+  if (!conflict)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, NULL, NULL,
+                                     &tree_conflicted,
+                                     db, wcroot->abspath,
+                                     conflict,
+                                     scratch_pool, scratch_pool));
+
+  if (!tree_conflicted
+      || (operation != svn_wc_operation_update
+          && operation != svn_wc_operation_switch))
+    {
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
+                                              NULL,
+                                              db, wcroot->abspath,
+                                              conflict,
+                                              scratch_pool,
+                                              scratch_pool));
+
+  if (reason == svn_wc_conflict_reason_deleted
+      || reason == svn_wc_conflict_reason_replaced)
+    {
+      SVN_ERR(svn_wc__db_op_raise_moved_away_internal(
+        wcroot, local_relpath, op_depth_below, db,
+        operation, action,
+        (locations && locations->nelts > 0)
+        ? APR_ARRAY_IDX(locations, 0,
+                        const svn_wc_conflict_version_t *)
+        : NULL,
+        (locations && locations->nelts > 1)
+        ? APR_ARRAY_IDX(locations, 1,
+                        const svn_wc_conflict_version_t *)
+        : NULL,
+        scratch_pool));
+
+      /* Transform the move information into revert information */
+      SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+                                          STMT_MOVE_NOTIFY_TO_REVERT));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Baton for op_revert_txn and op_revert_recursive_txn */
 struct revert_baton_t
 {
@@ -6823,9 +6896,7 @@ op_revert_txn(void *baton,
   svn_boolean_t moved_here;
   int affected_rows;
   const char *moved_to;
-  int op_depth_increased = 0;
   int op_depth_below;
-  svn_skel_t *conflict;
 
   /* ### Similar structure to op_revert_recursive_txn, should they be
          combined? */
@@ -6887,16 +6958,11 @@ op_revert_txn(void *baton,
                                                 local_relpath, op_depth,
                                                 moved_to, NULL, scratch_pool));
     }
-  else
-    {
-      SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL, wcroot,
-                                                local_relpath,
-                                                scratch_pool, scratch_pool));
-    }
-
 
   if (op_depth > 0 && op_depth == relpath_depth(local_relpath))
     {
+      int op_depth_increased;
+
       /* Can't do non-recursive revert if children exist */
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_SELECT_GE_OP_DEPTH_CHILDREN));
@@ -6935,54 +7001,12 @@ op_revert_txn(void *baton,
       /* If this node was moved-here, clear moved-to at the move source. */
       if (moved_here)
         SVN_ERR(clear_moved_to(wcroot, local_relpath, scratch_pool));
-    }
-
-  if (op_depth_increased && conflict)
-    {
-      svn_wc_operation_t operation;
-      svn_boolean_t tree_conflicted;
-      const apr_array_header_t *locations;
-
-      SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, NULL, NULL,
-                                          &tree_conflicted,
-                                          db, wcroot->abspath,
-                                          conflict,
-                                          scratch_pool, scratch_pool));
-      if (tree_conflicted
-          && (operation == svn_wc_operation_update
-              || operation == svn_wc_operation_switch))
-        {
-          svn_wc_conflict_reason_t reason;
-          svn_wc_conflict_action_t action;
-
-          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
-                                                      NULL,
-                                                      db, wcroot->abspath,
-                                                      conflict,
-                                                      scratch_pool,
-                                                      scratch_pool));
-
-          if (reason == svn_wc_conflict_reason_deleted
-              || reason == svn_wc_conflict_reason_replaced)
-            {
-              SVN_ERR(svn_wc__db_op_raise_moved_away_internal(
-                          wcroot, local_relpath, op_depth_below, db,
-                          operation, action,
-                          (locations && locations->nelts > 0)
-                            ? APR_ARRAY_IDX(locations, 0,
-                                            const svn_wc_conflict_version_t *)
-                            : NULL,
-                          (locations && locations->nelts > 1)
-                            ? APR_ARRAY_IDX(locations, 1,
-                                            const svn_wc_conflict_version_t *)
-                            : NULL,
-                          scratch_pool));
 
-              /* Transform the move information into revert information */
-              SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
-                                                  STMT_MOVE_NOTIFY_TO_REVERT));
-            }
-        }
+      /* If the node was moved itself, we don't have interesting moved
+         children (and the move itself was already broken) */
+      if (op_depth_increased && !moved_to)
+        SVN_ERR(revert_maybe_raise_moved_away(wcroot, db, local_relpath,
+                                              op_depth_below, scratch_pool));
     }
 
   if (rvb->clear_changelists)
@@ -8740,6 +8764,45 @@ svn_wc__db_op_delete_many(svn_wc__db_t *
                                            scratch_pool));
 }
 
+/* Helper function for read_info() to provide better diagnostics than just
+   asserting.
+
+   ### BH: Yes this code is ugly, and that is why I only introduce it in
+   ### read_info(). But we really need something to determine the root cause
+   ### of this problem to diagnose why TortoiseSVN users were seeing all those
+   ### assertions.
+
+   Adds an error to the *err chain if invalid values are encountered. In that
+   case the value is set to the first value in the map, assuming that caller
+   will just return the combined error.
+ */
+static int
+column_token_err(svn_error_t **err,
+                 svn_sqlite__stmt_t *stmt,
+                 int column,
+                 const svn_token_map_t *map)
+{
+  svn_error_t *err2;
+  const char *word = svn_sqlite__column_text(stmt, column, NULL);
+  int value;
+
+  /* svn_token__from_word_err() handles NULL for us */
+  err2 = svn_token__from_word_err(&value, map, word);
+
+  if (err2)
+    {
+      *err = svn_error_compose_create(
+                *err,
+                svn_error_createf(
+                    SVN_ERR_WC_CORRUPT, err2,
+                    _("Encountered invalid node state in column %d of "
+                      "info query to working copy database"),
+                    column));
+      value = map[0].val;
+    }
+
+  return value;
+}
 
 /* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
    DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
@@ -8807,11 +8870,11 @@ read_info(svn_wc__db_status_t *status,
       svn_node_kind_t node_kind;
 
       op_depth = svn_sqlite__column_int(stmt_info, 0);
-      node_kind = svn_sqlite__column_token(stmt_info, 4, kind_map);
+      node_kind = column_token_err(&err, stmt_info, 4, kind_map);
 
       if (status)
         {
-          *status = svn_sqlite__column_token(stmt_info, 3, presence_map);
+          *status = column_token_err(&err, stmt_info, 3, presence_map);
 
           if (op_depth != 0) /* WORKING */
             err = svn_error_compose_create(err,
@@ -8863,14 +8926,11 @@ read_info(svn_wc__db_status_t *status,
       if (depth)
         {
           if (node_kind != svn_node_dir)
-            {
-              *depth = svn_depth_unknown;
-            }
+            *depth = svn_depth_unknown;
+          else if (svn_sqlite__column_is_null(stmt_info, 11))
+            *depth = svn_depth_unknown;
           else
-            {
-              *depth = svn_sqlite__column_token_null(stmt_info, 11, depth_map,
-                                                     svn_depth_unknown);
-            }
+            *depth = column_token_err(&err, stmt_info, 11, depth_map);
         }
       if (checksum)
         {
@@ -15117,7 +15177,7 @@ make_copy_txn(svn_wc__db_wcroot_t *wcroo
       const char *name = svn_relpath_skip_ancestor(last_repos_relpath,
                                                    repos_relpath);
 
-      if (strcmp(name, svn_relpath_basename(local_relpath, NULL)) == 0)
+      if (name && strcmp(name, svn_relpath_basename(local_relpath, NULL)) == 0)
         op_depth = last_op_depth;
     }
 

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.h?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/wc_db.h Fri Sep 18 01:38:47 2015
@@ -1644,7 +1644,12 @@ svn_wc__db_op_mark_conflict(svn_wc__db_t
                             apr_pool_t *scratch_pool);
 
 
-/* ### caller maintains ACTUAL, and how the resolution occurred. we're just
+/* Clear all or some of the conflicts stored on LOCAL_ABSPATH, if any.
+
+   Any work items that are necessary as part of resolving this node
+   can be passed in WORK_ITEMS.
+
+### caller maintains ACTUAL, and how the resolution occurred. we're just
    ### recording state.
    ###
    ### I'm not sure that these three values are the best way to do this,

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_pristine.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_pristine.c Fri Sep 18 01:38:47 2015
@@ -333,14 +333,12 @@ pristine_install_txn(svn_sqlite__db_t *s
    * an orphan file and it doesn't matter if we overwrite it.) */
   {
     apr_finfo_t finfo;
-    SVN_ERR(svn_stream__install_get_info(&finfo, install_stream, APR_FINFO_SIZE,
-                                         scratch_pool));
-    SVN_ERR(svn_io_set_file_read_write(pristine_abspath, TRUE, scratch_pool));
+    SVN_ERR(svn_stream__install_get_info(&finfo, install_stream,
+                                         APR_FINFO_SIZE, scratch_pool));
     SVN_ERR(svn_stream__install_stream(install_stream, pristine_abspath,
-                                        TRUE, scratch_pool));
+                                       TRUE, scratch_pool));
 
-    SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                      STMT_INSERT_PRISTINE));
+    SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
     SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
     SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
@@ -383,9 +381,10 @@ svn_wc__db_pristine_prepare_install(svn_
   *install_data = apr_pcalloc(result_pool, sizeof(**install_data));
   (*install_data)->wcroot = wcroot;
 
-  SVN_ERR(svn_stream__create_for_install(stream,
-                                         temp_dir_abspath,
-                                         result_pool, scratch_pool));
+  SVN_ERR_W(svn_stream__create_for_install(stream,
+                                           temp_dir_abspath,
+                                           result_pool, scratch_pool),
+            _("Unable to create pristine install stream"));
 
   (*install_data)->inner_stream = *stream;
 
@@ -569,7 +568,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 +587,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);
@@ -686,42 +687,6 @@ svn_wc__db_pristine_transfer(svn_wc__db_
 
 
 
-/* Remove the file at FILE_ABSPATH in such a way that we could re-create a
- * new file of the same name at any time thereafter.
- *
- * On Windows, the file will not disappear immediately from the directory if
- * it is still being read so the best thing to do is first rename it to a
- * unique name. */
-static svn_error_t *
-remove_file(const char *file_abspath,
-            svn_wc__db_wcroot_t *wcroot,
-            svn_boolean_t ignore_enoent,
-            apr_pool_t *scratch_pool)
-{
-#ifdef WIN32
-  svn_error_t *err;
-  const char *temp_abspath;
-  const char *temp_dir_abspath
-    = pristine_get_tempdir(wcroot, scratch_pool, scratch_pool);
-
-  /* To rename the file to a unique name in the temp dir, first create a
-   * uniquely named file in the temp dir and then overwrite it. */
-  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);
-  if (err && ignore_enoent && APR_STATUS_IS_ENOENT(err->apr_err))
-    svn_error_clear(err);
-  else
-    SVN_ERR(err);
-  file_abspath = temp_abspath;
-#endif
-
-  SVN_ERR(svn_io_remove_file2(file_abspath, ignore_enoent, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
 /* If the pristine text referenced by SHA1_CHECKSUM in WCROOT/SDB, whose path
  * within the pristine store is PRISTINE_ABSPATH, has a reference count of
  * zero, delete it (both the database row and the disk file).
@@ -757,8 +722,8 @@ pristine_remove_if_unreferenced_txn(svn_
       svn_boolean_t ignore_enoent = TRUE;
 #endif
 
-      SVN_ERR(remove_file(pristine_abspath, wcroot, ignore_enoent,
-                          scratch_pool));
+      SVN_ERR(svn_io_remove_file2(pristine_abspath, ignore_enoent,
+                                  scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -944,11 +909,28 @@ svn_wc__db_pristine_check(svn_boolean_t
   {
     const char *pristine_abspath;
     svn_node_kind_t kind_on_disk;
+    svn_error_t *err;
 
     SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
                                sha1_checksum, scratch_pool, scratch_pool));
-    SVN_ERR(svn_io_check_path(pristine_abspath, &kind_on_disk, scratch_pool));
-    if (kind_on_disk != svn_node_file)
+    err = svn_io_check_path(pristine_abspath, &kind_on_disk, scratch_pool);
+#ifdef WIN32
+    if (err && err->apr_err == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED))
+      {
+        svn_error_clear(err);
+        /* Possible race condition: The filename is locked, but there is no
+           file or dir with this name. Let's fall back on checking the DB.
+
+           This case is triggered by the pristine store tests on deleting
+           a file that is still open via another handle, where this other
+           handle has a FILE_SHARE_DELETE share mode.
+         */
+      }
+    else
+#endif
+    if (err)
+      return svn_error_trace(err);
+    else if (kind_on_disk != svn_node_file)
       {
         *present = FALSE;
         return SVN_NO_ERROR;

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_util.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/wc_db_util.c Fri Sep 18 01:38:47 2015
@@ -127,7 +127,7 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
     {
       svn_node_kind_t kind;
 
-      /* A file stat is much cheaper then a failed database open handled
+      /* A file stat is much cheaper than a failed database open handled
          by SQLite. */
       SVN_ERR(svn_io_check_path(sdb_abspath, &kind, scratch_pool));
 

Modified: subversion/branches/patch-exec/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_wc/workqueue.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_wc/workqueue.c Fri Sep 18 01:38:47 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;
     }
 
@@ -418,13 +419,13 @@ run_postupgrade(work_item_baton_t *wqb,
      ### The order may matter for some sufficiently old clients.. but
      ### this code only runs during upgrade after the files had been
      ### removed earlier during the upgrade. */
-  SVN_ERR(svn_io_write_atomic(format_path, SVN_WC__NON_ENTRIES_STRING,
-                              sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
-                              NULL, scratch_pool));
-
-  SVN_ERR(svn_io_write_atomic(entries_path, SVN_WC__NON_ENTRIES_STRING,
-                              sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
-                              NULL, scratch_pool));
+  SVN_ERR(svn_io_write_atomic2(format_path, SVN_WC__NON_ENTRIES_STRING,
+                               sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
+                               NULL, TRUE, scratch_pool));
+
+  SVN_ERR(svn_io_write_atomic2(entries_path, SVN_WC__NON_ENTRIES_STRING,
+                               sizeof(SVN_WC__NON_ENTRIES_STRING) - 1,
+                               NULL, TRUE, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -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/patch-exec/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/mod_dav_svn/activity.c?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/patch-exec/subversion/mod_dav_svn/activity.c Fri Sep 18 01:38:47 2015
@@ -208,9 +208,9 @@ dav_svn__store_activity(const dav_svn_re
   activity_contents = apr_psprintf(repos->pool, "%s\n%s\n",
                                    txn_name, activity_id);
 
-  err = svn_io_write_atomic(final_path,
-                            activity_contents, strlen(activity_contents),
-                            NULL /* copy_perms path */, repos->pool);
+  err = svn_io_write_atomic2(final_path,
+                             activity_contents, strlen(activity_contents),
+                             NULL /* copy_perms path */, TRUE, repos->pool);
   if (err)
     {
       svn_error_t *serr = svn_error_quick_wrap(err,

Modified: subversion/branches/patch-exec/subversion/po/it.po
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/po/it.po?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/po/it.po (original)
+++ subversion/branches/patch-exec/subversion/po/it.po Fri Sep 18 01:38:47 2015
@@ -10134,7 +10134,7 @@ msgstr ""
 #: ../svn/propedit-cmd.c:158
 #, c-format
 msgid "Set new value for property '%s' on revision %ld\n"
-msgstr "Impostazione di un nuovo volore per la proprietà '%s' nella revisione %ld\n"
+msgstr "Impostazione di un nuovo valore per la proprietà '%s' nella revisione %ld\n"
 
 #: ../svn/propedit-cmd.c:164
 #, c-format

Modified: subversion/branches/patch-exec/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svn/cl.h?rev=1703735&r1=1703734&r2=1703735&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svn/cl.h (original)
+++ subversion/branches/patch-exec/subversion/svn/cl.h Fri Sep 18 01:38:47 2015
@@ -402,6 +402,14 @@ svn_cl__conflict_func_interactive(svn_wc
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
 
+
+svn_error_t *
+svn_cl__resolve_conflict(svn_boolean_t *resolved,
+                         svn_client_conflict_t *conflict,
+                         svn_client_ctx_t *ctx,
+                         svn_wc_conflict_choice_t conflict_choice,
+                         apr_pool_t *scratch_pool);
+
 
 /*** Command-line output functions -- printing to the user. ***/
 



Mime
View raw message