1The WebDatabase implementation in the renderer users a custom vfs to 2broker file open and other requests. This modifies the built-in vfs 3implementation to let that code share much of the implementation 4details. 5 6diff --git src/os_unix.c src/os_unix.c 7index ef04a72..e5e1509 100644 8--- src/os_unix.c 9+++ src/os_unix.c 10@@ -3496,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); 11 */ 12 13 /* 14+** Initializes a unixFile structure with zeros. 15+*/ 16+void initUnixFile(sqlite3_file* file) { 17+ memset(file, 0, sizeof(unixFile)); 18+} 19+ 20+/* 21 ** Initialize the contents of the unixFile structure pointed to by pId. 22 */ 23-static int fillInUnixFile( 24+int fillInUnixFile( 25 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 26 int h, /* Open file descriptor of file being opened */ 27 int dirfd, /* Directory file descriptor */ 28@@ -3812,6 +3819,73 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ 29 } 30 31 /* 32+** Initializes a unixFile structure with zeros. 33+*/ 34+void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { 35+ memset(file, 0, sizeof(unixFile)); 36+} 37+ 38+int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, 39+ int fd, 40+ int dirfd, 41+ sqlite3_file* file, 42+ const char* fileName, 43+ int noLock, 44+ int isDelete) { 45+ return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete, 0); 46+} 47+ 48+/* 49+** Search for an unused file descriptor that was opened on the database file. 50+** If a suitable file descriptor if found, then it is stored in *fd; otherwise, 51+** *fd is not modified. 52+** 53+** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot 54+** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. 55+*/ 56+int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, 57+ const char* fileName, 58+ int flags, 59+ int* fd) { 60+ unixFile* unixSQLite3File = (unixFile*)file; 61+ int fileType = flags & 0xFFFFFF00; 62+ if (fileType == SQLITE_OPEN_MAIN_DB) { 63+ UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); 64+ if (unusedFd) { 65+ *fd = unusedFd->fd; 66+ } else { 67+ unusedFd = sqlite3_malloc(sizeof(*unusedFd)); 68+ if (!unusedFd) { 69+ return SQLITE_NOMEM; 70+ } 71+ } 72+ unixSQLite3File->pUnused = unusedFd; 73+ } 74+ return SQLITE_OK; 75+} 76+ 77+/* 78+** Marks 'fd' as the unused file descriptor for 'pFile'. 79+*/ 80+void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, 81+ int fd, 82+ int flags) { 83+ unixFile* unixSQLite3File = (unixFile*)file; 84+ if (unixSQLite3File->pUnused) { 85+ unixSQLite3File->pUnused->fd = fd; 86+ unixSQLite3File->pUnused->flags = flags; 87+ } 88+} 89+ 90+/* 91+** Destroys pFile's field that keeps track of the unused file descriptor. 92+*/ 93+void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { 94+ unixFile* unixSQLite3File = (unixFile*)file; 95+ sqlite3_free(unixSQLite3File->pUnused); 96+} 97+ 98+/* 99 ** Open the file zPath. 100 ** 101 ** Previously, the SQLite OS layer used three functions in place of this 102@@ -3893,20 +3967,13 @@ static int unixOpen( 103 || eType==SQLITE_OPEN_TRANSIENT_DB 104 ); 105 106- memset(p, 0, sizeof(unixFile)); 107+ chromium_sqlite3_initialize_unix_sqlite3_file(pFile); 108 109 if( eType==SQLITE_OPEN_MAIN_DB ){ 110- UnixUnusedFd *pUnused; 111- pUnused = findReusableFd(zName, flags); 112- if( pUnused ){ 113- fd = pUnused->fd; 114- }else{ 115- pUnused = sqlite3_malloc(sizeof(*pUnused)); 116- if( !pUnused ){ 117- return SQLITE_NOMEM; 118- } 119+ rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); 120+ if( rc!=SQLITE_OK ){ 121+ return rc; 122 } 123- p->pUnused = pUnused; 124 }else if( !zName ){ 125 /* If zName is NULL, the upper layer is requesting a temp file. */ 126 assert(isDelete && !isOpenDirectory); 127@@ -3949,10 +4016,7 @@ static int unixOpen( 128 *pOutFlags = flags; 129 } 130 131- if( p->pUnused ){ 132- p->pUnused->fd = fd; 133- p->pUnused->flags = flags; 134- } 135+ chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); 136 137 if( isDelete ){ 138 #if OS_VXWORKS 139@@ -4028,7 +4092,7 @@ static int unixOpen( 140 rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); 141 open_finished: 142 if( rc!=SQLITE_OK ){ 143- sqlite3_free(p->pUnused); 144+ chromium_sqlite3_destroy_reusable_file_handle(pFile); 145 } 146 return rc; 147 } 148diff --git src/os_win.c src/os_win.c 149index bc03a4b..06539d7 100644 150--- src/os_win.c 151+++ src/os_win.c 152@@ -1890,4 +1890,11 @@ int sqlite3_os_end(void){ 153 return SQLITE_OK; 154 } 155 156+void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { 157+ winFile* winSQLite3File = (winFile*)file; 158+ memset(file, 0, sizeof(*file)); 159+ winSQLite3File->pMethod = &winIoMethod; 160+ winSQLite3File->h = handle; 161+} 162+ 163 #endif /* SQLITE_OS_WIN */ 164