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]
-----------------------------------------------------------------------------

Reply via email to