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 */