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.
--- 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,