Append-mode I/O on Windows and process I/O redirection
Martin Buchholz
martinrb at google.com
Sat Jun 7 06:09:33 UTC 2008
Sun folk, please add this commentary to Bugtraq:
I made append mode on windows atomic by calling CreateFile
with FILE_APPEND_DATA but not FILE_WRITE_DATA
6631352 File{OutputStream,Writer} should implement atomic append mode
using FILE_APPEND_DATA
winFileHandleOpen(JNIEnv *env, jstring path, int flags)
{
/* To implement O_APPEND, we use the strategy from
http://msdn2.microsoft.com/en-us/library/aa363858.aspx
"You can get atomic append by opening a file with
FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access.
If you do this then all writes will ignore the current file
pointer and be done at the end-of file." */
This was used to implement process I/O redirection in append mode
4960438 (process) Need IO redirection API for subprocesses
Unfortunately, the removal of FILE_WRITE_DATA permissions
causes file locking and file truncation to fail.
6709457 (fc) lock/tryLock() throws IOException "Access is denied" when
file opened for writing open [win]
What to do? I'll only play consultant, not engineer, on this myself,
because I no longer have access to a Windows system,
and for testing this may require access to several.
I suppose we'll sadly have to back out all the changes for 6631352.
Another strategy is to open the file in FILE_WRITE_DATA mode as before,
but to make each individual write work in append mode.
Another look at the msdn documentation suggests that this is possible
(did I miss this when I explored the docs a year ago?)
http://msdn.microsoft.com/en-us/library/aa365747(VS.85).aspx
Use WriteFile with a non-null OVERLAPPED, with Offset = OffsetHigh = 0xffffffff
"To write to the end of file, specify both the Offset and OffsetHigh
members of the OVERLAPPED structure as 0xFFFFFFFF. This is
functionally equivalent to previously calling the CreateFile function
to open hFile using FILE_APPEND_DATA access."
The above has a good chance of properly fixing 6631352.
What should the process code do, given that it doesn't control
how the subprocess will perform individual writes?
Well, we could simply set the file position at the end of the file,
which is "pretty good", but not quite right (concurrent writes
may cause one of the writes to be lost). Perhaps the ReOpenFile function
http://msdn.microsoft.com/en-us/library/aa365497(VS.85).aspx
can be used to create a new HANDLE with FILE_APPEND_DATA and
without FILE_WRITE_DATA and passing that to the subprocess.
Will someone then in turn complain
that the child process can't truncate its standard output??!
Hmmm....
Good luck!
Martin
More information about the core-libs-dev
mailing list