> From: Branko Cibej [mailto:brane@xbc.nu]
> Sent: Monday, November 03, 2003 8:01 AM
> brane@xbc.nu wrote:
>
> >BUILD: Revision 7611 on i386-unknown-freebsdelf5.0 static
> >
> >
> ...
>
> >Running all tests in merge_tests.py...FAILURE
> >
> >
> (fails everywhere else, too)
>
> I think this is a consequence of the move to use apr_tmp_dir_get in
> revision 7609. Both of my test machines have /tmp and /home on mounted
> on different volumes; now apr_file_renams on Unix just calls rename(2),
> which does not support cross-volume renames and returns EXDEV instead.
>
> I think this is an APR misfeature. The docs on apr_file_rename say that
> "Moving files or directories across devices may not be possible," but I
> think the workaround is so simple that APR should just implement it
> internally The Windows implementation of apr_file_rename does revert to
> copy+delete on cross-volume renames.
>
> Thoughts?
Something like this? (needs win32 counterpart)
Index: file_io/unix/open.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/open.c,v
retrieving revision 1.111
diff -u -r1.111 open.c
--- file_io/unix/open.c 19 Mar 2003 03:45:42 -0000 1.111
+++ file_io/unix/open.c 3 Nov 2003 12:18:47 -0000
@@ -216,7 +216,17 @@
const char *to_path,
apr_pool_t *p)
{
+ apr_status_t rv;
+
if (rename(from_path, to_path) != 0) {
+ if (errno == EXDEV) {
+ rv = apr_file_copy(from_path, to_path, APR_FILE_SOURCE_PERMS, p);
+ if (rv)
+ return rv;
+
+ return apr_file_remove(from_path, p);
+ }
+
return errno;
}
return APR_SUCCESS;
And temporarily in Subversion, until APR with such a fix is released:
* subversion/libsvn_subr/io.c
(file_copy): New helper function.
(svn_io_copy_file): Use helper.
(svn_io_rename_file): If rename isn't possible because it is cross filesystem,
copy and delete instead. Use helper.
Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c (revision 7614)
+++ subversion/libsvn_subr/io.c (working copy)
@@ -329,43 +329,26 @@
^L
/*** Creating, copying and appending files. ***/
-svn_error_t *
-svn_io_copy_file (const char *src,
- const char *dst,
- svn_boolean_t copy_perms,
- apr_pool_t *pool)
+static svn_error_t *
+file_copy (const char *src,
+ const char *src_apr,
+ const char *dst,
+ const char *dst_apr,
+ svn_boolean_t copy_perms,
+ apr_pool_t *pool)
{
- apr_file_t *d;
apr_status_t apr_err;
- const char *src_apr, *dst_tmp_apr;
- const char *dst_tmp;
- SVN_ERR (svn_path_cstring_from_utf8 (&src_apr, src, pool));
-
- /* For atomicity, we translate to a tmp file and then rename the tmp
- file over the real destination. */
-
- SVN_ERR (svn_io_open_unique_file (&d, &dst_tmp, dst, ".tmp", FALSE, pool));
- SVN_ERR (svn_path_cstring_from_utf8 (&dst_tmp_apr, dst_tmp, pool));
-
- apr_err = apr_file_close (d);
+ apr_err = apr_file_copy (src_apr, dst_apr, APR_OS_DEFAULT, pool);
if (apr_err)
- {
- return svn_error_createf
- (apr_err, NULL,
- "svn_io_copy_file: error closing '%s'", dst_tmp);
- }
-
- apr_err = apr_file_copy (src_apr, dst_tmp_apr, APR_OS_DEFAULT, pool);
- if (apr_err)
return svn_error_createf
(apr_err, NULL, "svn_io_copy_file: error copying '%s' to '%s'",
- src, dst_tmp);
+ src, dst);
/* If copying perms, set the perms on dst_tmp now, so they will be
atomically inherited in the upcoming rename. But note that we
had to wait until now to set perms, because if they say
- read-only, then we'd have failed filling dst_tmp's contents. */
+ read-only, then we'd have failed filling dst's contents. */
/* ### FIXME: apr_file_copy with perms may fail on Win32. We need a
platform-specific implementation to get the permissions right. */
@@ -396,7 +379,7 @@
(apr_err, NULL,
"svn_io_copy_file: closing '%s' after reading perms", src);
- apr_err = apr_file_perms_set (dst_tmp_apr, finfo.protection);
+ apr_err = apr_file_perms_set (dst_apr, finfo.protection);
/* We shouldn't be able to get APR_INCOMPLETE or APR_ENOTIMPL
here under normal circumstances, because the perms themselves
@@ -409,11 +392,43 @@
{
return svn_error_createf
(apr_err, NULL,
- "svn_io_copy_file: setting perms on '%s'", dst_tmp);
+ "svn_io_copy_file: setting perms on '%s'", dst);
}
}
#endif /* ! SVN_WIN32 */
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io_copy_file (const char *src,
+ const char *dst,
+ svn_boolean_t copy_perms,
+ apr_pool_t *pool)
+{
+ apr_file_t *d;
+ apr_status_t apr_err;
+ const char *src_apr, *dst_tmp_apr;
+ const char *dst_tmp;
+
+ SVN_ERR (svn_path_cstring_from_utf8 (&src_apr, src, pool));
+
+ /* For atomicity, we translate to a tmp file and then rename the tmp
+ file over the real destination. */
+
+ SVN_ERR (svn_io_open_unique_file (&d, &dst_tmp, dst, ".tmp", FALSE, pool));
+ SVN_ERR (svn_path_cstring_from_utf8 (&dst_tmp_apr, dst_tmp, pool));
+
+ apr_err = apr_file_close (d);
+ if (apr_err)
+ {
+ return svn_error_createf
+ (apr_err, NULL,
+ "svn_io_copy_file: error closing '%s'", dst_tmp);
+ }
+
+ SVN_ERR (file_copy (src, src_apr, dst_tmp, dst_tmp_apr, copy_perms, pool));
+
return svn_io_file_rename (dst_tmp, dst, pool);
}
@@ -1747,6 +1762,13 @@
status = apr_file_rename (from_path_apr, to_path_apr, pool);
+ if (APR_STATUS_IS_EXDEV(status))
+ {
+ SVN_ERR (file_copy (from_path, from_path_apr, to_path, to_path_apr, TRUE, pool));
+ SVN_ERR (svn_io_remove_file (from_path, pool));
+ return SVN_NO_ERROR;
+ }
+
#ifdef SVN_WIN32
/*
Windows is 'aided' by a number of types of applications that
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Nov 3 13:24:47 2003