| The WebDatabase implementation in the renderer users a custom vfs to |
| broker file open and other requests. This modifies the built-in vfs |
| implementation to let that code share much of the implementation |
| details. |
| |
| diff --git src/os_unix.c src/os_unix.c |
| index ef04a72..e5e1509 100644 |
| --- src/os_unix.c |
| +++ src/os_unix.c |
| @@ -3496,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); |
| */ |
| |
| /* |
| +** Initializes a unixFile structure with zeros. |
| +*/ |
| +void initUnixFile(sqlite3_file* file) { |
| + memset(file, 0, sizeof(unixFile)); |
| +} |
| + |
| +/* |
| ** Initialize the contents of the unixFile structure pointed to by pId. |
| */ |
| -static int fillInUnixFile( |
| +int fillInUnixFile( |
| sqlite3_vfs *pVfs, /* Pointer to vfs object */ |
| int h, /* Open file descriptor of file being opened */ |
| int dirfd, /* Directory file descriptor */ |
| @@ -3812,6 +3819,73 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ |
| } |
| |
| /* |
| +** Initializes a unixFile structure with zeros. |
| +*/ |
| +void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { |
| + memset(file, 0, sizeof(unixFile)); |
| +} |
| + |
| +int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, |
| + int fd, |
| + int dirfd, |
| + sqlite3_file* file, |
| + const char* fileName, |
| + int noLock, |
| + int isDelete) { |
| + return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete, 0); |
| +} |
| + |
| +/* |
| +** Search for an unused file descriptor that was opened on the database file. |
| +** If a suitable file descriptor if found, then it is stored in *fd; otherwise, |
| +** *fd is not modified. |
| +** |
| +** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot |
| +** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. |
| +*/ |
| +int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, |
| + const char* fileName, |
| + int flags, |
| + int* fd) { |
| + unixFile* unixSQLite3File = (unixFile*)file; |
| + int fileType = flags & 0xFFFFFF00; |
| + if (fileType == SQLITE_OPEN_MAIN_DB) { |
| + UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); |
| + if (unusedFd) { |
| + *fd = unusedFd->fd; |
| + } else { |
| + unusedFd = sqlite3_malloc(sizeof(*unusedFd)); |
| + if (!unusedFd) { |
| + return SQLITE_NOMEM; |
| + } |
| + } |
| + unixSQLite3File->pUnused = unusedFd; |
| + } |
| + return SQLITE_OK; |
| +} |
| + |
| +/* |
| +** Marks 'fd' as the unused file descriptor for 'pFile'. |
| +*/ |
| +void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, |
| + int fd, |
| + int flags) { |
| + unixFile* unixSQLite3File = (unixFile*)file; |
| + if (unixSQLite3File->pUnused) { |
| + unixSQLite3File->pUnused->fd = fd; |
| + unixSQLite3File->pUnused->flags = flags; |
| + } |
| +} |
| + |
| +/* |
| +** Destroys pFile's field that keeps track of the unused file descriptor. |
| +*/ |
| +void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { |
| + unixFile* unixSQLite3File = (unixFile*)file; |
| + sqlite3_free(unixSQLite3File->pUnused); |
| +} |
| + |
| +/* |
| ** Open the file zPath. |
| ** |
| ** Previously, the SQLite OS layer used three functions in place of this |
| @@ -3893,20 +3967,13 @@ static int unixOpen( |
| || eType==SQLITE_OPEN_TRANSIENT_DB |
| ); |
| |
| - memset(p, 0, sizeof(unixFile)); |
| + chromium_sqlite3_initialize_unix_sqlite3_file(pFile); |
| |
| if( eType==SQLITE_OPEN_MAIN_DB ){ |
| - UnixUnusedFd *pUnused; |
| - pUnused = findReusableFd(zName, flags); |
| - if( pUnused ){ |
| - fd = pUnused->fd; |
| - }else{ |
| - pUnused = sqlite3_malloc(sizeof(*pUnused)); |
| - if( !pUnused ){ |
| - return SQLITE_NOMEM; |
| - } |
| + rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); |
| + if( rc!=SQLITE_OK ){ |
| + return rc; |
| } |
| - p->pUnused = pUnused; |
| }else if( !zName ){ |
| /* If zName is NULL, the upper layer is requesting a temp file. */ |
| assert(isDelete && !isOpenDirectory); |
| @@ -3949,10 +4016,7 @@ static int unixOpen( |
| *pOutFlags = flags; |
| } |
| |
| - if( p->pUnused ){ |
| - p->pUnused->fd = fd; |
| - p->pUnused->flags = flags; |
| - } |
| + chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); |
| |
| if( isDelete ){ |
| #if OS_VXWORKS |
| @@ -4028,7 +4092,7 @@ static int unixOpen( |
| rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); |
| open_finished: |
| if( rc!=SQLITE_OK ){ |
| - sqlite3_free(p->pUnused); |
| + chromium_sqlite3_destroy_reusable_file_handle(pFile); |
| } |
| return rc; |
| } |
| diff --git src/os_win.c src/os_win.c |
| index bc03a4b..06539d7 100644 |
| --- src/os_win.c |
| +++ src/os_win.c |
| @@ -1890,4 +1890,11 @@ int sqlite3_os_end(void){ |
| return SQLITE_OK; |
| } |
| |
| +void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { |
| + winFile* winSQLite3File = (winFile*)file; |
| + memset(file, 0, sizeof(*file)); |
| + winSQLite3File->pMethod = &winIoMethod; |
| + winSQLite3File->h = handle; |
| +} |
| + |
| #endif /* SQLITE_OS_WIN */ |