changeset 13273:764441ecbf2e

osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile to work around http://support.microsoft.com/kb/899149. Also, Microsoft's documentation of the CreateFile Windows API says (quote): When an application creates a file across a network, it is better to use GENERIC_READ | GENERIC_WRITE for dwDesiredAccess than to use GENERIC_WRITE alone. The resulting code is faster, because the redirector can use the cache manager and send fewer SMBs with more data. This combination also avoids an issue where writing to a file across a network can occasionally return ERROR_ACCESS_DENIED.
author Adrian Buehlmann <adrian@cadifra.com>
date Sat, 15 Jan 2011 23:54:01 +0100
parents 5ccdca7df211
children 57d433f632b7
files mercurial/osutil.c
diffstat 1 files changed, 8 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/osutil.c	Tue Jan 04 06:29:08 2011 +0100
+++ b/mercurial/osutil.c	Sat Jan 15 23:54:01 2011 +0100
@@ -436,7 +436,14 @@
 	}
 	else
 		flags = _O_TEXT;
-	if (plus) {
+	if (m0 == 'r' && !plus) {
+		flags |= _O_RDONLY;
+		access = GENERIC_READ;
+	} else {
+		/*
+		work around http://support.microsoft.com/kb/899149 and
+		set _O_RDWR for 'w' and 'a', even if mode has no '+'
+		*/
 		flags |= _O_RDWR;
 		access = GENERIC_READ | GENERIC_WRITE;
 		fpmode[fppos++] = '+';
@@ -446,25 +453,13 @@
 	switch (m0) {
 	case 'r':
 		creation = OPEN_EXISTING;
-		if (!plus) {
-			flags |= _O_RDONLY;
-			access = GENERIC_READ;
-		}
 		break;
 	case 'w':
 		creation = CREATE_ALWAYS;
-		if (!plus) {
-			access = GENERIC_WRITE;
-			flags |= _O_WRONLY;
-		}
 		break;
 	case 'a':
 		creation = OPEN_ALWAYS;
 		flags |= _O_APPEND;
-		if (!plus) {
-			flags |= _O_WRONLY;
-			access = GENERIC_WRITE;
-		}
 		break;
 	default:
 		PyErr_Format(PyExc_ValueError,