1 The WebDatabase implementation in the renderer users a custom vfs to 2 broker file open and other requests. This modifies the built-in vfs 3 implementation to let that code share much of the implementation 4 details. 5 6 diff --git src/os_unix.c src/os_unix.c 7 index 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 } 148 diff --git src/os_win.c src/os_win.c 149 index 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