I am continuing to try to get the complete test suite to run on Windows.
I have another strange error in test misc7-17.1:
misc7-17.1...
Error: couldn't open "test.db-journal": permission denied
The TCL code for this test is:
#----------------------------------------------------------------------
# Test the situation where a hot-journal is discovered but write-access
# to it is denied. This should return SQLITE_BUSY.
#
do_test misc7-17.1 {
execsql {
BEGIN;
DELETE FROM t3 WHERE (oid%3)==0;
}
copy_file test.db bak.db
copy_file test.db-journal bak.db-journal
execsql {
COMMIT;
}
db close
copy_file bak.db test.db
copy_file bak.db-journal test.db-journal
sqlite3 db test.db
if {$::tcl_platform(platform) == "windows"} {
file attributes test.db-journal -permissions -readonly
} else {
file attributes test.db-journal -permissions r--------
}
catchsql {
SELECT count(*) FROM t3;
}
} {1 {database is locked}}
This error is being generated by the second copy_file command. If I
abort the script using an exit command after the first copy_file I can
see that both files (db and journal) exist. I can copy them manually etc.
I suspect the problem is that the journal file is being opened for
reading and writing but not shared for reading or writing so that the
copy_file command can't read the journal while sqlite still has it open.
The script can't close that database until after copy is made (to create
the hot journal later), so we have a catch 22 situation.
This seems to require a change to the sqlite source since the journal
file is opened with exclusive access. This test works on unix since
sqlite uses default permissions of 644 even for exclusive access which
allows others to read the file. So perhaps the function
sqlite3WinOpenExclusive in os_win.c should change its CreateFile call to
share for reading. Change line 793 and 808 from
h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
fileflags,
NULL
to
h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
fileflags,
NULL
As an aside, while we are changing things it seems to me that
sqlite3WinOpenReadOnly should also use FILE_SHARE_READ.
This means that exclusive access isn't really exclusive, but it's not
currently that way under unix now. Would this change cause problems for
anybody?
I can't think of any way to test a hot journal unless we can make a copy
of a journal as this test is trying to do. Does anybody have another idea?
Upon further investigation I discovered that this does not work either.
I believe that the copy_file command is trying to open the file for
reading and probably specifies FILE_SHARE_READ only (which is to be
expected). It turns out that Windows will not allow this mode to open a
file that another process, sqlite in this case, has open for writing,
which is how sqlite opens the journal file. The copy command won't be
able to open the file as long as sqlite has the file open for writing.
So we have have to do something else. We could create a custom copy
command that opens the with the FILE_SHARE_WRITE sharing mode. This
would allow the custom command to open the file even thought sqlite has
it open for writing.
sqlite uses GENERIC_READ | GENERIC_WRITE and FILE_SHARE_READ
custom copy uses GENERIC_READ and FILE_SHARE_READ | FILE_SHARE_WRITE
In this case only, Windows will allow the custom copy command to open
the journal since it has said it's OK if someone else has the file open
for writing.
So, does anyone know how to issue a low level windows CreateFile API
call from within TCL, or does this command have to be written in C?
Dennis Cote
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------