[prev in list] [next in list] [prev in thread] [next in thread]
List: subversion-dev
Subject: [PATCH] Proof-of-concept patch for APR 1.2 support on Windows
From: "Sergey A. Lipnevich" <sergey () optimaltec ! com>
Date: 2006-06-28 5:42:08
Message-ID: e7t4ud$u3l$1 () sea ! gmane ! org
[Download RAW message or body]
Hi All,
I was trying to run Subversion 1.3.x (.1 and .2) on Windows with Apache
2.2, and came across a discussion related to handling of APR_INCOMPLETE
error (http://svn.haxx.se/dev/archive-2005-12/0522.shtml) and a related
question of what to do with svn_io_set_file_read_write_carefully
(http://svn.haxx.se/dev/archive-2006-06/0093.shtml). Since my setup
wasn't working, I tried to fix Subversion 1.3.2 according to the ideas
mentioned in these threads, and came up with the following patch
(borrowing an idea from D.J. Heap's patch above for
svn_io_set_file_read_write_carefully). It's not intended for commit as
it is. Please let me know if this is the right approach to take, and
what needs to be done to finish this patch.
I ran the test suite with the following two consistent failures that I
didn't yet investigate:
FAIL: stat_tests.py 8: status for unignored file and directory
Log:
svn: warning: 'newfile' is not under version control
FAIL: stat_tests.py 8: status for unignored file and directory
FAIL: lock_tests.py 19: update handles svn:needs-lock correctly
Log:
svn: '.' is not a working copy
FAIL: lock_tests.py 19: update handles svn:needs-lock correctly
The compiler I use is from VS 2005.
Thanks!
Sergey.
[
Initial support for APR 1.2, boils down to avoiding APR_FINFO_PROT as much
as possible.
* subversion/libsvn_subr/io.c:
use APR_FREADONLY to detect read-only file attribute on Win32;
replace contents of svn_io_set_file_read_write_carefully with
a call to either svn_io_set_file_read_write or
svn_io_set_file_read_only;
don't do anything about "executable" attribute on Win32;
if svn_io_stat gets APR_INCOMPLETE status, disregard it if all but
APR_FINFO_PROT bits are valid;
don't try to handle SGID bit on Win32;
remove pre-APR 0.9.5 code related to SGID.
]
["apr-1.2.diff" (text/x-patch)]
--- subversion/libsvn_subr/io.c 2005-11-16 18:05:43.000000000 -0500
+++ subversion/libsvn_subr/io.c 2006-06-27 17:46:52.131177100 -0400
@@ -47,6 +47,10 @@
#include <apr_strings.h>
#include <apr_portable.h>
#include <apr_md5.h>
+#ifdef WIN32
+/* APR keeps this declaration private, but we need it. */
+#define APR_FREADONLY 0x10000000 /* from apr_arch_file_io.h */
+#endif
#include "svn_types.h"
#include "svn_path.h"
@@ -1052,94 +1056,8 @@ svn_io_set_file_read_write_carefully (co
svn_boolean_t ignore_enoent,
apr_pool_t *pool)
{
- apr_status_t status;
- const char *path_apr;
- apr_finfo_t finfo;
- apr_fileperms_t perms_to_set;
-
- SVN_ERR (svn_path_cstring_from_utf8 (&path_apr, path, pool));
-
- /* Try to change only a minimal amount of the perms first
- by getting the current perms and adding execute bits
- only on where read perms are granted. If this fails
- fall through to the svn_io_set_file* calls. */
- status = apr_stat (&finfo, path_apr, APR_FINFO_PROT, pool);
- if (status)
- {
- if (ignore_enoent && APR_STATUS_IS_ENOENT (status))
- return SVN_NO_ERROR;
- else if (status != APR_ENOTIMPL)
- return svn_error_wrap_apr (status,
- _("Can't change read-write perms of "
- "file '%s'"),
- svn_path_local_style (path, pool));
- }
- else
- {
- perms_to_set = finfo.protection;
- if (enable_write) /* Make read-write. */
- SVN_ERR (get_default_file_perms (path, &perms_to_set,
- pool));
- else /* Make read-only. */
- {
- if (finfo.protection & APR_UREAD)
- perms_to_set &= ~APR_UWRITE;
- if (finfo.protection & APR_GREAD)
- perms_to_set &= ~APR_GWRITE;
- if (finfo.protection & APR_WREAD)
- perms_to_set &= ~APR_WWRITE;
- }
-
- /* If we aren't changing anything then just return, this save
- some system calls and helps with shared working copies */
- if (perms_to_set == finfo.protection)
- return SVN_NO_ERROR;
-
- status = apr_file_perms_set (path_apr, perms_to_set);
- if (status)
- {
- if (APR_STATUS_IS_EPERM (status))
- {
- /* We don't have permissions to change the
- permissions! Try a move, copy, and delete
- workaround to see if we can get the file owned by
- us. If these succeed, try the permissions set
- again.
-
- Note that we only attempt this in the
- stat-available path. This assumes that the
- move-copy workaround will only be helpful on
- platforms that implement apr_stat. */
- SVN_ERR (reown_file (path_apr, pool));
- status = apr_file_perms_set (path_apr, perms_to_set);
- }
-
- if (status)
- {
- if (ignore_enoent && APR_STATUS_IS_ENOENT (status))
- return SVN_NO_ERROR;
- else if (status == APR_ENOTIMPL) /* on win32, for example. */
- {
- if (enable_write)
- SVN_ERR (svn_io_set_file_read_write (path, ignore_enoent,
- pool));
-
- else
- SVN_ERR (svn_io_set_file_read_only (path, ignore_enoent,
- pool));
- }
- else
- return svn_error_wrap_apr
- (status, _("Can't change read-write perms of file '%s'"),
- svn_path_local_style (path, pool));
- }
- else
- return SVN_NO_ERROR;
- }
- else
- return SVN_NO_ERROR;
- }
- return SVN_NO_ERROR;
+ return (enable_write ? svn_io_set_file_read_write : svn_io_set_file_read_only)
+ (path, ignore_enoent, pool);
}
svn_error_t *
@@ -1150,12 +1068,21 @@ svn_io_set_file_executable (const char *
{
apr_status_t status;
const char *path_apr;
+ apr_finfo_t finfo;
SVN_ERR (svn_path_cstring_from_utf8 (&path_apr, path, pool));
+#ifdef WIN32
+ /* No executable attribute is available on Win32. */
+
+ if (ignore_enoent)
+ return SVN_NO_ERROR;
+
+ /* We have to make sure the file exists before leaving. */
+ status = apr_stat(&finfo, path_apr, APR_FINFO_MIN, pool);
+#else /* !WIN32 */
if (executable)
{
- apr_finfo_t finfo;
apr_fileperms_t perms_to_set;
/* Try to change only a minimal amount of the perms first
@@ -1233,7 +1160,8 @@ svn_io_set_file_executable (const char *
0,
APR_FILE_ATTR_EXECUTABLE,
pool);
-
+#endif /* WIN32 */
+
if (status && status != APR_ENOTIMPL)
if (!ignore_enoent || !APR_STATUS_IS_ENOENT(status))
return svn_error_wrap_apr (status,
@@ -2357,8 +2285,20 @@ svn_io_stat (apr_finfo_t *finfo, const c
status = apr_stat (finfo, fname_apr, wanted, pool);
if (status)
- return svn_error_wrap_apr (status, _("Can't stat '%s'"),
- svn_path_local_style (fname, pool));
+ {
+ /* See if the error is due to APR_FINFO_PROT and the rest of the
+ * "wanted" data is valid. */
+ if (APR_STATUS_IS_INCOMPLETE(status) && (wanted & APR_FINFO_PROT))
+ {
+ apr_int32_t invalid = wanted & ~finfo->valid;
+ /* All invalid bits are in APR_FINFO_PROT? */
+ if (!(invalid & ~APR_FINFO_PROT))
+ return SVN_NO_ERROR;
+ }
+
+ return svn_error_wrap_apr (status, _("Can't stat '%s'"),
+ svn_path_local_style (fname, pool));
+ }
return SVN_NO_ERROR;
}
@@ -2385,7 +2325,9 @@ svn_io_file_rename (const char *from_pat
SVN_ERR (svn_path_cstring_from_utf8 (&to_path_apr, to_path, pool));
#ifdef WIN32
- status = apr_stat (&finfo, to_path_apr, APR_FINFO_PROT, pool);
+ /* On Win32, APR_FINFO_MIN is enough to get APR_FREADONLY flag in
+ * finfo.protection. */
+ status = apr_stat (&finfo, to_path_apr, APR_FINFO_MIN, pool);
if (APR_STATUS_IS_ENOENT (status))
{
was_read_only = FALSE;
@@ -2398,8 +2340,7 @@ svn_io_file_rename (const char *from_pat
file permissions. But that shouldn't happen in a Subversion
working copy, and then set_read_write will fail, so the end
result is the same. */
- was_read_only = !(finfo.protection
- & (APR_UWRITE | APR_GWRITE | APR_WWRITE));
+ was_read_only = (finfo.protection & APR_FREADONLY) != 0;
if (was_read_only)
SVN_ERR (svn_io_set_file_read_write (to_path, FALSE, pool));
}
@@ -2529,7 +2470,9 @@ dir_make (const char *path, apr_fileperm
}
#endif
-#if defined(APR_GSETID)
+ /* Don't try to set group ID on Win32. */
+#if defined(APR_GSETID) && !defined(WIN32)
+ /* APR_GSETID appears in APR 0.9.5. */
if (sgid)
{
apr_finfo_t finfo;
@@ -2544,20 +2487,7 @@ dir_make (const char *path, apr_fileperm
* don't support the sgid bit, and that's okay. */
apr_file_perms_set (path_apr, finfo.protection | APR_GSETID);
}
-#elif !defined (WIN32)
- /* APR_GSETID appears in APR 0.9.5, so we need some fallback code
- until Subversion can require 0.9.5. */
- if (sgid)
- {
- struct stat st;
-
- if (stat (path_apr, &st) != 0)
- return svn_error_wrap_apr (APR_FROM_OS_ERROR (errno),
- _("Can't stat new directory '%s'"),
- svn_path_local_style (path, pool));
- chmod (path_apr, (st.st_mode & ~S_IFMT) | S_ISGID);
- }
-#endif
+#endif /* APR_GSETID && !WIN32 */
return SVN_NO_ERROR;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic