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. ***/