Robert Simpson wrote:

What I say below is in no means trying to be rude or show you (or anyone) up. I have no idea what your experiences are with Windows or Unix or Unix-Like operating systems. I'm probably stating things that almost all of us already know. :)


So? If you open the file, that's 1 handle open. Someone unlinks it, but a handle is still open. sqlite3_open() then opens the file, that's 2 handles. You then close your handle and there's still 1 handle open until sqlite is done with it. I'm not a *nix programmer, so maybe I am missing something obvious.

In Unix you can delete an open file. The file is simply removed from the directory. Properly, this is called "unlinking". The actual syscall is called "unlink". When a file has 0 hard-links, and no process has it open, it is removed from the file system and the space reclaimed. Normal files have only one "hard-link". The 'hard-link' count is stored in the file's inode in a traditional unix file system. (I know about UFS and EXT2/EXT3. I have no idea what JFS, XFS, ReiserFS, et al do.)

In Windows you can not delete an open file, even if your process has the file open for writing. The text at the bottom was lifted directly from the February 2003 Win32 platform SDK on the "DeleteFile" API call [1] about 15 seconds ago. Note that the rules I'm discussing are for NT kernel based versions of Windows.


#2.. Would that work if you opened the file exclusively? If you don't open it exclusively, theoretically someone else could open it too.


On Windows, sqlite3_open() calls the CreateFile() API with the OPEN_ALWAYS flag, which means if the file doesn't exist, then create it -- in either case, always open the file. To atomically create a file and make sqlite3 open it (at least in Windows) you would call CreateFile() with the CREATE_NEW flag, which will atomically fail if the file already exists. If it creates a new file however, you can then pass the filename to sqlite3_open() and then subsequently close your handle.


I know :) I'm simply saying that I wish that sqlite3_open() took some flags and "did the right thing" based on the underling OS. Those flags would be specific to sqlite and translated into the native OS flags deep inside to "os_***.c" wrappers.

#define SQLITE3_OPEN_DEFAULT    0
#define SQLITE3_OPEN_EXISTING    1
#define SQLITE3_OPEN_TRUNCATE   2
...etc...

So my question is simply, "Why was sqlite3 designed to behave the way it does?" (That is, the caller has no control over the underlying "open" operation.

Another option would be to create a version of "sqlite3_open" that takes an existing OS handle and uses the handle as-is (I suppose that you'd still have to pass in a filename so that the journal, vacuum, (and other?), files could be created).

Now, I've not had a need for any of this. I did notice this a long time ago though. If I really needed this, I'd code it myself. I've already hacked away on the sqlite code base to make it do some things that I want it to do.

[1]

If an application attempts to delete a file that does not exist, the *DeleteFile* function fails. If the file is a read-only file, the function fails with ERROR_ACCESS_DENIED. To delete a read-only file, you must first remove the read-only attribute.

To delete or rename a file, you must have either delete permission on the file or delete child permission in the parent directory. If you set up a directory with all access except delete and delete child and the ACLs of new files are inherited, then you should be able to create a file without being able to delete it. However, you can then create a file get all the access you request on the handle returned to you at the time you create the file. If you requested delete permission at the time you created the file, you could delete or rename the file with that handle but not with any other. For more information, see File Security and Access Rights <file_security_and_access_rights.htm>.

The *DeleteFile* function fails if an application attempts to delete a file that is open for normal I/O or as a memory-mapped file.

*Windows Me/98/95: *The *DeleteFile* function deletes a file even if it is open for normal I/O or as a memory-mapped file. To prevent loss of data, close files before attempting to delete them.

To recursively delete the files in a directory, use the *SHFileOperation* function.

To close an open file, use the *CloseHandle* function.

The *DeleteFile* function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to *CreateFile* <createfile.htm> to open the file fail with ERROR_ACCESS_DENIED.

*Windows Me/98/95: **DeleteFileW* is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.



Reply via email to