/ Hex Artifact Content
Login

Artifact 15bddcddf6b1bf6360130e09aee950f5f563d5f3:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 4d 61 79 20 30  /*.** 2010 May 0
0010: 35 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  5.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2f 0a 23 69 66 20  *****.**.*/.#if 
0180: 53 51 4c 49 54 45 5f 54 45 53 54 20 20 20 20 20  SQLITE_TEST     
0190: 20 20 20 20 20 2f 2a 20 54 68 69 73 20 66 69 6c       /* This fil
01a0: 65 20 69 73 20 75 73 65 64 20 66 6f 72 20 74 65  e is used for te
01b0: 73 74 69 6e 67 20 6f 6e 6c 79 20 2a 2f 0a 0a 23  sting only */..#
01c0: 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33  include "sqlite3
01d0: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 73 71  .h".#include "sq
01e0: 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65  liteInt.h"..type
01f0: 64 65 66 20 73 74 72 75 63 74 20 54 65 73 74 76  def struct Testv
0200: 66 73 20 54 65 73 74 76 66 73 3b 0a 74 79 70 65  fs Testvfs;.type
0210: 64 65 66 20 73 74 72 75 63 74 20 54 65 73 74 76  def struct Testv
0220: 66 73 53 68 6d 20 54 65 73 74 76 66 73 53 68 6d  fsShm TestvfsShm
0230: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
0240: 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20 54   TestvfsBuffer T
0250: 65 73 74 76 66 73 42 75 66 66 65 72 3b 0a 74 79  estvfsBuffer;.ty
0260: 70 65 64 65 66 20 73 74 72 75 63 74 20 54 65 73  pedef struct Tes
0270: 74 76 66 73 46 69 6c 65 20 54 65 73 74 76 66 73  tvfsFile Testvfs
0280: 46 69 6c 65 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  File;../*.** An 
0290: 6f 70 65 6e 20 66 69 6c 65 20 68 61 6e 64 6c 65  open file handle
02a0: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73 74  ..*/.struct Test
02b0: 76 66 73 46 69 6c 65 20 7b 0a 20 20 73 71 6c 69  vfsFile {.  sqli
02c0: 74 65 33 5f 66 69 6c 65 20 62 61 73 65 3b 20 20  te3_file base;  
02d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
02e0: 61 73 65 20 63 6c 61 73 73 2e 20 20 4d 75 73 74  ase class.  Must
02f0: 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20 20 73   be first */.  s
0300: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
0310: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
0320: 2a 20 54 68 65 20 56 46 53 20 2a 2f 0a 20 20 63  * The VFS */.  c
0330: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65  onst char *zFile
0340: 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 2f  name;          /
0350: 2a 20 46 69 6c 65 6e 61 6d 65 20 61 73 20 70 61  * Filename as pa
0360: 73 73 65 64 20 74 6f 20 78 4f 70 65 6e 28 29 20  ssed to xOpen() 
0370: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
0380: 65 20 2a 70 52 65 61 6c 3b 20 20 20 20 20 20 20  e *pReal;       
0390: 20 20 20 20 20 2f 2a 20 54 68 65 20 72 65 61 6c       /* The real
03a0: 2c 20 75 6e 64 65 72 6c 79 69 6e 67 20 66 69 6c  , underlying fil
03b0: 65 20 64 65 73 63 72 69 70 74 6f 72 20 2a 2f 0a  e descriptor */.
03c0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 68 6d 49    Tcl_Obj *pShmI
03d0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
03e0: 20 20 2f 2a 20 53 68 61 72 65 64 20 6d 65 6d 6f    /* Shared memo
03f0: 72 79 20 69 64 20 66 6f 72 20 54 63 6c 20 63 61  ry id for Tcl ca
0400: 6c 6c 62 61 63 6b 73 20 2a 2f 0a 0a 20 20 54 65  llbacks */..  Te
0410: 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 53 68  stvfsBuffer *pSh
0420: 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  m;            /*
0430: 20 53 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 62   Shared memory b
0440: 75 66 66 65 72 20 2a 2f 0a 20 20 75 33 32 20 65  uffer */.  u32 e
0450: 78 63 6c 6c 6f 63 6b 3b 20 20 20 20 20 20 20 20  xcllock;        
0460: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
0470: 73 6b 20 6f 66 20 65 78 63 6c 75 73 69 76 65 20  sk of exclusive 
0480: 6c 6f 63 6b 73 20 2a 2f 0a 20 20 75 33 32 20 73  locks */.  u32 s
0490: 68 61 72 65 64 6c 6f 63 6b 3b 20 20 20 20 20 20  haredlock;      
04a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
04b0: 73 6b 20 6f 66 20 73 68 61 72 65 64 20 6c 6f 63  sk of shared loc
04c0: 6b 73 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 46  ks */.  TestvfsF
04d0: 69 6c 65 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  ile *pNext;     
04e0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
04f0: 68 61 6e 64 6c 65 20 6f 70 65 6e 65 64 20 6f 6e  handle opened on
0500: 20 74 68 65 20 73 61 6d 65 20 66 69 6c 65 20 2a   the same file *
0510: 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  /.};.../*.** An 
0520: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
0530: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 61 6c   structure is al
0540: 6c 6f 63 61 74 65 64 20 66 6f 72 20 65 61 63 68  located for each
0550: 20 56 46 53 20 63 72 65 61 74 65 64 2e 20 54 68   VFS created. Th
0560: 65 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 76 66 73  e.** sqlite3_vfs
0570: 2e 70 41 70 70 44 61 74 61 20 66 69 65 6c 64 20  .pAppData field 
0580: 6f 66 20 74 68 65 20 56 46 53 20 73 74 72 75 63  of the VFS struc
0590: 74 75 72 65 20 72 65 67 69 73 74 65 72 65 64 20  ture registered 
05a0: 77 69 74 68 20 53 51 4c 69 74 65 0a 2a 2a 20 69  with SQLite.** i
05b0: 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74  s set to point t
05c0: 6f 20 69 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  o it..*/.struct 
05d0: 54 65 73 74 76 66 73 20 7b 0a 20 20 63 68 61 72  Testvfs {.  char
05e0: 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20   *zName;        
05f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0600: 61 6d 65 20 6f 66 20 74 68 69 73 20 56 46 53 20  ame of this VFS 
0610: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  */.  sqlite3_vfs
0620: 20 2a 70 50 61 72 65 6e 74 3b 20 20 20 20 20 20   *pParent;      
0630: 20 20 20 20 20 2f 2a 20 54 68 65 20 56 46 53 20       /* The VFS 
0640: 74 6f 20 75 73 65 20 66 6f 72 20 66 69 6c 65 20  to use for file 
0650: 49 4f 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  IO */.  sqlite3_
0660: 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20  vfs *pVfs;      
0670: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74          /* The t
0680: 65 73 74 76 66 73 20 72 65 67 69 73 74 65 72 65  estvfs registere
0690: 64 20 77 69 74 68 20 53 51 4c 69 74 65 20 2a 2f  d with SQLite */
06a0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
06b0: 6e 74 65 72 70 3b 20 20 20 20 20 20 20 20 20 20  nterp;          
06c0: 20 20 20 2f 2a 20 49 6e 74 65 72 70 72 65 74 65     /* Interprete
06d0: 72 20 74 6f 20 72 75 6e 20 73 63 72 69 70 74 20  r to run script 
06e0: 69 6e 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  in */.  Tcl_Obj 
06f0: 2a 70 53 63 72 69 70 74 3b 20 20 20 20 20 20 20  *pScript;       
0700: 20 20 20 20 20 20 20 20 2f 2a 20 53 63 72 69 70          /* Scrip
0710: 74 20 74 6f 20 65 78 65 63 75 74 65 20 2a 2f 0a  t to execute */.
0720: 20 20 69 6e 74 20 6e 53 63 72 69 70 74 3b 20 20    int nScript;  
0730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0740: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65    /* Number of e
0750: 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 72 61 79  lements in array
0760: 20 61 70 53 63 72 69 70 74 20 2a 2f 0a 20 20 54   apScript */.  T
0770: 63 6c 5f 4f 62 6a 20 2a 2a 61 70 53 63 72 69 70  cl_Obj **apScrip
0780: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t;             /
0790: 2a 20 41 72 72 61 79 20 76 65 72 73 69 6f 6e 20  * Array version 
07a0: 6f 66 20 70 53 63 72 69 70 74 20 2a 2f 0a 20 20  of pScript */.  
07b0: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70  TestvfsBuffer *p
07c0: 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20 20  Buffer;         
07d0: 2f 2a 20 4c 69 73 74 20 6f 66 20 73 68 61 72 65  /* List of share
07e0: 64 20 62 75 66 66 65 72 73 20 2a 2f 0a 20 20 69  d buffers */.  i
07f0: 6e 74 20 69 73 4e 6f 73 68 6d 3b 0a 0a 20 20 69  nt isNoshm;..  i
0800: 6e 74 20 6d 61 73 6b 3b 0a 20 20 69 6e 74 20 69  nt mask;.  int i
0810: 49 6f 65 72 72 43 6e 74 3b 0a 20 20 69 6e 74 20  IoerrCnt;.  int 
0820: 69 6f 65 72 72 3b 0a 20 20 69 6e 74 20 6e 49 6f  ioerr;.  int nIo
0830: 65 72 72 46 61 69 6c 3b 0a 7d 3b 0a 0a 2f 2a 0a  errFail;.};../*.
0840: 2a 2a 20 54 68 65 20 54 65 73 74 76 66 73 2e 6d  ** The Testvfs.m
0850: 61 73 6b 20 76 61 72 69 61 62 6c 65 20 69 73 20  ask variable is 
0860: 73 65 74 20 74 6f 20 61 20 63 6f 6d 62 69 6e 61  set to a combina
0870: 74 69 6f 6e 20 6f 66 20 74 68 65 20 66 6f 6c 6c  tion of the foll
0880: 6f 77 69 6e 67 2e 0a 2a 2a 20 49 66 20 61 20 62  owing..** If a b
0890: 69 74 20 69 73 20 63 6c 65 61 72 20 69 6e 20 54  it is clear in T
08a0: 65 73 74 76 66 73 2e 6d 61 73 6b 2c 20 74 68 65  estvfs.mask, the
08b0: 6e 20 63 61 6c 6c 73 20 6d 61 64 65 20 62 79 20  n calls made by 
08c0: 53 51 4c 69 74 65 20 74 6f 20 74 68 65 20 0a 2a  SQLite to the .*
08d0: 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  * corresponding 
08e0: 56 46 53 20 6d 65 74 68 6f 64 20 69 73 20 69 67  VFS method is ig
08f0: 6e 6f 72 65 64 20 66 6f 72 20 70 75 72 70 6f 73  nored for purpos
0900: 65 73 20 6f 66 3a 0a 2a 2a 0a 2a 2a 20 20 20 2b  es of:.**.**   +
0910: 20 53 69 6d 75 6c 61 74 69 6e 67 20 49 4f 20 65   Simulating IO e
0920: 72 72 6f 72 73 2c 20 61 6e 64 0a 2a 2a 20 20 20  rrors, and.**   
0930: 2b 20 49 6e 76 6f 6b 69 6e 67 20 74 68 65 20 54  + Invoking the T
0940: 63 6c 20 63 61 6c 6c 62 61 63 6b 20 73 63 72 69  cl callback scri
0950: 70 74 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 54  pt..*/.#define T
0960: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
0970: 41 53 4b 20 20 20 20 30 78 30 30 30 30 30 30 30  ASK    0x0000000
0980: 31 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  1.#define TESTVF
0990: 53 5f 53 48 4d 53 49 5a 45 5f 4d 41 53 4b 20 20  S_SHMSIZE_MASK  
09a0: 20 20 30 78 30 30 30 30 30 30 30 32 0a 23 64 65    0x00000002.#de
09b0: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d  fine TESTVFS_SHM
09c0: 47 45 54 5f 4d 41 53 4b 20 20 20 20 20 30 78 30  GET_MASK     0x0
09d0: 30 30 30 30 30 30 34 0a 23 64 65 66 69 6e 65 20  0000004.#define 
09e0: 54 45 53 54 56 46 53 5f 53 48 4d 52 45 4c 45 41  TESTVFS_SHMRELEA
09f0: 53 45 5f 4d 41 53 4b 20 30 78 30 30 30 30 30 30  SE_MASK 0x000000
0a00: 30 38 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  08.#define TESTV
0a10: 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20  FS_SHMLOCK_MASK 
0a20: 20 20 20 30 78 30 30 30 30 30 30 31 30 0a 23 64     0x00000010.#d
0a30: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48  efine TESTVFS_SH
0a40: 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 30 78  MBARRIER_MASK 0x
0a50: 30 30 30 30 30 30 32 30 0a 23 64 65 66 69 6e 65  00000020.#define
0a60: 20 54 45 53 54 56 46 53 5f 53 48 4d 43 4c 4f 53   TESTVFS_SHMCLOS
0a70: 45 5f 4d 41 53 4b 20 20 20 30 78 30 30 30 30 30  E_MASK   0x00000
0a80: 30 34 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  040.#define TEST
0a90: 56 46 53 5f 53 48 4d 50 41 47 45 5f 4d 41 53 4b  VFS_SHMPAGE_MASK
0aa0: 20 20 20 20 30 78 30 30 30 30 30 30 38 30 0a 0a      0x00000080..
0ab0: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
0ac0: 4f 50 45 4e 5f 4d 41 53 4b 20 20 20 20 20 20 20  OPEN_MASK       
0ad0: 30 78 30 30 30 30 30 31 30 30 0a 23 64 65 66 69  0x00000100.#defi
0ae0: 6e 65 20 54 45 53 54 56 46 53 5f 53 59 4e 43 5f  ne TESTVFS_SYNC_
0af0: 4d 41 53 4b 20 20 20 20 20 20 20 30 78 30 30 30  MASK       0x000
0b00: 30 30 32 30 30 0a 23 64 65 66 69 6e 65 20 54 45  00200.#define TE
0b10: 53 54 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20 20  STVFS_ALL_MASK  
0b20: 20 20 20 20 20 20 30 78 30 30 30 30 30 33 46 46        0x000003FF
0b30: 0a 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  ...#define TESTV
0b40: 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 32 35 36  FS_MAX_PAGES 256
0b50: 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72 65 64  ../*.** A shared
0b60: 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 20  -memory buffer. 
0b70: 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f 66 20  There is one of 
0b80: 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20 66 6f  these objects fo
0b90: 72 20 65 61 63 68 20 73 68 61 72 65 64 0a 2a 2a  r each shared.**
0ba0: 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20 6f   memory region o
0bb0: 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74 73  pened by clients
0bc0: 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e 74 73  . If two clients
0bd0: 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65 20 66   open the same f
0be0: 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20 61 72  ile,.** there ar
0bf0: 65 20 74 77 6f 20 54 65 73 74 76 66 73 46 69 6c  e two TestvfsFil
0c00: 65 20 73 74 72 75 63 74 75 72 65 73 20 62 75 74  e structures but
0c10: 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74 76 66   only one Testvf
0c20: 73 42 75 66 66 65 72 20 73 74 72 75 63 74 75 72  sBuffer structur
0c30: 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73  e..*/.struct Tes
0c40: 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20 20 63  tvfsBuffer {.  c
0c50: 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20 20 20  har *zFile;     
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0c70: 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66 69 6c  * Associated fil
0c80: 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20  e name */.  int 
0c90: 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20  pgsz;           
0ca0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
0cb0: 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 75 38  age size */.  u8
0cc0: 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46 53 5f   *aPage[TESTVFS_
0cd0: 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20 2f 2a  MAX_PAGES];   /*
0ce0: 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c 6c 6f   Array of ckallo
0cf0: 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 54  c'd pages */.  T
0d00: 65 73 74 76 66 73 46 69 6c 65 20 2a 70 46 69 6c  estvfsFile *pFil
0d10: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  e;             /
0d20: 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e 20 68  * List of open h
0d30: 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65 73 74  andles */.  Test
0d40: 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65 78 74  vfsBuffer *pNext
0d50: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
0d60: 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c 69  ext in linked li
0d70: 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66 65 72  st of all buffer
0d80: 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69 6e  s */.};...#defin
0d90: 65 20 50 41 52 45 4e 54 56 46 53 28 78 29 20 28  e PARENTVFS(x) (
0da0: 28 28 54 65 73 74 76 66 73 20 2a 29 28 28 78 29  ((Testvfs *)((x)
0db0: 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e 70 50  ->pAppData))->pP
0dc0: 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e 65 20  arent)..#define 
0dd0: 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52 47 53  TESTVFS_MAX_ARGS
0de0: 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68   12.../*.** Meth
0df0: 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20  od declarations 
0e00: 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c 65 2e  for TestvfsFile.
0e10: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
0e20: 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  vfsClose(sqlite3
0e30: 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20  _file*);.static 
0e40: 69 6e 74 20 74 76 66 73 52 65 61 64 28 73 71 6c  int tvfsRead(sql
0e50: 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f 69 64  ite3_file*, void
0e60: 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c  *, int iAmt, sql
0e70: 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74  ite3_int64 iOfst
0e80: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
0e90: 66 73 57 72 69 74 65 28 73 71 6c 69 74 65 33 5f  fsWrite(sqlite3_
0ea0: 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f 69 64  file*,const void
0eb0: 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c 69  *,int iAmt, sqli
0ec0: 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74 29  te3_int64 iOfst)
0ed0: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ;.static int tvf
0ee0: 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  sTruncate(sqlite
0ef0: 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74 65 33  3_file*, sqlite3
0f00: 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a 73 74  _int64 size);.st
0f10: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 79 6e  atic int tvfsSyn
0f20: 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  c(sqlite3_file*,
0f30: 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74 61   int flags);.sta
0f40: 74 69 63 20 69 6e 74 20 74 76 66 73 46 69 6c 65  tic int tvfsFile
0f50: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
0f60: 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  e*, sqlite3_int6
0f70: 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61 74 69  4 *pSize);.stati
0f80: 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28 73  c int tvfsLock(s
0f90: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e  qlite3_file*, in
0fa0: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
0fb0: 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74 65  vfsUnlock(sqlite
0fc0: 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a 73  3_file*, int);.s
0fd0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43 68  tatic int tvfsCh
0fe0: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28  eckReservedLock(
0ff0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69  sqlite3_file*, i
1000: 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  nt *);.static in
1010: 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72 6f  t tvfsFileContro
1020: 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  l(sqlite3_file*,
1030: 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70   int op, void *p
1040: 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  Arg);.static int
1050: 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 28   tvfsSectorSize(
1060: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a  sqlite3_file*);.
1070: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44  static int tvfsD
1080: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
1090: 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69 6c  tics(sqlite3_fil
10a0: 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68  e*);../*.** Meth
10b0: 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20  od declarations 
10c0: 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a 2a 2f  for tvfs_vfs..*/
10d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
10e0: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73  Open(sqlite3_vfs
10f0: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2c  *, const char *,
1100: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20   sqlite3_file*, 
1110: 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  int , int *);.st
1120: 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65 6c  atic int tvfsDel
1130: 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  ete(sqlite3_vfs*
1140: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
1150: 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69 72  ame, int syncDir
1160: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1170: 66 73 41 63 63 65 73 73 28 73 71 6c 69 74 65 33  fsAccess(sqlite3
1180: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
1190: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66 6c  r *zName, int fl
11a0: 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74 61  ags, int *);.sta
11b0: 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c  tic int tvfsFull
11c0: 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65 33  Pathname(sqlite3
11d0: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
11e0: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20 63  r *zName, int, c
11f0: 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69 66 6e  har *zOut);.#ifn
1200: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
1210: 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a 73  LOAD_EXTENSION.s
1220: 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66 73  tatic void *tvfs
1230: 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76  DlOpen(sqlite3_v
1240: 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  fs*, const char 
1250: 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73 74 61  *zFilename);.sta
1260: 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c 45  tic void tvfsDlE
1270: 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66 73  rror(sqlite3_vfs
1280: 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68  *, int nByte, ch
1290: 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a 73 74  ar *zErrMsg);.st
12a0: 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66 73  atic void (*tvfs
12b0: 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76 66  DlSym(sqlite3_vf
12c0: 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20  s*,void*, const 
12d0: 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29 29 28  char *zSymbol))(
12e0: 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76 6f  void);.static vo
12f0: 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28 73  id tvfsDlClose(s
1300: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f 69  qlite3_vfs*, voi
1310: 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20 53  d*);.#endif /* S
1320: 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f  QLITE_OMIT_LOAD_
1330: 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73 74 61  EXTENSION */.sta
1340: 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e 64  tic int tvfsRand
1350: 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f 76  omness(sqlite3_v
1360: 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20  fs*, int nByte, 
1370: 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74 61  char *zOut);.sta
1380: 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65 65  tic int tvfsSlee
1390: 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20  p(sqlite3_vfs*, 
13a0: 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73  int microseconds
13b0: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
13c0: 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71  fsCurrentTime(sq
13d0: 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f 75 62  lite3_vfs*, doub
13e0: 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69 6e  le*);..static in
13f0: 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73 71  t tvfsShmOpen(sq
1400: 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73 74  lite3_file*);.st
1410: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
1420: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
1430: 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 20 2a 29  e*, int , int *)
1440: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ;.static int tvf
1450: 73 53 68 6d 47 65 74 28 73 71 6c 69 74 65 33 5f  sShmGet(sqlite3_
1460: 66 69 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74  file*, int , int
1470: 20 2a 2c 20 76 6f 6c 61 74 69 6c 65 20 76 6f 69   *, volatile voi
1480: 64 20 2a 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  d **);.static in
1490: 74 20 74 76 66 73 53 68 6d 52 65 6c 65 61 73 65  t tvfsShmRelease
14a0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b  (sqlite3_file*);
14b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
14c0: 53 68 6d 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f  ShmLock(sqlite3_
14d0: 66 69 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74  file*, int , int
14e0: 2c 20 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 76  , int);.static v
14f0: 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72 72 69  oid tvfsShmBarri
1500: 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  er(sqlite3_file*
1510: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1520: 66 73 53 68 6d 43 6c 6f 73 65 28 73 71 6c 69 74  fsShmClose(sqlit
1530: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a  e3_file*, int);.
1540: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
1550: 68 6d 50 61 67 65 28 73 71 6c 69 74 65 33 5f 66  hmPage(sqlite3_f
1560: 69 6c 65 2a 2c 69 6e 74 2c 69 6e 74 2c 69 6e 74  ile*,int,int,int
1570: 2c 20 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20  , void volatile 
1580: 2a 2a 29 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c  **);..static sql
1590: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20  ite3_io_methods 
15a0: 74 76 66 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 20  tvfs_io_methods 
15b0: 3d 20 7b 0a 20 20 32 2c 20 20 20 20 20 20 20 20  = {.  2,        
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d0: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
15e0: 2a 2f 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20  */.  tvfsClose, 
15f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1600: 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a       /* xClose *
1610: 2f 0a 20 20 74 76 66 73 52 65 61 64 2c 20 20 20  /.  tvfsRead,   
1620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1630: 20 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a      /* xRead */.
1640: 20 20 74 76 66 73 57 72 69 74 65 2c 20 20 20 20    tvfsWrite,    
1650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1660: 20 20 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20    /* xWrite */. 
1670: 20 74 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20   tvfsTruncate,  
1680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1690: 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f   /* xTruncate */
16a0: 0a 20 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20  .  tvfsSync,    
16b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c0: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20     /* xSync */. 
16d0: 20 74 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20   tvfsFileSize,  
16e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16f0: 20 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f   /* xFileSize */
1700: 0a 20 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20  .  tvfsLock,    
1710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1720: 20 20 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20     /* xLock */. 
1730: 20 74 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20   tvfsUnlock,    
1740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1750: 20 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20   /* xUnlock */. 
1760: 20 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76   tvfsCheckReserv
1770: 65 64 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20  edLock,         
1780: 20 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76   /* xCheckReserv
1790: 65 64 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73  edLock */.  tvfs
17a0: 46 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20  FileControl,    
17b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
17c0: 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20  FileControl */. 
17d0: 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c   tvfsSectorSize,
17e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17f0: 20 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20   /* xSectorSize 
1800: 2a 2f 0a 20 20 74 76 66 73 44 65 76 69 63 65 43  */.  tvfsDeviceC
1810: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 2c 20  haracteristics, 
1820: 20 20 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43       /* xDeviceC
1830: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 20 2a  haracteristics *
1840: 2f 0a 20 20 74 76 66 73 53 68 6d 4f 70 65 6e 2c  /.  tvfsShmOpen,
1850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1860: 20 20 20 20 2f 2a 20 78 53 68 6d 4f 70 65 6e 20      /* xShmOpen 
1870: 2a 2f 0a 20 20 74 76 66 73 53 68 6d 53 69 7a 65  */.  tvfsShmSize
1880: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1890: 20 20 20 20 20 2f 2a 20 78 53 68 6d 53 69 7a 65       /* xShmSize
18a0: 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 47 65 74   */.  tvfsShmGet
18b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
18c0: 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 47 65 74        /* xShmGet
18d0: 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 52 65 6c   */.  tvfsShmRel
18e0: 65 61 73 65 2c 20 20 20 20 20 20 20 20 20 20 20  ease,           
18f0: 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 52 65 6c        /* xShmRel
1900: 65 61 73 65 20 2a 2f 0a 20 20 74 76 66 73 53 68  ease */.  tvfsSh
1910: 6d 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20  mLock,          
1920: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68            /* xSh
1930: 6d 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73 53  mLock */.  tvfsS
1940: 68 6d 42 61 72 72 69 65 72 2c 20 20 20 20 20 20  hmBarrier,      
1950: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
1960: 68 6d 42 61 72 72 69 65 72 20 2a 2f 0a 20 20 74  hmBarrier */.  t
1970: 76 66 73 53 68 6d 43 6c 6f 73 65 2c 20 20 20 20  vfsShmClose,    
1980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1990: 2a 20 78 53 68 6d 43 6c 6f 73 65 20 2a 2f 0a 20  * xShmClose */. 
19a0: 20 74 76 66 73 53 68 6d 50 61 67 65 20 20 20 20   tvfsShmPage    
19b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19c0: 20 2f 2a 20 78 53 68 6d 50 61 67 65 20 2a 2f 0a   /* xShmPage */.
19d0: 7d 3b 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  };..static int t
19e0: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 54 65  vfsResultCode(Te
19f0: 73 74 76 66 73 20 2a 70 2c 20 69 6e 74 20 2a 70  stvfs *p, int *p
1a00: 52 63 29 7b 0a 20 20 73 74 72 75 63 74 20 65 72  Rc){.  struct er
1a10: 72 63 6f 64 65 20 7b 0a 20 20 20 20 69 6e 74 20  rcode {.    int 
1a20: 65 43 6f 64 65 3b 0a 20 20 20 20 63 6f 6e 73 74  eCode;.    const
1a30: 20 63 68 61 72 20 2a 7a 43 6f 64 65 3b 0a 20 20   char *zCode;.  
1a40: 7d 20 61 43 6f 64 65 5b 5d 20 3d 20 7b 0a 20 20  } aCode[] = {.  
1a50: 20 20 7b 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 20    { SQLITE_OK,  
1a60: 20 20 20 22 53 51 4c 49 54 45 5f 4f 4b 22 20 20     "SQLITE_OK"  
1a70: 20 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49     },.    { SQLI
1a80: 54 45 5f 45 52 52 4f 52 2c 20 20 22 53 51 4c 49  TE_ERROR,  "SQLI
1a90: 54 45 5f 45 52 52 4f 52 22 20 20 7d 2c 0a 20 20  TE_ERROR"  },.  
1aa0: 20 20 7b 20 53 51 4c 49 54 45 5f 49 4f 45 52 52    { SQLITE_IOERR
1ab0: 2c 20 20 22 53 51 4c 49 54 45 5f 49 4f 45 52 52  ,  "SQLITE_IOERR
1ac0: 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  "  },.    { SQLI
1ad0: 54 45 5f 4c 4f 43 4b 45 44 2c 20 22 53 51 4c 49  TE_LOCKED, "SQLI
1ae0: 54 45 5f 4c 4f 43 4b 45 44 22 20 7d 2c 0a 20 20  TE_LOCKED" },.  
1af0: 20 20 7b 20 53 51 4c 49 54 45 5f 42 55 53 59 2c    { SQLITE_BUSY,
1b00: 20 20 20 22 53 51 4c 49 54 45 5f 42 55 53 59 22     "SQLITE_BUSY"
1b10: 20 20 20 7d 2c 0a 20 20 7d 3b 0a 0a 20 20 63 6f     },.  };..  co
1b20: 6e 73 74 20 63 68 61 72 20 2a 7a 3b 0a 20 20 69  nst char *z;.  i
1b30: 6e 74 20 69 3b 0a 0a 20 20 7a 20 3d 20 54 63 6c  nt i;..  z = Tcl
1b40: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1b50: 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 66  (p->interp);.  f
1b60: 6f 72 28 69 3d 30 3b 20 69 3c 41 72 72 61 79 53  or(i=0; i<ArrayS
1b70: 69 7a 65 28 61 43 6f 64 65 29 3b 20 69 2b 2b 29  ize(aCode); i++)
1b80: 7b 0a 20 20 20 20 69 66 28 20 30 3d 3d 73 74 72  {.    if( 0==str
1b90: 63 6d 70 28 7a 2c 20 61 43 6f 64 65 5b 69 5d 2e  cmp(z, aCode[i].
1ba0: 7a 43 6f 64 65 29 20 29 7b 0a 20 20 20 20 20 20  zCode) ){.      
1bb0: 2a 70 52 63 20 3d 20 61 43 6f 64 65 5b 69 5d 2e  *pRc = aCode[i].
1bc0: 65 43 6f 64 65 3b 0a 20 20 20 20 20 20 72 65 74  eCode;.      ret
1bd0: 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  urn 1;.    }.  }
1be0: 0a 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ..  return 0;.}.
1bf0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76  ..static void tv
1c00: 66 73 45 78 65 63 54 63 6c 28 0a 20 20 54 65 73  fsExecTcl(.  Tes
1c10: 74 76 66 73 20 2a 70 2c 20 0a 20 20 63 6f 6e 73  tvfs *p, .  cons
1c20: 74 20 63 68 61 72 20 2a 7a 4d 65 74 68 6f 64 2c  t char *zMethod,
1c30: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 61 72 67 31  .  Tcl_Obj *arg1
1c40: 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 61 72 67  ,.  Tcl_Obj *arg
1c50: 32 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 61 72  2,.  Tcl_Obj *ar
1c60: 67 33 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  g3.){.  int rc; 
1c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c80: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
1c90: 6e 20 63 6f 64 65 20 66 72 6f 6d 20 54 63 6c 5f  n code from Tcl_
1ca0: 45 76 61 6c 4f 62 6a 28 29 20 2a 2f 0a 20 20 69  EvalObj() */.  i
1cb0: 6e 74 20 6e 41 72 67 3b 20 20 20 20 20 20 20 20  nt nArg;        
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1cd0: 2a 20 45 6c 65 6d 65 6e 74 73 20 69 6e 20 65 76  * Elements in ev
1ce0: 61 6c 27 64 20 6c 69 73 74 20 2a 2f 0a 20 20 69  al'd list */.  i
1cf0: 6e 74 20 6e 53 63 72 69 70 74 3b 0a 20 20 54 63  nt nScript;.  Tc
1d00: 6c 5f 4f 62 6a 20 2a 2a 20 61 70 3b 0a 0a 20 20  l_Obj ** ap;..  
1d10: 61 73 73 65 72 74 28 20 70 2d 3e 70 53 63 72 69  assert( p->pScri
1d20: 70 74 20 29 3b 0a 0a 20 20 69 66 28 20 21 70 2d  pt );..  if( !p-
1d30: 3e 61 70 53 63 72 69 70 74 20 29 7b 0a 20 20 20  >apScript ){.   
1d40: 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20   int nByte;.    
1d50: 69 6e 74 20 69 3b 0a 20 20 20 20 69 66 28 20 54  int i;.    if( T
1d60: 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 4c 69 73 74 4f  CL_OK!=Tcl_ListO
1d70: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 70 2d  bjGetElements(p-
1d80: 3e 69 6e 74 65 72 70 2c 20 70 2d 3e 70 53 63 72  >interp, p->pScr
1d90: 69 70 74 2c 20 26 6e 53 63 72 69 70 74 2c 20 26  ipt, &nScript, &
1da0: 61 70 29 20 29 7b 0a 20 20 20 20 20 20 54 63 6c  ap) ){.      Tcl
1db0: 5f 42 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72  _BackgroundError
1dc0: 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20  (p->interp);.   
1dd0: 20 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75     Tcl_ResetResu
1de0: 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20  lt(p->interp);. 
1df0: 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20       return;.   
1e00: 20 7d 0a 20 20 20 20 70 2d 3e 6e 53 63 72 69 70   }.    p->nScrip
1e10: 74 20 3d 20 6e 53 63 72 69 70 74 3b 0a 20 20 20  t = nScript;.   
1e20: 20 6e 42 79 74 65 20 3d 20 28 6e 53 63 72 69 70   nByte = (nScrip
1e30: 74 2b 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52  t+TESTVFS_MAX_AR
1e40: 47 53 29 2a 73 69 7a 65 6f 66 28 54 63 6c 5f 4f  GS)*sizeof(Tcl_O
1e50: 62 6a 20 2a 29 3b 0a 20 20 20 20 70 2d 3e 61 70  bj *);.    p->ap
1e60: 53 63 72 69 70 74 20 3d 20 28 54 63 6c 5f 4f 62  Script = (Tcl_Ob
1e70: 6a 20 2a 2a 29 63 6b 61 6c 6c 6f 63 28 6e 42 79  j **)ckalloc(nBy
1e80: 74 65 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  te);.    memset(
1e90: 70 2d 3e 61 70 53 63 72 69 70 74 2c 20 30 2c 20  p->apScript, 0, 
1ea0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 66 6f 72 28  nByte);.    for(
1eb0: 69 3d 30 3b 20 69 3c 6e 53 63 72 69 70 74 3b 20  i=0; i<nScript; 
1ec0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 70 2d 3e 61  i++){.      p->a
1ed0: 70 53 63 72 69 70 74 5b 69 5d 20 3d 20 61 70 5b  pScript[i] = ap[
1ee0: 69 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  i];.    }.  }.. 
1ef0: 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 70 2d 3e   p->apScript[p->
1f00: 6e 53 63 72 69 70 74 5d 20 3d 20 54 63 6c 5f 4e  nScript] = Tcl_N
1f10: 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 4d 65 74  ewStringObj(zMet
1f20: 68 6f 64 2c 20 2d 31 29 3b 0a 20 20 70 2d 3e 61  hod, -1);.  p->a
1f30: 70 53 63 72 69 70 74 5b 70 2d 3e 6e 53 63 72 69  pScript[p->nScri
1f40: 70 74 2b 31 5d 20 3d 20 61 72 67 31 3b 0a 20 20  pt+1] = arg1;.  
1f50: 70 2d 3e 61 70 53 63 72 69 70 74 5b 70 2d 3e 6e  p->apScript[p->n
1f60: 53 63 72 69 70 74 2b 32 5d 20 3d 20 61 72 67 32  Script+2] = arg2
1f70: 3b 0a 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b  ;.  p->apScript[
1f80: 70 2d 3e 6e 53 63 72 69 70 74 2b 33 5d 20 3d 20  p->nScript+3] = 
1f90: 61 72 67 33 3b 0a 0a 20 20 66 6f 72 28 6e 41 72  arg3;..  for(nAr
1fa0: 67 3d 70 2d 3e 6e 53 63 72 69 70 74 3b 20 70 2d  g=p->nScript; p-
1fb0: 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67 5d 3b  >apScript[nArg];
1fc0: 20 6e 41 72 67 2b 2b 29 7b 0a 20 20 20 20 54 63   nArg++){.    Tc
1fd0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70  l_IncrRefCount(p
1fe0: 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67 5d  ->apScript[nArg]
1ff0: 29 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 54  );.  }..  rc = T
2000: 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 70 2d 3e 69  cl_EvalObjv(p->i
2010: 6e 74 65 72 70 2c 20 6e 41 72 67 2c 20 70 2d 3e  nterp, nArg, p->
2020: 61 70 53 63 72 69 70 74 2c 20 54 43 4c 5f 45 56  apScript, TCL_EV
2030: 41 4c 5f 47 4c 4f 42 41 4c 29 3b 0a 20 20 69 66  AL_GLOBAL);.  if
2040: 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 7b 0a  ( rc!=TCL_OK ){.
2050: 20 20 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75      Tcl_Backgrou
2060: 6e 64 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72  ndError(p->inter
2070: 70 29 3b 0a 20 20 20 20 54 63 6c 5f 52 65 73 65  p);.    Tcl_Rese
2080: 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72  tResult(p->inter
2090: 70 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 6e  p);.  }..  for(n
20a0: 41 72 67 3d 70 2d 3e 6e 53 63 72 69 70 74 3b 20  Arg=p->nScript; 
20b0: 70 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67  p->apScript[nArg
20c0: 5d 3b 20 6e 41 72 67 2b 2b 29 7b 0a 20 20 20 20  ]; nArg++){.    
20d0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
20e0: 28 70 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72  (p->apScript[nAr
20f0: 67 5d 29 3b 0a 20 20 20 20 70 2d 3e 61 70 53 63  g]);.    p->apSc
2100: 72 69 70 74 5b 6e 41 72 67 5d 20 3d 20 30 3b 0a  ript[nArg] = 0;.
2110: 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c    }.}.../*.** Cl
2120: 6f 73 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ose an tvfs-file
2130: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2140: 74 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65  tvfsClose(sqlite
2150: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
2160: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
2170: 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65 20   = (TestvfsFile 
2180: 2a 29 70 46 69 6c 65 3b 0a 20 20 69 66 28 20 70  *)pFile;.  if( p
2190: 2d 3e 70 53 68 6d 49 64 20 29 7b 0a 20 20 20 20  ->pShmId ){.    
21a0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
21b0: 28 70 2d 3e 70 53 68 6d 49 64 29 3b 0a 20 20 20  (p->pShmId);.   
21c0: 20 70 2d 3e 70 53 68 6d 49 64 20 3d 20 30 3b 0a   p->pShmId = 0;.
21d0: 20 20 7d 0a 20 20 69 66 28 20 70 46 69 6c 65 2d    }.  if( pFile-
21e0: 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20 20  >pMethods ){.   
21f0: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
2200: 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 29  pFile->pMethods)
2210: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
2220: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70 2d  qlite3OsClose(p-
2230: 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  >pReal);.}../*.*
2240: 2a 20 52 65 61 64 20 64 61 74 61 20 66 72 6f 6d  * Read data from
2250: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
2260: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
2270: 73 52 65 61 64 28 0a 20 20 73 71 6c 69 74 65 33  sRead(.  sqlite3
2280: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 0a 20  _file *pFile, . 
2290: 20 76 6f 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20   void *zBuf, .  
22a0: 69 6e 74 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c  int iAmt, .  sql
22b0: 69 74 65 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a  ite_int64 iOfst.
22c0: 29 7b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65  ){.  TestvfsFile
22d0: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 46 69   *p = (TestvfsFi
22e0: 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 72 65  le *)pFile;.  re
22f0: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65  turn sqlite3OsRe
2300: 61 64 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75  ad(p->pReal, zBu
2310: 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b  f, iAmt, iOfst);
2320: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
2330: 64 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73 2d  data to an tvfs-
2340: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
2350: 69 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a 20  int tvfsWrite(. 
2360: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
2370: 46 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 76  File, .  const v
2380: 6f 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e  oid *zBuf, .  in
2390: 74 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74  t iAmt, .  sqlit
23a0: 65 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b  e_int64 iOfst.){
23b0: 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a  .  TestvfsFile *
23c0: 70 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65  p = (TestvfsFile
23d0: 20 2a 29 70 46 69 6c 65 3b 0a 20 20 72 65 74 75   *)pFile;.  retu
23e0: 72 6e 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74  rn sqlite3OsWrit
23f0: 65 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66  e(p->pReal, zBuf
2400: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
2410: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63 61 74  }../*.** Truncat
2420: 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  e an tvfs-file..
2430: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2440: 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74  fsTruncate(sqlit
2450: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
2460: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 73 69 7a  sqlite_int64 siz
2470: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 69 6c  e){.  TestvfsFil
2480: 65 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 46  e *p = (TestvfsF
2490: 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 72  ile *)pFile;.  r
24a0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 54  eturn sqlite3OsT
24b0: 72 75 6e 63 61 74 65 28 70 2d 3e 70 52 65 61 6c  runcate(p->pReal
24c0: 2c 20 73 69 7a 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  , size);.}../*.*
24d0: 2a 20 53 79 6e 63 20 61 6e 20 74 76 66 73 2d 66  * Sync an tvfs-f
24e0: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
24f0: 6e 74 20 74 76 66 73 53 79 6e 63 28 73 71 6c 69  nt tvfsSync(sqli
2500: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
2510: 20 69 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20 69   int flags){.  i
2520: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2530: 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65  K;.  TestvfsFile
2540: 20 2a 70 46 64 20 3d 20 28 54 65 73 74 76 66 73   *pFd = (Testvfs
2550: 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20  File *)pFile;.  
2560: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
2570: 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66  stvfs *)pFd->pVf
2580: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20  s->pAppData;..  
2590: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
25a0: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
25b0: 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 29 7b 0a 20  S_SYNC_MASK ){. 
25c0: 20 20 20 63 68 61 72 20 2a 7a 46 6c 61 67 73 3b     char *zFlags;
25d0: 0a 0a 20 20 20 20 73 77 69 74 63 68 28 20 66 6c  ..    switch( fl
25e0: 61 67 73 20 29 7b 0a 20 20 20 20 20 20 63 61 73  ags ){.      cas
25f0: 65 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4e 4f  e SQLITE_SYNC_NO
2600: 52 4d 41 4c 3a 0a 20 20 20 20 20 20 20 20 7a 46  RMAL:.        zF
2610: 6c 61 67 73 20 3d 20 22 6e 6f 72 6d 61 6c 22 3b  lags = "normal";
2620: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
2630: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
2640: 45 5f 53 59 4e 43 5f 46 55 4c 4c 3a 0a 20 20 20  E_SYNC_FULL:.   
2650: 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 66       zFlags = "f
2660: 75 6c 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72  ull";.        br
2670: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
2680: 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4e 4f 52 4d  SQLITE_SYNC_NORM
2690: 41 4c 7c 53 51 4c 49 54 45 5f 53 59 4e 43 5f 44  AL|SQLITE_SYNC_D
26a0: 41 54 41 4f 4e 4c 59 3a 0a 20 20 20 20 20 20 20  ATAONLY:.       
26b0: 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72 6d 61   zFlags = "norma
26c0: 6c 7c 64 61 74 61 6f 6e 6c 79 22 3b 0a 20 20 20  l|dataonly";.   
26d0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
26e0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59    case SQLITE_SY
26f0: 4e 43 5f 46 55 4c 4c 7c 53 51 4c 49 54 45 5f 53  NC_FULL|SQLITE_S
2700: 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20  YNC_DATAONLY:.  
2710: 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22        zFlags = "
2720: 66 75 6c 6c 7c 64 61 74 61 6f 6e 6c 79 22 3b 0a  full|dataonly";.
2730: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
2740: 20 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20       default:.  
2750: 20 20 20 20 20 20 61 73 73 65 72 74 28 30 29 3b        assert(0);
2760: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 74 76 66 73  .    }..    tvfs
2770: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 79 6e  ExecTcl(p, "xSyn
2780: 63 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  c", .        Tcl
2790: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
27a0: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
27b0: 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a  ), pFd->pShmId,.
27c0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
27d0: 74 72 69 6e 67 4f 62 6a 28 7a 46 6c 61 67 73 2c  tringObj(zFlags,
27e0: 20 2d 31 29 0a 20 20 20 20 29 3b 0a 20 20 20 20   -1).    );.    
27f0: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
2800: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69  , &rc);.  }..  i
2810: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2820: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2830: 69 74 65 33 4f 73 53 79 6e 63 28 70 46 64 2d 3e  ite3OsSync(pFd->
2840: 70 52 65 61 6c 2c 20 66 6c 61 67 73 29 3b 0a 20  pReal, flags);. 
2850: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
2860: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
2870: 20 74 68 65 20 63 75 72 72 65 6e 74 20 66 69 6c   the current fil
2880: 65 2d 73 69 7a 65 20 6f 66 20 61 6e 20 74 76 66  e-size of an tvf
2890: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
28a0: 63 20 69 6e 74 20 74 76 66 73 46 69 6c 65 53 69  c int tvfsFileSi
28b0: 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ze(sqlite3_file 
28c0: 2a 70 46 69 6c 65 2c 20 73 71 6c 69 74 65 5f 69  *pFile, sqlite_i
28d0: 6e 74 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20  nt64 *pSize){.  
28e0: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70 20 3d  TestvfsFile *p =
28f0: 20 28 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29   (TestvfsFile *)
2900: 70 46 69 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20  pFile;.  return 
2910: 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a  sqlite3OsFileSiz
2920: 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69 7a  e(p->pReal, pSiz
2930: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63  e);.}../*.** Loc
2940: 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  k an tvfs-file..
2950: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2960: 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  fsLock(sqlite3_f
2970: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
2980: 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76 66  eLock){.  Testvf
2990: 73 46 69 6c 65 20 2a 70 20 3d 20 28 54 65 73 74  sFile *p = (Test
29a0: 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  vfsFile *)pFile;
29b0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
29c0: 33 4f 73 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  3OsLock(p->pReal
29d0: 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a  , eLock);.}../*.
29e0: 2a 2a 20 55 6e 6c 6f 63 6b 20 61 6e 20 74 76 66  ** Unlock an tvf
29f0: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
2a00: 63 20 69 6e 74 20 74 76 66 73 55 6e 6c 6f 63 6b  c int tvfsUnlock
2a10: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
2a20: 46 69 6c 65 2c 20 69 6e 74 20 65 4c 6f 63 6b 29  File, int eLock)
2a30: 7b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20  {.  TestvfsFile 
2a40: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c  *p = (TestvfsFil
2a50: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 72 65 74  e *)pFile;.  ret
2a60: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 55 6e 6c  urn sqlite3OsUnl
2a70: 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c  ock(p->pReal, eL
2a80: 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  ock);.}../*.** C
2a90: 68 65 63 6b 20 69 66 20 61 6e 6f 74 68 65 72 20  heck if another 
2aa0: 66 69 6c 65 2d 68 61 6e 64 6c 65 20 68 6f 6c 64  file-handle hold
2ab0: 73 20 61 20 52 45 53 45 52 56 45 44 20 6c 6f 63  s a RESERVED loc
2ac0: 6b 20 6f 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c  k on an tvfs-fil
2ad0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
2ae0: 20 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76   tvfsCheckReserv
2af0: 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  edLock(sqlite3_f
2b00: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
2b10: 2a 70 52 65 73 4f 75 74 29 7b 0a 20 20 54 65 73  *pResOut){.  Tes
2b20: 74 76 66 73 46 69 6c 65 20 2a 70 20 3d 20 28 54  tvfsFile *p = (T
2b30: 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69  estvfsFile *)pFi
2b40: 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  le;.  return sql
2b50: 69 74 65 33 4f 73 43 68 65 63 6b 52 65 73 65 72  ite3OsCheckReser
2b60: 76 65 64 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  vedLock(p->pReal
2b70: 2c 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f  , pResOut);.}../
2b80: 2a 0a 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f  *.** File contro
2b90: 6c 20 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75  l method. For cu
2ba0: 73 74 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20  stom operations 
2bb0: 6f 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  on an tvfs-file.
2bc0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
2bd0: 76 66 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73  vfsFileControl(s
2be0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2bf0: 6c 65 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64  le, int op, void
2c00: 20 2a 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76   *pArg){.  Testv
2c10: 66 73 46 69 6c 65 20 2a 70 20 3d 20 28 54 65 73  fsFile *p = (Tes
2c20: 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65  tvfsFile *)pFile
2c30: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
2c40: 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28  e3OsFileControl(
2c50: 70 2d 3e 70 52 65 61 6c 2c 20 6f 70 2c 20 70 41  p->pReal, op, pA
2c60: 72 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  rg);.}../*.** Re
2c70: 74 75 72 6e 20 74 68 65 20 73 65 63 74 6f 72 2d  turn the sector-
2c80: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 66 6f  size in bytes fo
2c90: 72 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  r an tvfs-file..
2ca0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2cb0: 66 73 53 65 63 74 6f 72 53 69 7a 65 28 73 71 6c  fsSectorSize(sql
2cc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
2cd0: 29 7b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65  ){.  TestvfsFile
2ce0: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 46 69   *p = (TestvfsFi
2cf0: 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 72 65  le *)pFile;.  re
2d00: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 65  turn sqlite3OsSe
2d10: 63 74 6f 72 53 69 7a 65 28 70 2d 3e 70 52 65 61  ctorSize(p->pRea
2d20: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  l);.}../*.** Ret
2d30: 75 72 6e 20 74 68 65 20 64 65 76 69 63 65 20 63  urn the device c
2d40: 68 61 72 61 63 74 65 72 69 73 74 69 63 20 66 6c  haracteristic fl
2d50: 61 67 73 20 73 75 70 70 6f 72 74 65 64 20 62 79  ags supported by
2d60: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
2d70: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
2d80: 73 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72  sDeviceCharacter
2d90: 69 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66  istics(sqlite3_f
2da0: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
2db0: 65 73 74 76 66 73 46 69 6c 65 20 2a 70 20 3d 20  estvfsFile *p = 
2dc0: 28 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70  (TestvfsFile *)p
2dd0: 46 69 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20 73  File;.  return s
2de0: 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65 43 68  qlite3OsDeviceCh
2df0: 61 72 61 63 74 65 72 69 73 74 69 63 73 28 70 2d  aracteristics(p-
2e00: 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  >pReal);.}../*.*
2e10: 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73 20 66  * Open an tvfs f
2e20: 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73  ile handle..*/.s
2e30: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 4f 70  tatic int tvfsOp
2e40: 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  en(.  sqlite3_vf
2e50: 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74  s *pVfs,.  const
2e60: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20   char *zName,.  
2e70: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2e80: 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73  ile,.  int flags
2e90: 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61  ,.  int *pOutFla
2ea0: 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  gs.){.  int rc;.
2eb0: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
2ec0: 46 64 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c  Fd = (TestvfsFil
2ed0: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 54 63 6c  e *)pFile;.  Tcl
2ee0: 5f 4f 62 6a 20 2a 70 49 64 20 3d 20 30 3b 0a 20  _Obj *pId = 0;. 
2ef0: 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54   Testvfs *p = (T
2f00: 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d 3e 70  estvfs *)pVfs->p
2f10: 41 70 70 44 61 74 61 3b 0a 0a 20 20 70 46 64 2d  AppData;..  pFd-
2f20: 3e 70 53 68 6d 20 3d 20 30 3b 0a 20 20 70 46 64  >pShm = 0;.  pFd
2f30: 2d 3e 70 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20  ->pShmId = 0;.  
2f40: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d  pFd->zFilename =
2f50: 20 7a 4e 61 6d 65 3b 0a 20 20 70 46 64 2d 3e 70   zName;.  pFd->p
2f60: 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 46  Vfs = pVfs;.  pF
2f70: 64 2d 3e 70 52 65 61 6c 20 3d 20 28 73 71 6c 69  d->pReal = (sqli
2f80: 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 46 64 5b  te3_file *)&pFd[
2f90: 31 5d 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61  1];..  /* Evalua
2fa0: 74 65 20 74 68 65 20 54 63 6c 20 73 63 72 69 70  te the Tcl scrip
2fb0: 74 3a 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  t: .  **.  **   
2fc0: 53 43 52 49 50 54 20 78 4f 70 65 6e 20 46 49 4c  SCRIPT xOpen FIL
2fd0: 45 4e 41 4d 45 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ENAME.  **.  ** 
2fe0: 49 66 20 74 68 65 20 73 63 72 69 70 74 20 72 65  If the script re
2ff0: 74 75 72 6e 73 20 61 6e 20 53 51 4c 69 74 65 20  turns an SQLite 
3000: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
3010: 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c   than SQLITE_OK,
3020: 20 61 6e 0a 20 20 2a 2a 20 65 72 72 6f 72 20 69   an.  ** error i
3030: 73 20 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68  s returned to th
3040: 65 20 63 61 6c 6c 65 72 2e 20 49 66 20 69 74 20  e caller. If it 
3050: 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f  returns SQLITE_O
3060: 4b 2c 20 74 68 65 20 6e 65 77 0a 20 20 2a 2a 20  K, the new.  ** 
3070: 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20 6e 61  connection is na
3080: 6d 65 64 20 22 61 6e 6f 6e 22 2e 20 4f 74 68 65  med "anon". Othe
3090: 72 77 69 73 65 2c 20 74 68 65 20 76 61 6c 75 65  rwise, the value
30a0: 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68 65   returned by the
30b0: 0a 20 20 2a 2a 20 73 63 72 69 70 74 20 69 73 20  .  ** script is 
30c0: 75 73 65 64 20 61 73 20 74 68 65 20 63 6f 6e 6e  used as the conn
30d0: 65 63 74 69 6f 6e 20 6e 61 6d 65 2e 0a 20 20 2a  ection name..  *
30e0: 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73  /.  Tcl_ResetRes
30f0: 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a  ult(p->interp);.
3100: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
3110: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
3120: 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b  VFS_OPEN_MASK ){
3130: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
3140: 28 70 2c 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c  (p, "xOpen", Tcl
3150: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
3160: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
3170: 29 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66  ), 0, 0);.    if
3180: 28 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65  ( tvfsResultCode
3190: 28 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20  (p, &rc) ){.    
31a0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
31b0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
31c0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
31d0: 20 20 70 49 64 20 3d 20 54 63 6c 5f 47 65 74 4f    pId = Tcl_GetO
31e0: 62 6a 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  bjResult(p->inte
31f0: 72 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  rp);.    }.  }. 
3200: 20 69 66 28 20 21 70 49 64 20 29 7b 0a 20 20 20   if( !pId ){.   
3210: 20 70 49 64 20 3d 20 54 63 6c 5f 4e 65 77 53 74   pId = Tcl_NewSt
3220: 72 69 6e 67 4f 62 6a 28 22 61 6e 6f 6e 22 2c 20  ringObj("anon", 
3230: 2d 31 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 49  -1);.  }.  Tcl_I
3240: 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 49 64 29  ncrRefCount(pId)
3250: 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64 20  ;.  pFd->pShmId 
3260: 3d 20 70 49 64 3b 0a 20 20 54 63 6c 5f 52 65 73  = pId;.  Tcl_Res
3270: 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  etResult(p->inte
3280: 72 70 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c  rp);..  rc = sql
3290: 69 74 65 33 4f 73 4f 70 65 6e 28 50 41 52 45 4e  ite3OsOpen(PAREN
32a0: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 4e 61 6d  TVFS(pVfs), zNam
32b0: 65 2c 20 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66  e, pFd->pReal, f
32c0: 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29  lags, pOutFlags)
32d0: 3b 0a 20 20 69 66 28 20 70 46 64 2d 3e 70 52 65  ;.  if( pFd->pRe
32e0: 61 6c 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a  al->pMethods ){.
32f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d      sqlite3_io_m
3300: 65 74 68 6f 64 73 20 2a 70 4d 65 74 68 6f 64 73  ethods *pMethods
3310: 3b 0a 20 20 20 20 70 4d 65 74 68 6f 64 73 20 3d  ;.    pMethods =
3320: 20 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74   (sqlite3_io_met
3330: 68 6f 64 73 20 2a 29 63 6b 61 6c 6c 6f 63 28 73  hods *)ckalloc(s
3340: 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f  izeof(sqlite3_io
3350: 5f 6d 65 74 68 6f 64 73 29 29 3b 0a 20 20 20 20  _methods));.    
3360: 6d 65 6d 63 70 79 28 70 4d 65 74 68 6f 64 73 2c  memcpy(pMethods,
3370: 20 26 74 76 66 73 5f 69 6f 5f 6d 65 74 68 6f 64   &tvfs_io_method
3380: 73 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65  s, sizeof(sqlite
3390: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29 29 3b 0a  3_io_methods));.
33a0: 20 20 20 20 69 66 28 20 28 28 54 65 73 74 76 66      if( ((Testvf
33b0: 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61  s *)pVfs->pAppDa
33c0: 74 61 29 2d 3e 69 73 4e 6f 73 68 6d 20 29 7b 0a  ta)->isNoshm ){.
33d0: 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e        pMethods->
33e0: 78 53 68 6d 4f 70 65 6e 20 3d 20 30 3b 0a 20 20  xShmOpen = 0;.  
33f0: 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53      pMethods->xS
3400: 68 6d 47 65 74 20 3d 20 30 3b 0a 20 20 20 20 20  hmGet = 0;.     
3410: 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 53   pMethods->xShmS
3420: 69 7a 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  ize = 0;.      p
3430: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 52 65 6c  Methods->xShmRel
3440: 65 61 73 65 20 3d 20 30 3b 0a 20 20 20 20 20 20  ease = 0;.      
3450: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 43 6c  pMethods->xShmCl
3460: 6f 73 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  ose = 0;.      p
3470: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63  Methods->xShmLoc
3480: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65  k = 0;.      pMe
3490: 74 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72 69  thods->xShmBarri
34a0: 65 72 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  er = 0;.    }.  
34b0: 20 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64    pFile->pMethod
34c0: 73 20 3d 20 70 4d 65 74 68 6f 64 73 3b 0a 20 20  s = pMethods;.  
34d0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
34e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20  }../*.** Delete 
34f0: 74 68 65 20 66 69 6c 65 20 6c 6f 63 61 74 65 64  the file located
3500: 20 61 74 20 7a 50 61 74 68 2e 20 49 66 20 74 68   at zPath. If th
3510: 65 20 64 69 72 53 79 6e 63 20 61 72 67 75 6d 65  e dirSync argume
3520: 6e 74 20 69 73 20 74 72 75 65 2c 0a 2a 2a 20 65  nt is true,.** e
3530: 6e 73 75 72 65 20 74 68 65 20 66 69 6c 65 2d 73  nsure the file-s
3540: 79 73 74 65 6d 20 6d 6f 64 69 66 69 63 61 74 69  ystem modificati
3550: 6f 6e 73 20 61 72 65 20 73 79 6e 63 65 64 20 74  ons are synced t
3560: 6f 20 64 69 73 6b 20 62 65 66 6f 72 65 0a 2a 2a  o disk before.**
3570: 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73   returning..*/.s
3580: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65  tatic int tvfsDe
3590: 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73  lete(sqlite3_vfs
35a0: 20 2a 70 56 66 73 2c 20 63 6f 6e 73 74 20 63 68   *pVfs, const ch
35b0: 61 72 20 2a 7a 50 61 74 68 2c 20 69 6e 74 20 64  ar *zPath, int d
35c0: 69 72 53 79 6e 63 29 7b 0a 20 20 72 65 74 75 72  irSync){.  retur
35d0: 6e 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74  n sqlite3OsDelet
35e0: 65 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  e(PARENTVFS(pVfs
35f0: 29 2c 20 7a 50 61 74 68 2c 20 64 69 72 53 79 6e  ), zPath, dirSyn
3600: 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73  c);.}../*.** Tes
3610: 74 20 66 6f 72 20 61 63 63 65 73 73 20 70 65 72  t for access per
3620: 6d 69 73 73 69 6f 6e 73 2e 20 52 65 74 75 72 6e  missions. Return
3630: 20 74 72 75 65 20 69 66 20 74 68 65 20 72 65 71   true if the req
3640: 75 65 73 74 65 64 20 70 65 72 6d 69 73 73 69 6f  uested permissio
3650: 6e 0a 2a 2a 20 69 73 20 61 76 61 69 6c 61 62 6c  n.** is availabl
3660: 65 2c 20 6f 72 20 66 61 6c 73 65 20 6f 74 68 65  e, or false othe
3670: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
3680: 20 69 6e 74 20 74 76 66 73 41 63 63 65 73 73 28   int tvfsAccess(
3690: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
36a0: 70 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63  pVfs, .  const c
36b0: 68 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69  har *zPath, .  i
36c0: 6e 74 20 66 6c 61 67 73 2c 20 0a 20 20 69 6e 74  nt flags, .  int
36d0: 20 2a 70 52 65 73 4f 75 74 0a 29 7b 0a 20 20 72   *pResOut.){.  r
36e0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 41  eturn sqlite3OsA
36f0: 63 63 65 73 73 28 50 41 52 45 4e 54 56 46 53 28  ccess(PARENTVFS(
3700: 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 66 6c  pVfs), zPath, fl
3710: 61 67 73 2c 20 70 52 65 73 4f 75 74 29 3b 0a 7d  ags, pResOut);.}
3720: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65  ../*.** Populate
3730: 20 62 75 66 66 65 72 20 7a 4f 75 74 20 77 69 74   buffer zOut wit
3740: 68 20 74 68 65 20 66 75 6c 6c 20 63 61 6e 6f 6e  h the full canon
3750: 69 63 61 6c 20 70 61 74 68 6e 61 6d 65 20 63 6f  ical pathname co
3760: 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 74  rresponding.** t
3770: 6f 20 74 68 65 20 70 61 74 68 6e 61 6d 65 20 69  o the pathname i
3780: 6e 20 7a 50 61 74 68 2e 20 7a 4f 75 74 20 69 73  n zPath. zOut is
3790: 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 70   guaranteed to p
37a0: 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65 72  oint to a buffer
37b0: 0a 2a 2a 20 6f 66 20 61 74 20 6c 65 61 73 74 20  .** of at least 
37c0: 28 44 45 56 53 59 4d 5f 4d 41 58 5f 50 41 54 48  (DEVSYM_MAX_PATH
37d0: 4e 41 4d 45 2b 31 29 20 62 79 74 65 73 2e 0a 2a  NAME+1) bytes..*
37e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
37f0: 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20  sFullPathname(. 
3800: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
3810: 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  fs, .  const cha
3820: 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74  r *zPath, .  int
3830: 20 6e 4f 75 74 2c 20 0a 20 20 63 68 61 72 20 2a   nOut, .  char *
3840: 7a 4f 75 74 0a 29 7b 0a 20 20 72 65 74 75 72 6e  zOut.){.  return
3850: 20 73 71 6c 69 74 65 33 4f 73 46 75 6c 6c 50 61   sqlite3OsFullPa
3860: 74 68 6e 61 6d 65 28 50 41 52 45 4e 54 56 46 53  thname(PARENTVFS
3870: 28 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 6e  (pVfs), zPath, n
3880: 4f 75 74 2c 20 7a 4f 75 74 29 3b 0a 7d 0a 0a 23  Out, zOut);.}..#
3890: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
38a0: 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f  IT_LOAD_EXTENSIO
38b0: 4e 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 74 68 65  N./*.** Open the
38c0: 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72 79   dynamic library
38d0: 20 6c 6f 63 61 74 65 64 20 61 74 20 7a 50 61 74   located at zPat
38e0: 68 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 68  h and return a h
38f0: 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  andle..*/.static
3900: 20 76 6f 69 64 20 2a 74 76 66 73 44 6c 4f 70 65   void *tvfsDlOpe
3910: 6e 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  n(sqlite3_vfs *p
3920: 56 66 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Vfs, const char 
3930: 2a 7a 50 61 74 68 29 7b 0a 20 20 72 65 74 75 72  *zPath){.  retur
3940: 6e 20 73 71 6c 69 74 65 33 4f 73 44 6c 4f 70 65  n sqlite3OsDlOpe
3950: 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  n(PARENTVFS(pVfs
3960: 29 2c 20 7a 50 61 74 68 29 3b 0a 7d 0a 0a 2f 2a  ), zPath);.}../*
3970: 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 65  .** Populate the
3980: 20 62 75 66 66 65 72 20 7a 45 72 72 4d 73 67 20   buffer zErrMsg 
3990: 28 73 69 7a 65 20 6e 42 79 74 65 20 62 79 74 65  (size nByte byte
39a0: 73 29 20 77 69 74 68 20 61 20 68 75 6d 61 6e 20  s) with a human 
39b0: 72 65 61 64 61 62 6c 65 0a 2a 2a 20 75 74 66 2d  readable.** utf-
39c0: 38 20 73 74 72 69 6e 67 20 64 65 73 63 72 69 62  8 string describ
39d0: 69 6e 67 20 74 68 65 20 6d 6f 73 74 20 72 65 63  ing the most rec
39e0: 65 6e 74 20 65 72 72 6f 72 20 65 6e 63 6f 75 6e  ent error encoun
39f0: 74 65 72 65 64 20 61 73 73 6f 63 69 61 74 65 64  tered associated
3a00: 20 0a 2a 2a 20 77 69 74 68 20 64 79 6e 61 6d 69   .** with dynami
3a10: 63 20 6c 69 62 72 61 72 69 65 73 2e 0a 2a 2f 0a  c libraries..*/.
3a20: 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73  static void tvfs
3a30: 44 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f  DlError(sqlite3_
3a40: 76 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e  vfs *pVfs, int n
3a50: 42 79 74 65 2c 20 63 68 61 72 20 2a 7a 45 72 72  Byte, char *zErr
3a60: 4d 73 67 29 7b 0a 20 20 73 71 6c 69 74 65 33 4f  Msg){.  sqlite3O
3a70: 73 44 6c 45 72 72 6f 72 28 50 41 52 45 4e 54 56  sDlError(PARENTV
3a80: 46 53 28 70 56 66 73 29 2c 20 6e 42 79 74 65 2c  FS(pVfs), nByte,
3a90: 20 7a 45 72 72 4d 73 67 29 3b 0a 7d 0a 0a 2f 2a   zErrMsg);.}../*
3aa0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
3ab0: 6e 74 65 72 20 74 6f 20 74 68 65 20 73 79 6d 62  nter to the symb
3ac0: 6f 6c 20 7a 53 79 6d 62 6f 6c 20 69 6e 20 74 68  ol zSymbol in th
3ad0: 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72  e dynamic librar
3ae0: 79 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  y pHandle..*/.st
3af0: 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66 73  atic void (*tvfs
3b00: 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76 66  DlSym(sqlite3_vf
3b10: 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70  s *pVfs, void *p
3b20: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53  , const char *zS
3b30: 79 6d 29 29 28 76 6f 69 64 29 7b 0a 20 20 72 65  ym))(void){.  re
3b40: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 44 6c  turn sqlite3OsDl
3b50: 53 79 6d 28 50 41 52 45 4e 54 56 46 53 28 70 56  Sym(PARENTVFS(pV
3b60: 66 73 29 2c 20 70 2c 20 7a 53 79 6d 29 3b 0a 7d  fs), p, zSym);.}
3b70: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68  ../*.** Close th
3b80: 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72  e dynamic librar
3b90: 79 20 68 61 6e 64 6c 65 20 70 48 61 6e 64 6c 65  y handle pHandle
3ba0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
3bb0: 20 74 76 66 73 44 6c 43 6c 6f 73 65 28 73 71 6c   tvfsDlClose(sql
3bc0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
3bd0: 76 6f 69 64 20 2a 70 48 61 6e 64 6c 65 29 7b 0a  void *pHandle){.
3be0: 20 20 73 71 6c 69 74 65 33 4f 73 44 6c 43 6c 6f    sqlite3OsDlClo
3bf0: 73 65 28 50 41 52 45 4e 54 56 46 53 28 70 56 66  se(PARENTVFS(pVf
3c00: 73 29 2c 20 70 48 61 6e 64 6c 65 29 3b 0a 7d 0a  s), pHandle);.}.
3c10: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
3c20: 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e  _OMIT_LOAD_EXTEN
3c30: 53 49 4f 4e 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50  SION */../*.** P
3c40: 6f 70 75 6c 61 74 65 20 74 68 65 20 62 75 66 66  opulate the buff
3c50: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
3c60: 20 7a 42 75 66 4f 75 74 20 77 69 74 68 20 6e 42   zBufOut with nB
3c70: 79 74 65 20 62 79 74 65 73 20 6f 66 20 0a 2a 2a  yte bytes of .**
3c80: 20 72 61 6e 64 6f 6d 20 64 61 74 61 2e 0a 2a 2f   random data..*/
3c90: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3ca0: 52 61 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74  Randomness(sqlit
3cb0: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69 6e  e3_vfs *pVfs, in
3cc0: 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a 7a  t nByte, char *z
3cd0: 42 75 66 4f 75 74 29 7b 0a 20 20 72 65 74 75 72  BufOut){.  retur
3ce0: 6e 20 73 71 6c 69 74 65 33 4f 73 52 61 6e 64 6f  n sqlite3OsRando
3cf0: 6d 6e 65 73 73 28 50 41 52 45 4e 54 56 46 53 28  mness(PARENTVFS(
3d00: 70 56 66 73 29 2c 20 6e 42 79 74 65 2c 20 7a 42  pVfs), nByte, zB
3d10: 75 66 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ufOut);.}../*.**
3d20: 20 53 6c 65 65 70 20 66 6f 72 20 6e 4d 69 63 72   Sleep for nMicr
3d30: 6f 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 2e 20  o microseconds. 
3d40: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
3d50: 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f 6e 64  r of microsecond
3d60: 73 20 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 73  s .** actually s
3d70: 6c 65 70 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lept..*/.static 
3d80: 69 6e 74 20 74 76 66 73 53 6c 65 65 70 28 73 71  int tvfsSleep(sq
3d90: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
3da0: 20 69 6e 74 20 6e 4d 69 63 72 6f 29 7b 0a 20 20   int nMicro){.  
3db0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
3dc0: 53 6c 65 65 70 28 50 41 52 45 4e 54 56 46 53 28  Sleep(PARENTVFS(
3dd0: 70 56 66 73 29 2c 20 6e 4d 69 63 72 6f 29 3b 0a  pVfs), nMicro);.
3de0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
3df0: 74 68 65 20 63 75 72 72 65 6e 74 20 74 69 6d 65  the current time
3e00: 20 61 73 20 61 20 4a 75 6c 69 61 6e 20 44 61 79   as a Julian Day
3e10: 20 6e 75 6d 62 65 72 20 69 6e 20 2a 70 54 69 6d   number in *pTim
3e20: 65 4f 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eOut..*/.static 
3e30: 69 6e 74 20 74 76 66 73 43 75 72 72 65 6e 74 54  int tvfsCurrentT
3e40: 69 6d 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ime(sqlite3_vfs 
3e50: 2a 70 56 66 73 2c 20 64 6f 75 62 6c 65 20 2a 70  *pVfs, double *p
3e60: 54 69 6d 65 4f 75 74 29 7b 0a 20 20 72 65 74 75  TimeOut){.  retu
3e70: 72 6e 20 50 41 52 45 4e 54 56 46 53 28 70 56 66  rn PARENTVFS(pVf
3e80: 73 29 2d 3e 78 43 75 72 72 65 6e 74 54 69 6d 65  s)->xCurrentTime
3e90: 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29  (PARENTVFS(pVfs)
3ea0: 2c 20 70 54 69 6d 65 4f 75 74 29 3b 0a 7d 0a 0a  , pTimeOut);.}..
3eb0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 49  static int tvfsI
3ec0: 6e 6a 65 63 74 49 6f 65 72 72 28 54 65 73 74 76  njectIoerr(Testv
3ed0: 66 73 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 65  fs *p){.  int re
3ee0: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d 3e  t = 0;.  if( p->
3ef0: 69 6f 65 72 72 20 29 7b 0a 20 20 20 20 70 2d 3e  ioerr ){.    p->
3f00: 69 49 6f 65 72 72 43 6e 74 2d 2d 3b 0a 20 20 20  iIoerrCnt--;.   
3f10: 20 69 66 28 20 70 2d 3e 69 49 6f 65 72 72 43 6e   if( p->iIoerrCn
3f20: 74 3d 3d 30 20 7c 7c 20 28 70 2d 3e 69 49 6f 65  t==0 || (p->iIoe
3f30: 72 72 43 6e 74 3c 30 20 26 26 20 70 2d 3e 69 6f  rrCnt<0 && p->io
3f40: 65 72 72 3d 3d 32 29 20 29 7b 0a 20 20 20 20 20  err==2) ){.     
3f50: 20 72 65 74 20 3d 20 31 3b 0a 20 20 20 20 20 20   ret = 1;.      
3f60: 70 2d 3e 6e 49 6f 65 72 72 46 61 69 6c 2b 2b 3b  p->nIoerrFail++;
3f70: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
3f80: 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73 74 61 74  urn ret;.}..stat
3f90: 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d 4f 70  ic int tvfsShmOp
3fa0: 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  en(.  sqlite3_fi
3fb0: 6c 65 20 2a 70 46 69 6c 65 44 65 73 0a 29 7b 0a  le *pFileDes.){.
3fc0: 20 20 54 65 73 74 76 66 73 20 2a 70 3b 0a 20 20    Testvfs *p;.  
3fd0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
3fe0: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
3ff0: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
4000: 2f 0a 20 20 54 65 73 74 76 66 73 42 75 66 66 65  /.  TestvfsBuffe
4010: 72 20 2a 70 42 75 66 66 65 72 3b 20 20 20 20 20  r *pBuffer;     
4020: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f      /* Buffer to
4030: 20 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e   open connection
4040: 20 74 6f 20 2a 2f 0a 20 20 54 65 73 74 76 66 73   to */.  Testvfs
4050: 46 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20 20  File *pFd;      
4060: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4070: 74 65 73 74 76 66 73 20 66 69 6c 65 20 73 74 72  testvfs file str
4080: 75 63 74 75 72 65 20 2a 2f 0a 0a 20 20 70 46 64  ucture */..  pFd
4090: 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65 2a   = (TestvfsFile*
40a0: 29 70 46 69 6c 65 44 65 73 3b 0a 20 20 70 20 3d  )pFileDes;.  p =
40b0: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
40c0: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
40d0: 0a 20 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e  .  assert( pFd->
40e0: 70 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70  pShmId && pFd->p
40f0: 53 68 6d 3d 3d 30 20 26 26 20 70 46 64 2d 3e 70  Shm==0 && pFd->p
4100: 4e 65 78 74 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a  Next==0 );..  /*
4110: 20 45 76 61 6c 75 61 74 65 20 74 68 65 20 54 63   Evaluate the Tc
4120: 6c 20 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a  l script: .  **.
4130: 20 20 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53    **   SCRIPT xS
4140: 68 6d 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45 0a  hmOpen FILENAME.
4150: 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74    */.  Tcl_Reset
4160: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
4170: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  );.  if( p->pScr
4180: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
4190: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
41a0: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
41b0: 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4f  xecTcl(p, "xShmO
41c0: 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pen", Tcl_NewStr
41d0: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c  ingObj(pFd->zFil
41e0: 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30 2c 20 30  ename, -1), 0, 0
41f0: 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52  );.    if( tvfsR
4200: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
4210: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72  ) ){.      if( r
4220: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
4230: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
4240: 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72    }..  assert( r
4250: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
4260: 20 20 69 66 28 20 70 2d 3e 6d 61 73 6b 26 54 45    if( p->mask&TE
4270: 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41  STVFS_SHMOPEN_MA
4280: 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74  SK && tvfsInject
4290: 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20  Ioerr(p) ){.    
42a0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
42b0: 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  ERR;.  }..  /* S
42c0: 65 61 72 63 68 20 66 6f 72 20 61 20 54 65 73 74  earch for a Test
42d0: 76 66 73 42 75 66 66 65 72 2e 20 43 72 65 61 74  vfsBuffer. Creat
42e0: 65 20 61 20 6e 65 77 20 6f 6e 65 20 69 66 20 72  e a new one if r
42f0: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 66 6f  equired. */.  fo
4300: 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75  r(pBuffer=p->pBu
4310: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70  ffer; pBuffer; p
4320: 42 75 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e  Buffer=pBuffer->
4330: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
4340: 30 3d 3d 73 74 72 63 6d 70 28 70 46 64 2d 3e 7a  0==strcmp(pFd->z
4350: 46 69 6c 65 6e 61 6d 65 2c 20 70 42 75 66 66 65  Filename, pBuffe
4360: 72 2d 3e 7a 46 69 6c 65 29 20 29 20 62 72 65 61  r->zFile) ) brea
4370: 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 21 70 42  k;.  }.  if( !pB
4380: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 69 6e 74  uffer ){.    int
4390: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
43a0: 54 65 73 74 76 66 73 42 75 66 66 65 72 29 20 2b  TestvfsBuffer) +
43b0: 20 73 74 72 6c 65 6e 28 70 46 64 2d 3e 7a 46 69   strlen(pFd->zFi
43c0: 6c 65 6e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 20  lename) + 1;.   
43d0: 20 70 42 75 66 66 65 72 20 3d 20 28 54 65 73 74   pBuffer = (Test
43e0: 76 66 73 42 75 66 66 65 72 20 2a 29 63 6b 61 6c  vfsBuffer *)ckal
43f0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
4400: 6d 65 6d 73 65 74 28 70 42 75 66 66 65 72 2c 20  memset(pBuffer, 
4410: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  0, nByte);.    p
4420: 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 20 3d 20  Buffer->zFile = 
4430: 28 63 68 61 72 20 2a 29 26 70 42 75 66 66 65 72  (char *)&pBuffer
4440: 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28  [1];.    strcpy(
4450: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
4460: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b  pFd->zFilename);
4470: 0a 20 20 20 20 70 42 75 66 66 65 72 2d 3e 70 4e  .    pBuffer->pN
4480: 65 78 74 20 3d 20 70 2d 3e 70 42 75 66 66 65 72  ext = p->pBuffer
4490: 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66 66 65 72  ;.    p->pBuffer
44a0: 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 7d 0a   = pBuffer;.  }.
44b0: 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74 20 74 68  .  /* Connect th
44c0: 65 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e TestvfsBuffer 
44d0: 74 6f 20 74 68 65 20 6e 65 77 20 54 65 73 74 76  to the new Testv
44e0: 66 73 53 68 6d 20 68 61 6e 64 6c 65 20 61 6e 64  fsShm handle and
44f0: 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 70 46   return. */.  pF
4500: 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42 75 66 66  d->pNext = pBuff
4510: 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20 70 42 75  er->pFile;.  pBu
4520: 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46  ffer->pFile = pF
4530: 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d  d;.  pFd->pShm =
4540: 20 70 42 75 66 66 65 72 3b 0a 20 20 72 65 74 75   pBuffer;.  retu
4550: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
4560: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
4570: 53 68 6d 53 69 7a 65 28 0a 20 20 73 71 6c 69 74  ShmSize(.  sqlit
4580: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a  e3_file *pFile,.
4590: 20 20 69 6e 74 20 72 65 71 53 69 7a 65 2c 0a 20    int reqSize,. 
45a0: 20 69 6e 74 20 2a 70 4e 65 77 53 69 7a 65 0a 29   int *pNewSize.)
45b0: 7b 0a 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20  {.  assert(0);. 
45c0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
45d0: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
45e0: 74 76 66 73 53 68 6d 47 65 74 28 0a 20 20 73 71  tvfsShmGet(.  sq
45f0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
4600: 65 2c 20 0a 20 20 69 6e 74 20 72 65 71 4d 61 70  e, .  int reqMap
4610: 53 69 7a 65 2c 20 0a 20 20 69 6e 74 20 2a 70 4d  Size, .  int *pM
4620: 61 70 53 69 7a 65 2c 20 0a 20 20 76 6f 6c 61 74  apSize, .  volat
4630: 69 6c 65 20 76 6f 69 64 20 2a 2a 70 70 0a 29 7b  ile void **pp.){
4640: 0a 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20 20  .  assert(0);.  
4650: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4660: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 74  ;.}.static int t
4670: 76 66 73 53 68 6d 52 65 6c 65 61 73 65 28 73 71  vfsShmRelease(sq
4680: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
4690: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 30 29 3b  e){.  assert(0);
46a0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
46b0: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  _OK;.}..static v
46c0: 6f 69 64 20 74 76 66 73 41 6c 6c 6f 63 50 61 67  oid tvfsAllocPag
46d0: 65 28 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e(TestvfsBuffer 
46e0: 2a 70 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 69  *p, int iPage, i
46f0: 6e 74 20 70 67 73 7a 29 7b 0a 20 20 61 73 73 65  nt pgsz){.  asse
4700: 72 74 28 20 69 50 61 67 65 3c 54 45 53 54 56 46  rt( iPage<TESTVF
4710: 53 5f 4d 41 58 5f 50 41 47 45 53 20 29 3b 0a 20  S_MAX_PAGES );. 
4720: 20 69 66 28 20 70 2d 3e 61 50 61 67 65 5b 69 50   if( p->aPage[iP
4730: 61 67 65 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 70  age]==0 ){.    p
4740: 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 20 3d  ->aPage[iPage] =
4750: 20 28 75 38 20 2a 29 63 6b 61 6c 6c 6f 63 28 70   (u8 *)ckalloc(p
4760: 67 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74  gsz);.    memset
4770: 28 70 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d  (p->aPage[iPage]
4780: 2c 20 30 2c 20 70 67 73 7a 29 3b 0a 20 20 20 20  , 0, pgsz);.    
4790: 70 2d 3e 70 67 73 7a 20 3d 20 70 67 73 7a 3b 0a  p->pgsz = pgsz;.
47a0: 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e    }.}..static in
47b0: 74 20 74 76 66 73 53 68 6d 50 61 67 65 28 0a 20  t tvfsShmPage(. 
47c0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
47d0: 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  File,           
47e0: 20 2f 2a 20 48 61 6e 64 6c 65 20 6f 70 65 6e 20   /* Handle open 
47f0: 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  on database file
4800: 20 2a 2f 0a 20 20 69 6e 74 20 69 50 61 67 65 2c   */.  int iPage,
4810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4820: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 74 6f        /* Page to
4830: 20 72 65 74 72 69 65 76 65 20 2a 2f 0a 20 20 69   retrieve */.  i
4840: 6e 74 20 70 67 73 7a 2c 20 20 20 20 20 20 20 20  nt pgsz,        
4850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4860: 2a 20 53 69 7a 65 20 6f 66 20 70 61 67 65 73 20  * Size of pages 
4870: 2a 2f 0a 20 20 69 6e 74 20 69 73 57 72 69 74 65  */.  int isWrite
4880: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
4890: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
48a0: 65 78 74 65 6e 64 20 66 69 6c 65 20 69 66 20 6e  extend file if n
48b0: 65 63 65 73 73 61 72 79 20 2a 2f 0a 20 20 76 6f  ecessary */.  vo
48c0: 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 70 70  id volatile **pp
48d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
48e0: 20 4f 55 54 3a 20 4d 61 70 70 65 64 20 6d 65 6d   OUT: Mapped mem
48f0: 6f 72 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ory */.){.  int 
4900: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
4910: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
4920: 46 64 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c  Fd = (TestvfsFil
4930: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73  e *)pFile;.  Tes
4940: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
4950: 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d  fs *)(pFd->pVfs-
4960: 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69  >pAppData);..  i
4970: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
4980: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
4990: 5f 53 48 4d 50 41 47 45 5f 4d 41 53 4b 20 29 7b  _SHMPAGE_MASK ){
49a0: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 41  .    Tcl_Obj *pA
49b0: 72 67 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28  rg = Tcl_NewObj(
49c0: 29 3b 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52  );.    Tcl_IncrR
49d0: 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a 20  efCount(pArg);. 
49e0: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
49f0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69  pendElement(p->i
4a00: 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c  nterp, pArg, Tcl
4a10: 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 50 61 67 65  _NewIntObj(iPage
4a20: 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74  ));.    Tcl_List
4a30: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
4a40: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41 72 67  (p->interp, pArg
4a50: 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28  , Tcl_NewIntObj(
4a60: 70 67 73 7a 29 29 3b 0a 20 20 20 20 54 63 6c 5f  pgsz));.    Tcl_
4a70: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
4a80: 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ment(p->interp, 
4a90: 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pArg, Tcl_NewInt
4aa0: 4f 62 6a 28 69 73 57 72 69 74 65 29 29 3b 0a 20  Obj(isWrite));. 
4ab0: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
4ac0: 2c 20 22 78 53 68 6d 50 61 67 65 22 2c 20 0a 20  , "xShmPage", . 
4ad0: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
4ae0: 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68  ringObj(pFd->pSh
4af0: 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70  m->zFile, -1), p
4b00: 46 64 2d 3e 70 53 68 6d 49 64 2c 20 70 41 72 67  Fd->pShmId, pArg
4b10: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
4b20: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
4b30: 63 29 3b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72  c);.    Tcl_Decr
4b40: 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a  RefCount(pArg);.
4b50: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
4b60: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61  LITE_OK && p->ma
4b70: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 50 41  sk&TESTVFS_SHMPA
4b80: 47 45 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49  GE_MASK && tvfsI
4b90: 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b  njectIoerr(p) ){
4ba0: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
4bb0: 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69  _IOERR;.  }..  i
4bc0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4bd0: 20 26 26 20 69 73 57 72 69 74 65 20 26 26 20 21   && isWrite && !
4be0: 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65  pFd->pShm->aPage
4bf0: 5b 69 50 61 67 65 5d 20 29 7b 0a 20 20 20 20 74  [iPage] ){.    t
4c00: 76 66 73 41 6c 6c 6f 63 50 61 67 65 28 70 46 64  vfsAllocPage(pFd
4c10: 2d 3e 70 53 68 6d 2c 20 69 50 61 67 65 2c 20 70  ->pShm, iPage, p
4c20: 67 73 7a 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20  gsz);.  }.  *pp 
4c30: 3d 20 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65  = (void volatile
4c40: 20 2a 29 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50   *)pFd->pShm->aP
4c50: 61 67 65 5b 69 50 61 67 65 5d 3b 0a 0a 20 20 72  age[iPage];..  r
4c60: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74  eturn rc;.}...st
4c70: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
4c80: 4c 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f  Lock(.  sqlite3_
4c90: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69  file *pFile,.  i
4ca0: 6e 74 20 6f 66 73 74 2c 0a 20 20 69 6e 74 20 6e  nt ofst,.  int n
4cb0: 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 0a 29 7b  ,.  int flags.){
4cc0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
4cd0: 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73  TE_OK;.  Testvfs
4ce0: 46 69 6c 65 20 2a 70 46 64 20 3d 20 28 54 65 73  File *pFd = (Tes
4cf0: 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65  tvfsFile *)pFile
4d00: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
4d10: 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64   (Testvfs *)(pFd
4d20: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
4d30: 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b 0a  );.  int nLock;.
4d40: 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 38 30 5d    char zLock[80]
4d50: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
4d60: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
4d70: 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d  ESTVFS_SHMLOCK_M
4d80: 41 53 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ASK ){.    sqlit
4d90: 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65  e3_snprintf(size
4da0: 6f 66 28 7a 4c 6f 63 6b 29 2c 20 7a 4c 6f 63 6b  of(zLock), zLock
4db0: 2c 20 22 25 64 20 25 64 22 2c 20 6f 66 73 74 2c  , "%d %d", ofst,
4dc0: 20 6e 29 3b 0a 20 20 20 20 6e 4c 6f 63 6b 20 3d   n);.    nLock =
4dd0: 20 73 74 72 6c 65 6e 28 7a 4c 6f 63 6b 29 3b 0a   strlen(zLock);.
4de0: 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 26 20      if( flags & 
4df0: 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20  SQLITE_SHM_LOCK 
4e00: 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79 28  ){.      strcpy(
4e10: 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22  &zLock[nLock], "
4e20: 20 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d 65 6c   lock");.    }el
4e30: 73 65 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79  se{.      strcpy
4e40: 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20  (&zLock[nLock], 
4e50: 22 20 75 6e 6c 6f 63 6b 22 29 3b 0a 20 20 20 20  " unlock");.    
4e60: 7d 0a 20 20 20 20 6e 4c 6f 63 6b 20 2b 3d 20 73  }.    nLock += s
4e70: 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f  trlen(&zLock[nLo
4e80: 63 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20 66 6c  ck]);.    if( fl
4e90: 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d  ags & SQLITE_SHM
4ea0: 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20 20 20  _SHARED ){.     
4eb0: 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e   strcpy(&zLock[n
4ec0: 4c 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65 64 22  Lock], " shared"
4ed0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
4ee0: 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63      strcpy(&zLoc
4ef0: 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78 63 6c  k[nLock], " excl
4f00: 75 73 69 76 65 22 29 3b 0a 20 20 20 20 7d 0a 20  usive");.    }. 
4f10: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
4f20: 2c 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 0a 20  , "xShmLock", . 
4f30: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
4f40: 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68  ringObj(pFd->pSh
4f50: 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70  m->zFile, -1), p
4f60: 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20 20 20  Fd->pShmId,.    
4f70: 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e      Tcl_NewStrin
4f80: 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31 29 0a  gObj(zLock, -1).
4f90: 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52      );.    tvfsR
4fa0: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
4fb0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  );.  }..  if( rc
4fc0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
4fd0: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
4fe0: 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 26 26 20 74  HMLOCK_MASK && t
4ff0: 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70  vfsInjectIoerr(p
5000: 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  ) ){.    rc = SQ
5010: 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a  LITE_IOERR;.  }.
5020: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
5030: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  E_OK ){.    int 
5040: 69 73 4c 6f 63 6b 20 3d 20 28 66 6c 61 67 73 20  isLock = (flags 
5050: 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43  & SQLITE_SHM_LOC
5060: 4b 29 3b 0a 20 20 20 20 69 6e 74 20 69 73 45 78  K);.    int isEx
5070: 63 6c 20 3d 20 28 66 6c 61 67 73 20 26 20 53 51  cl = (flags & SQ
5080: 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49  LITE_SHM_EXCLUSI
5090: 56 45 29 3b 0a 20 20 20 20 75 33 32 20 6d 61 73  VE);.    u32 mas
50a0: 6b 20 3d 20 28 28 28 31 3c 3c 6e 29 2d 31 29 20  k = (((1<<n)-1) 
50b0: 3c 3c 20 6f 66 73 74 29 3b 0a 20 20 20 20 69 66  << ofst);.    if
50c0: 28 20 69 73 4c 6f 63 6b 20 29 7b 0a 20 20 20 20  ( isLock ){.    
50d0: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
50e0: 32 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 32 3d  2;.      for(p2=
50f0: 70 46 64 2d 3e 70 53 68 6d 2d 3e 70 46 69 6c 65  pFd->pShm->pFile
5100: 3b 20 70 32 3b 20 70 32 3d 70 32 2d 3e 70 4e 65  ; p2; p2=p2->pNe
5110: 78 74 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  xt){.        if(
5120: 20 70 32 3d 3d 70 46 64 20 29 20 63 6f 6e 74 69   p2==pFd ) conti
5130: 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28  nue;.        if(
5140: 20 28 70 32 2d 3e 65 78 63 6c 6c 6f 63 6b 26 6d   (p2->excllock&m
5150: 61 73 6b 29 20 7c 7c 20 28 69 73 45 78 63 6c 20  ask) || (isExcl 
5160: 26 26 20 70 32 2d 3e 73 68 61 72 65 64 6c 6f 63  && p2->sharedloc
5170: 6b 26 6d 61 73 6b 29 20 29 7b 0a 20 20 20 20 20  k&mask) ){.     
5180: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
5190: 5f 42 55 53 59 3b 0a 20 20 20 20 20 20 20 20 20  _BUSY;.         
51a0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
51b0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
51c0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
51d0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  K ){.        if(
51e0: 20 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e   isExcl )  pFd->
51f0: 65 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b  excllock |= mask
5200: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 69  ;.        if( !i
5210: 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61  sExcl ) pFd->sha
5220: 72 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b  redlock |= mask;
5230: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
5240: 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 69 73  se{.      if( is
5250: 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65 78 63  Excl )  pFd->exc
5260: 6c 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29  llock &= (~mask)
5270: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69 73 45  ;.      if( !isE
5280: 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72 65  xcl ) pFd->share
5290: 64 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29  dlock &= (~mask)
52a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
52b0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
52c0: 74 69 63 20 76 6f 69 64 20 74 76 66 73 53 68 6d  tic void tvfsShm
52d0: 42 61 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f  Barrier(sqlite3_
52e0: 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20  file *pFile){.  
52f0: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70 46 64  TestvfsFile *pFd
5300: 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65 20   = (TestvfsFile 
5310: 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73 74 76  *)pFile;.  Testv
5320: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
5330: 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70   *)(pFd->pVfs->p
5340: 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69 66 28  AppData);..  if(
5350: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
5360: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
5370: 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 29  HMBARRIER_MASK )
5380: 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63  {.    tvfsExecTc
5390: 6c 28 70 2c 20 22 78 53 68 6d 42 61 72 72 69 65  l(p, "xShmBarrie
53a0: 72 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  r", .        Tcl
53b0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
53c0: 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20  d->pShm->zFile, 
53d0: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
53e0: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 7d  , 0.    );.  }.}
53f0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ..static int tvf
5400: 73 53 68 6d 43 6c 6f 73 65 28 0a 20 20 73 71 6c  sShmClose(.  sql
5410: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
5420: 2c 0a 20 20 69 6e 74 20 64 65 6c 65 74 65 46 6c  ,.  int deleteFl
5430: 61 67 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ag.){.  int rc =
5440: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
5450: 73 74 76 66 73 46 69 6c 65 20 2a 70 46 64 20 3d  stvfsFile *pFd =
5460: 20 28 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29   (TestvfsFile *)
5470: 70 46 69 6c 65 3b 0a 20 20 54 65 73 74 76 66 73  pFile;.  Testvfs
5480: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
5490: 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70  )(pFd->pVfs->pAp
54a0: 70 44 61 74 61 29 3b 0a 20 20 54 65 73 74 76 66  pData);.  Testvf
54b0: 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  sBuffer *pBuffer
54c0: 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b 0a 20 20   = pFd->pShm;.  
54d0: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 2a 70 70  TestvfsFile **pp
54e0: 46 64 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  Fd;..  assert( p
54f0: 46 64 2d 3e 70 53 68 6d 49 64 20 26 26 20 70 46  Fd->pShmId && pF
5500: 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a 20 20 69 66  d->pShm );..  if
5510: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
5520: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
5530: 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 29 7b  SHMCLOSE_MASK ){
5540: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
5550: 28 70 2c 20 22 78 53 68 6d 43 6c 6f 73 65 22 2c  (p, "xShmClose",
5560: 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65   .        Tcl_Ne
5570: 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e  wStringObj(pFd->
5580: 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29  pShm->zFile, -1)
5590: 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30  , pFd->pShmId, 0
55a0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
55b0: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
55c0: 63 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70  c);.  }..  for(p
55d0: 70 46 64 3d 26 70 42 75 66 66 65 72 2d 3e 70 46  pFd=&pBuffer->pF
55e0: 69 6c 65 3b 20 2a 70 70 46 64 21 3d 70 46 64 3b  ile; *ppFd!=pFd;
55f0: 20 70 70 46 64 3d 26 28 28 2a 70 70 46 64 29 2d   ppFd=&((*ppFd)-
5600: 3e 70 4e 65 78 74 29 29 3b 0a 20 20 61 73 73 65  >pNext));.  asse
5610: 72 74 28 20 28 2a 70 70 46 64 29 3d 3d 70 46 64  rt( (*ppFd)==pFd
5620: 20 29 3b 0a 20 20 2a 70 70 46 64 20 3d 20 70 46   );.  *ppFd = pF
5630: 64 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 69 66 28  d->pNext;..  if(
5640: 20 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65 3d   pBuffer->pFile=
5650: 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b  =0 ){.    int i;
5660: 0a 20 20 20 20 54 65 73 74 76 66 73 42 75 66 66  .    TestvfsBuff
5670: 65 72 20 2a 2a 70 70 3b 0a 20 20 20 20 66 6f 72  er **pp;.    for
5680: 28 70 70 3d 26 70 2d 3e 70 42 75 66 66 65 72 3b  (pp=&p->pBuffer;
5690: 20 2a 70 70 21 3d 70 42 75 66 66 65 72 3b 20 70   *pp!=pBuffer; p
56a0: 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74  p=&((*pp)->pNext
56b0: 29 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20 28 2a  ));.    *pp = (*
56c0: 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  pp)->pNext;.    
56d0: 66 6f 72 28 69 3d 30 3b 20 70 42 75 66 66 65 72  for(i=0; pBuffer
56e0: 2d 3e 61 50 61 67 65 5b 69 5d 3b 20 69 2b 2b 29  ->aPage[i]; i++)
56f0: 7b 0a 20 20 20 20 20 20 63 6b 66 72 65 65 28 28  {.      ckfree((
5700: 63 68 61 72 20 2a 29 70 42 75 66 66 65 72 2d 3e  char *)pBuffer->
5710: 61 50 61 67 65 5b 69 5d 29 3b 0a 20 20 20 20 7d  aPage[i]);.    }
5720: 0a 20 20 20 20 63 6b 66 72 65 65 28 28 63 68 61  .    ckfree((cha
5730: 72 20 2a 29 70 42 75 66 66 65 72 29 3b 0a 20 20  r *)pBuffer);.  
5740: 7d 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20  }.  pFd->pShm = 
5750: 30 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  0;..  return rc;
5760: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
5770: 65 73 74 76 66 73 5f 6f 62 6a 5f 63 6d 64 28 0a  estvfs_obj_cmd(.
5780: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c    ClientData cd,
5790: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
57a0: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
57b0: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
57c0: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
57d0: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
57e0: 73 74 76 66 73 20 2a 29 63 64 3b 0a 0a 20 20 73  stvfs *)cd;..  s
57f0: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
5800: 20 2a 43 4d 44 5f 73 74 72 73 5b 5d 20 3d 20 7b   *CMD_strs[] = {
5810: 20 0a 20 20 20 20 22 73 68 6d 22 2c 20 20 20 22   .    "shm",   "
5820: 64 65 6c 65 74 65 22 2c 20 20 20 22 66 69 6c 74  delete",   "filt
5830: 65 72 22 2c 20 20 20 22 69 6f 65 72 72 22 2c 20  er",   "ioerr", 
5840: 20 20 22 73 63 72 69 70 74 22 2c 20 30 20 0a 20    "script", 0 . 
5850: 20 7d 3b 0a 20 20 65 6e 75 6d 20 44 42 5f 65 6e   };.  enum DB_en
5860: 75 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f 53 48  um { .    CMD_SH
5870: 4d 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c 20 43  M, CMD_DELETE, C
5880: 4d 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44 5f 49  MD_FILTER, CMD_I
5890: 4f 45 52 52 2c 20 43 4d 44 5f 53 43 52 49 50 54  OERR, CMD_SCRIPT
58a0: 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74 20 69 3b 0a  .  };..  int i;.
58b0: 20 20 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20    .  if( objc<2 
58c0: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
58d0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
58e0: 31 2c 20 6f 62 6a 76 2c 20 22 53 55 42 43 4f 4d  1, objv, "SUBCOM
58f0: 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20 20 20  MAND ...");.    
5900: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
5910: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f  ;.  }.  if( Tcl_
5920: 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a 28  GetIndexFromObj(
5930: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c  interp, objv[1],
5940: 20 43 4d 44 5f 73 74 72 73 2c 20 22 73 75 62 63   CMD_strs, "subc
5950: 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69 29 20  ommand", 0, &i) 
5960: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  ){.    return TC
5970: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54  L_ERROR;.  }.  T
5980: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
5990: 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77 69 74 63  nterp);..  switc
59a0: 68 28 20 28 65 6e 75 6d 20 44 42 5f 65 6e 75 6d  h( (enum DB_enum
59b0: 29 69 20 29 7b 0a 20 20 20 20 63 61 73 65 20 43  )i ){.    case C
59c0: 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20 20 20 20  MD_SHM: {.      
59d0: 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20  Tcl_Obj *pObj;. 
59e0: 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
59f0: 20 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20    TestvfsBuffer 
5a00: 2a 70 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20  *pBuffer;.      
5a10: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
5a20: 20 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 26     if( objc!=3 &
5a30: 26 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20  & objc!=4 ){.   
5a40: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
5a50: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
5a60: 20 6f 62 6a 76 2c 20 22 46 49 4c 45 20 3f 56 41   objv, "FILE ?VA
5a70: 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20  LUE?");.        
5a80: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
5a90: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
5aa0: 7a 4e 61 6d 65 20 3d 20 63 6b 61 6c 6c 6f 63 28  zName = ckalloc(
5ab0: 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61  p->pParent->mxPa
5ac0: 74 68 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70  thname);.      p
5ad0: 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46 75 6c 6c  ->pParent->xFull
5ae0: 50 61 74 68 6e 61 6d 65 28 0a 20 20 20 20 20 20  Pathname(.      
5af0: 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74 2c 20      p->pParent, 
5b00: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
5b10: 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20 20 20 20  jv[2]), .       
5b20: 20 20 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d     p->pParent->m
5b30: 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e 61 6d 65  xPathname, zName
5b40: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
5b50: 66 6f 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70  for(pBuffer=p->p
5b60: 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b  Buffer; pBuffer;
5b70: 20 70 42 75 66 66 65 72 3d 70 42 75 66 66 65 72   pBuffer=pBuffer
5b80: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
5b90: 20 20 69 66 28 20 30 3d 3d 73 74 72 63 6d 70 28    if( 0==strcmp(
5ba0: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
5bb0: 7a 4e 61 6d 65 29 20 29 20 62 72 65 61 6b 3b 0a  zName) ) break;.
5bc0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 6b        }.      ck
5bd0: 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 20  free(zName);.   
5be0: 20 20 20 69 66 28 20 21 70 42 75 66 66 65 72 20     if( !pBuffer 
5bf0: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41  ){.        Tcl_A
5c00: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
5c10: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 66 69 6c  rp, "no such fil
5c20: 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  e: ", Tcl_GetStr
5c30: 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29  ing(objv[2]), 0)
5c40: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
5c50: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
5c60: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f 62    }.      if( ob
5c70: 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20 20  jc==4 ){.       
5c80: 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20   int n;.        
5c90: 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47 65 74 42  u8 *a = Tcl_GetB
5ca0: 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28  yteArrayFromObj(
5cb0: 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b 0a 20 20  objv[3], &n);.  
5cc0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 42        assert( pB
5cd0: 75 66 66 65 72 2d 3e 70 67 73 7a 3d 3d 30 20 7c  uffer->pgsz==0 |
5ce0: 7c 20 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3d  | pBuffer->pgsz=
5cf0: 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20 20 20  =32768 );.      
5d00: 20 20 66 6f 72 28 69 3d 30 3b 20 69 2a 33 32 37    for(i=0; i*327
5d10: 36 38 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  68<n; i++){.    
5d20: 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
5d30: 3d 20 33 32 37 36 38 3b 0a 20 20 20 20 20 20 20  = 32768;.       
5d40: 20 20 20 74 76 66 73 41 6c 6c 6f 63 50 61 67 65     tvfsAllocPage
5d50: 28 70 42 75 66 66 65 72 2c 20 69 2c 20 33 32 37  (pBuffer, i, 327
5d60: 36 38 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  68);.          i
5d70: 66 28 20 6e 2d 69 2a 33 32 37 36 38 3c 33 32 37  f( n-i*32768<327
5d80: 36 38 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  68 ){.          
5d90: 20 20 6e 42 79 74 65 20 3d 20 6e 3b 0a 20 20 20    nByte = n;.   
5da0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5db0: 20 20 20 6d 65 6d 63 70 79 28 70 42 75 66 66 65     memcpy(pBuffe
5dc0: 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20 26 61 5b  r->aPage[i], &a[
5dd0: 69 2a 33 32 37 36 38 5d 2c 20 6e 42 79 74 65 29  i*32768], nByte)
5de0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
5df0: 20 20 7d 0a 0a 20 20 20 20 20 20 70 4f 62 6a 20    }..      pObj 
5e00: 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a  = Tcl_NewObj();.
5e10: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 70        for(i=0; p
5e20: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
5e30: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
5e40: 54 63 6c 5f 41 70 70 65 6e 64 4f 62 6a 54 6f 4f  Tcl_AppendObjToO
5e50: 62 6a 28 70 4f 62 6a 2c 20 54 63 6c 5f 4e 65 77  bj(pObj, Tcl_New
5e60: 42 79 74 65 41 72 72 61 79 4f 62 6a 28 70 42 75  ByteArrayObj(pBu
5e70: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20  ffer->aPage[i], 
5e80: 33 32 37 36 38 29 29 3b 0a 20 20 20 20 20 20 7d  32768));.      }
5e90: 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62  .      Tcl_SetOb
5ea0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
5eb0: 70 4f 62 6a 29 3b 0a 20 20 20 20 20 20 62 72 65  pObj);.      bre
5ec0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
5ed0: 61 73 65 20 43 4d 44 5f 46 49 4c 54 45 52 3a 20  ase CMD_FILTER: 
5ee0: 7b 0a 20 20 20 20 20 20 73 74 61 74 69 63 20 73  {.      static s
5ef0: 74 72 75 63 74 20 56 66 73 4d 65 74 68 6f 64 20  truct VfsMethod 
5f00: 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a  {.        char *
5f10: 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 69  zName;.        i
5f20: 6e 74 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 7d  nt mask;.      }
5f30: 20 76 66 73 6d 65 74 68 6f 64 20 5b 5d 20 3d 20   vfsmethod [] = 
5f40: 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68  {.        { "xSh
5f50: 6d 4f 70 65 6e 22 2c 20 20 20 20 54 45 53 54 56  mOpen",    TESTV
5f60: 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20  FS_SHMOPEN_MASK 
5f70: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53  },.        { "xS
5f80: 68 6d 53 69 7a 65 22 2c 20 20 20 20 54 45 53 54  hmSize",    TEST
5f90: 56 46 53 5f 53 48 4d 53 49 5a 45 5f 4d 41 53 4b  VFS_SHMSIZE_MASK
5fa0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
5fb0: 53 68 6d 47 65 74 22 2c 20 20 20 20 20 54 45 53  ShmGet",     TES
5fc0: 54 56 46 53 5f 53 48 4d 47 45 54 5f 4d 41 53 4b  TVFS_SHMGET_MASK
5fd0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
5fe0: 53 68 6d 52 65 6c 65 61 73 65 22 2c 20 54 45 53  ShmRelease", TES
5ff0: 54 56 46 53 5f 53 48 4d 52 45 4c 45 41 53 45 5f  TVFS_SHMRELEASE_
6000: 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20  MASK },.        
6010: 7b 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 20 20  { "xShmLock",   
6020: 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b   TESTVFS_SHMLOCK
6030: 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20  _MASK },.       
6040: 20 7b 20 22 78 53 68 6d 42 61 72 72 69 65 72 22   { "xShmBarrier"
6050: 2c 20 54 45 53 54 56 46 53 5f 53 48 4d 42 41 52  , TESTVFS_SHMBAR
6060: 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  RIER_MASK },.   
6070: 20 20 20 20 20 7b 20 22 78 53 68 6d 43 6c 6f 73       { "xShmClos
6080: 65 22 2c 20 20 20 54 45 53 54 56 46 53 5f 53 48  e",   TESTVFS_SH
6090: 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20  MCLOSE_MASK },. 
60a0: 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 50 61         { "xShmPa
60b0: 67 65 22 2c 20 20 20 20 54 45 53 54 56 46 53 5f  ge",    TESTVFS_
60c0: 53 48 4d 50 41 47 45 5f 4d 41 53 4b 20 7d 2c 0a  SHMPAGE_MASK },.
60d0: 20 20 20 20 20 20 20 20 7b 20 22 78 53 79 6e 63          { "xSync
60e0: 22 2c 20 20 20 20 20 20 20 54 45 53 54 56 46 53  ",       TESTVFS
60f0: 5f 53 59 4e 43 5f 4d 41 53 4b 20 7d 2c 0a 20 20  _SYNC_MASK },.  
6100: 20 20 20 20 20 20 7b 20 22 78 4f 70 65 6e 22 2c        { "xOpen",
6110: 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 4f         TESTVFS_O
6120: 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20  PEN_MASK },.    
6130: 20 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4f    };.      Tcl_O
6140: 62 6a 20 2a 2a 61 70 45 6c 65 6d 20 3d 20 30 3b  bj **apElem = 0;
6150: 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6c 65 6d  .      int nElem
6160: 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20   = 0;.      int 
6170: 69 3b 0a 20 20 20 20 20 20 69 6e 74 20 6d 61 73  i;.      int mas
6180: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28  k = 0;.      if(
6190: 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20   objc!=3 ){.    
61a0: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
61b0: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20  Args(interp, 2, 
61c0: 6f 62 6a 76 2c 20 22 4c 49 53 54 22 29 3b 0a 20  objv, "LIST");. 
61d0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
61e0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
61f0: 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 4c  .      if( Tcl_L
6200: 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74  istObjGetElement
6210: 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32  s(interp, objv[2
6220: 5d 2c 20 26 6e 45 6c 65 6d 2c 20 26 61 70 45 6c  ], &nElem, &apEl
6230: 65 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72  em) ){.        r
6240: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
6250: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54  .      }.      T
6260: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
6270: 6e 74 65 72 70 29 3b 0a 20 20 20 20 20 20 66 6f  nterp);.      fo
6280: 72 28 69 3d 30 3b 20 69 3c 6e 45 6c 65 6d 3b 20  r(i=0; i<nElem; 
6290: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  i++){.        in
62a0: 74 20 69 4d 65 74 68 6f 64 3b 0a 20 20 20 20 20  t iMethod;.     
62b0: 20 20 20 63 68 61 72 20 2a 7a 45 6c 65 6d 20 3d     char *zElem =
62c0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61   Tcl_GetString(a
62d0: 70 45 6c 65 6d 5b 69 5d 29 3b 0a 20 20 20 20 20  pElem[i]);.     
62e0: 20 20 20 66 6f 72 28 69 4d 65 74 68 6f 64 3d 30     for(iMethod=0
62f0: 3b 20 69 4d 65 74 68 6f 64 3c 41 72 72 61 79 53  ; iMethod<ArrayS
6300: 69 7a 65 28 76 66 73 6d 65 74 68 6f 64 29 3b 20  ize(vfsmethod); 
6310: 69 4d 65 74 68 6f 64 2b 2b 29 7b 0a 20 20 20 20  iMethod++){.    
6320: 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70        if( strcmp
6330: 28 7a 45 6c 65 6d 2c 20 76 66 73 6d 65 74 68 6f  (zElem, vfsmetho
6340: 64 5b 69 4d 65 74 68 6f 64 5d 2e 7a 4e 61 6d 65  d[iMethod].zName
6350: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
6360: 20 20 20 20 6d 61 73 6b 20 7c 3d 20 76 66 73 6d      mask |= vfsm
6370: 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e 6d  ethod[iMethod].m
6380: 61 73 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ask;.           
6390: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
63a0: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
63b0: 20 20 20 20 20 20 69 66 28 20 69 4d 65 74 68 6f        if( iMetho
63c0: 64 3d 3d 41 72 72 61 79 53 69 7a 65 28 76 66 73  d==ArraySize(vfs
63d0: 6d 65 74 68 6f 64 29 20 29 7b 0a 20 20 20 20 20  method) ){.     
63e0: 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52       Tcl_AppendR
63f0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 75  esult(interp, "u
6400: 6e 6b 6e 6f 77 6e 20 6d 65 74 68 6f 64 3a 20 22  nknown method: "
6410: 2c 20 7a 45 6c 65 6d 2c 20 30 29 3b 0a 20 20 20  , zElem, 0);.   
6420: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
6430: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20  L_ERROR;.       
6440: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
6450: 20 70 2d 3e 6d 61 73 6b 20 3d 20 6d 61 73 6b 3b   p->mask = mask;
6460: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
6470: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d    }..    case CM
6480: 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20 20 20 20  D_SCRIPT: {.    
6490: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
64a0: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79  .        int nBy
64b0: 74 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  te;.        if( 
64c0: 70 2d 3e 70 53 63 72 69 70 74 20 29 7b 0a 20 20  p->pScript ){.  
64d0: 20 20 20 20 20 20 20 20 54 63 6c 5f 44 65 63 72          Tcl_Decr
64e0: 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72  RefCount(p->pScr
64f0: 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ipt);.          
6500: 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70  ckfree((char *)p
6510: 2d 3e 61 70 53 63 72 69 70 74 29 3b 0a 20 20 20  ->apScript);.   
6520: 20 20 20 20 20 20 20 70 2d 3e 61 70 53 63 72 69         p->apScri
6530: 70 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  pt = 0;.        
6540: 20 20 70 2d 3e 6e 53 63 72 69 70 74 20 3d 20 30    p->nScript = 0
6550: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70  ;.          p->p
6560: 53 63 72 69 70 74 20 3d 20 30 3b 0a 20 20 20 20  Script = 0;.    
6570: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 54 63      }.        Tc
6580: 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f  l_GetStringFromO
6590: 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26 6e 42 79  bj(objv[2], &nBy
65a0: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  te);.        if(
65b0: 20 6e 42 79 74 65 3e 30 20 29 7b 0a 20 20 20 20   nByte>0 ){.    
65c0: 20 20 20 20 20 20 70 2d 3e 70 53 63 72 69 70 74        p->pScript
65d0: 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65   = Tcl_Duplicate
65e0: 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29 3b 0a 20 20  Obj(objv[2]);.  
65f0: 20 20 20 20 20 20 20 20 54 63 6c 5f 49 6e 63 72          Tcl_Incr
6600: 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72  RefCount(p->pScr
6610: 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ipt);.        }.
6620: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
6630: 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 20  objc!=2 ){.     
6640: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
6650: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
6660: 62 6a 76 2c 20 22 3f 53 43 52 49 50 54 3f 22 29  bjv, "?SCRIPT?")
6670: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
6680: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
6690: 20 20 7d 0a 0a 20 20 20 20 20 20 54 63 6c 5f 52    }..      Tcl_R
66a0: 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  esetResult(inter
66b0: 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d  p);.      if( p-
66c0: 3e 70 53 63 72 69 70 74 20 29 20 54 63 6c 5f 53  >pScript ) Tcl_S
66d0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
66e0: 72 70 2c 20 70 2d 3e 70 53 63 72 69 70 74 29 3b  rp, p->pScript);
66f0: 0a 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ..      break;. 
6700: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 0a 20 20 20     }..    /*.   
6710: 20 2a 2a 20 54 45 53 54 56 46 53 20 69 6f 65 72   ** TESTVFS ioer
6720: 72 20 3f 49 46 41 49 4c 20 50 45 52 53 49 53 54  r ?IFAIL PERSIST
6730: 3f 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  ?.    **.    ** 
6740: 20 20 57 68 65 72 65 20 49 46 41 49 4c 20 69 73    Where IFAIL is
6750: 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20   an integer and 
6760: 50 45 52 53 49 53 54 20 69 73 20 62 6f 6f 6c 65  PERSIST is boole
6770: 61 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 63  an..    */.    c
6780: 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a 20 7b  ase CMD_IOERR: {
6790: 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65 74 20  .      int iRet 
67a0: 3d 20 70 2d 3e 6e 49 6f 65 72 72 46 61 69 6c 3b  = p->nIoerrFail;
67b0: 0a 0a 20 20 20 20 20 20 70 2d 3e 6e 49 6f 65 72  ..      p->nIoer
67c0: 72 46 61 69 6c 20 3d 20 30 3b 0a 20 20 20 20 20  rFail = 0;.     
67d0: 20 70 2d 3e 69 6f 65 72 72 20 3d 20 30 3b 0a 20   p->ioerr = 0;. 
67e0: 20 20 20 20 20 70 2d 3e 69 49 6f 65 72 72 43 6e       p->iIoerrCn
67f0: 74 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20 69 66  t = 0;..      if
6800: 28 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20  ( objc==4 ){.   
6810: 20 20 20 20 20 69 6e 74 20 69 43 6e 74 2c 20 69       int iCnt, i
6820: 50 65 72 73 69 73 74 3b 0a 20 20 20 20 20 20 20  Persist;.       
6830: 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c   if( TCL_OK!=Tcl
6840: 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  _GetIntFromObj(i
6850: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20  nterp, objv[2], 
6860: 26 69 43 6e 74 29 0a 20 20 20 20 20 20 20 20 20  &iCnt).         
6870: 7c 7c 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47  || TCL_OK!=Tcl_G
6880: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
6890: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 33 5d  (interp, objv[3]
68a0: 2c 20 26 69 50 65 72 73 69 73 74 29 0a 20 20 20  , &iPersist).   
68b0: 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
68c0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
68d0: 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  OR;.        }.  
68e0: 20 20 20 20 20 20 70 2d 3e 69 6f 65 72 72 20 3d        p->ioerr =
68f0: 20 28 69 43 6e 74 3e 30 29 20 2b 20 69 50 65 72   (iCnt>0) + iPer
6900: 73 69 73 74 3b 0a 20 20 20 20 20 20 20 20 70 2d  sist;.        p-
6910: 3e 69 49 6f 65 72 72 43 6e 74 20 3d 20 69 43 6e  >iIoerrCnt = iCn
6920: 74 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  t;.      }else i
6930: 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20  f( objc!=2 ){.  
6940: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
6950: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
6960: 42 61 64 20 61 72 67 73 22 2c 20 30 29 3b 0a 20  Bad args", 0);. 
6970: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
6980: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
6990: 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62  .      Tcl_SetOb
69a0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
69b0: 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 52  Tcl_NewIntObj(iR
69c0: 65 74 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  et));.      brea
69d0: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61  k;.    }..    ca
69e0: 73 65 20 43 4d 44 5f 44 45 4c 45 54 45 3a 20 7b  se CMD_DELETE: {
69f0: 0a 20 20 20 20 20 20 54 63 6c 5f 44 65 6c 65 74  .      Tcl_Delet
6a00: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
6a10: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
6a20: 62 6a 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20  bjv[0]));.      
6a30: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
6a40: 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ..  return TCL_O
6a50: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  K;.}..static voi
6a60: 64 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 64 65  d testvfs_obj_de
6a70: 6c 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 29  l(ClientData cd)
6a80: 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  {.  Testvfs *p =
6a90: 20 28 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a   (Testvfs *)cd;.
6aa0: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
6ab0: 20 29 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f   ) Tcl_DecrRefCo
6ac0: 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b  unt(p->pScript);
6ad0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75  .  sqlite3_vfs_u
6ae0: 6e 72 65 67 69 73 74 65 72 28 70 2d 3e 70 56 66  nregister(p->pVf
6af0: 73 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68  s);.  ckfree((ch
6b00: 61 72 20 2a 29 70 2d 3e 61 70 53 63 72 69 70 74  ar *)p->apScript
6b10: 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61  );.  ckfree((cha
6b20: 72 20 2a 29 70 2d 3e 70 56 66 73 29 3b 0a 20 20  r *)p->pVfs);.  
6b30: 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70  ckfree((char *)p
6b40: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67  );.}../*.** Usag
6b50: 65 3a 20 20 74 65 73 74 76 66 73 20 56 46 53 4e  e:  testvfs VFSN
6b60: 41 4d 45 20 3f 53 57 49 54 43 48 45 53 3f 0a 2a  AME ?SWITCHES?.*
6b70: 2a 0a 2a 2a 20 53 77 69 74 63 68 65 73 20 61 72  *.** Switches ar
6b80: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68  e:.**.**   -nosh
6b90: 6d 20 20 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20  m   BOOLEAN     
6ba0: 20 20 20 20 20 20 20 20 28 54 72 75 65 20 74 6f          (True to
6bb0: 20 6f 6d 69 74 20 73 68 6d 20 6d 65 74 68 6f 64   omit shm method
6bc0: 73 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65  s. Default false
6bd0: 29 0a 2a 2a 20 20 20 2d 64 65 66 61 75 6c 74 20  ).**   -default 
6be0: 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20 20 20  BOOLEAN         
6bf0: 20 20 20 20 28 54 72 75 65 20 74 6f 20 6d 61 6b      (True to mak
6c00: 65 20 74 68 65 20 76 66 73 20 64 65 66 61 75 6c  e the vfs defaul
6c10: 74 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65  t. Default false
6c20: 29 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 6f 6d  ).**.** This com
6c30: 6d 61 6e 64 20 63 72 65 61 74 65 73 20 74 77 6f  mand creates two
6c40: 20 74 68 69 6e 67 73 20 77 68 65 6e 20 69 74 20   things when it 
6c50: 69 73 20 69 6e 76 6f 6b 65 64 3a 20 61 6e 20 53  is invoked: an S
6c60: 51 4c 69 74 65 20 56 46 53 2c 20 61 6e 64 0a 2a  QLite VFS, and.*
6c70: 2a 20 61 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e  * a Tcl command.
6c80: 20 42 6f 74 68 20 61 72 65 20 6e 61 6d 65 64 20   Both are named 
6c90: 56 46 53 4e 41 4d 45 2e 20 54 68 65 20 56 46 53  VFSNAME. The VFS
6ca0: 20 69 73 20 69 6e 73 74 61 6c 6c 65 64 2e 20 49   is installed. I
6cb0: 74 20 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 73 74  t is not.** inst
6cc0: 61 6c 6c 65 64 20 61 73 20 74 68 65 20 64 65 66  alled as the def
6cd0: 61 75 6c 74 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20  ault VFS..**.** 
6ce0: 54 68 65 20 56 46 53 20 70 61 73 73 65 73 20 61  The VFS passes a
6cf0: 6c 6c 20 66 69 6c 65 20 49 2f 4f 20 63 61 6c 6c  ll file I/O call
6d00: 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65  s through to the
6d10: 20 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 2e   underlying VFS.
6d20: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 65 76 65 72 20  .**.** Whenever 
6d30: 6f 6e 65 20 6f 66 20 74 68 65 20 78 53 68 6d 53  one of the xShmS
6d40: 69 7a 65 2c 20 78 53 68 6d 47 65 74 20 6f 72 20  ize, xShmGet or 
6d50: 78 53 68 6d 52 65 6c 65 61 73 65 20 6d 65 74 68  xShmRelease meth
6d60: 6f 64 73 20 6f 66 20 74 68 65 20 56 46 53 0a 2a  ods of the VFS.*
6d70: 2a 20 61 72 65 20 69 6e 76 6f 6b 65 64 2c 20 74  * are invoked, t
6d80: 68 65 20 53 43 52 49 50 54 20 69 73 20 65 78 65  he SCRIPT is exe
6d90: 63 75 74 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73  cuted as follows
6da0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50 54  :.**.**   SCRIPT
6db0: 20 78 53 68 6d 53 69 7a 65 20 20 20 20 46 49 4c   xShmSize    FIL
6dc0: 45 4e 41 4d 45 20 49 44 0a 2a 2a 20 20 20 53 43  ENAME ID.**   SC
6dd0: 52 49 50 54 20 78 53 68 6d 47 65 74 20 20 20 20  RIPT xShmGet    
6de0: 20 46 49 4c 45 4e 41 4d 45 20 49 44 0a 2a 2a 20   FILENAME ID.** 
6df0: 20 20 53 43 52 49 50 54 20 78 53 68 6d 52 65 6c    SCRIPT xShmRel
6e00: 65 61 73 65 20 46 49 4c 45 4e 41 4d 45 20 49 44  ease FILENAME ID
6e10: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65  .**.** The value
6e20: 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68 65   returned by the
6e30: 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20 53   invocation of S
6e40: 43 52 49 50 54 20 61 62 6f 76 65 20 69 73 20 69  CRIPT above is i
6e50: 6e 74 65 72 70 72 65 74 65 64 20 61 73 0a 2a 2a  nterpreted as.**
6e60: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
6e70: 20 63 6f 64 65 20 61 6e 64 20 72 65 74 75 72 6e   code and return
6e80: 65 64 20 74 6f 20 53 51 4c 69 74 65 2e 20 45 69  ed to SQLite. Ei
6e90: 74 68 65 72 20 61 20 73 79 6d 62 6f 6c 69 63 20  ther a symbolic 
6ea0: 0a 2a 2a 20 22 53 51 4c 49 54 45 5f 4f 4b 22 20  .** "SQLITE_OK" 
6eb0: 6f 72 20 6e 75 6d 65 72 69 63 20 22 30 22 20 76  or numeric "0" v
6ec0: 61 6c 75 65 20 6d 61 79 20 62 65 20 72 65 74 75  alue may be retu
6ed0: 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  rned..**.** The 
6ee0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20  contents of the 
6ef0: 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 62 75  shared-memory bu
6f00: 66 66 65 72 20 61 73 73 6f 63 69 61 74 65 64 20  ffer associated 
6f10: 77 69 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c  with a given fil
6f20: 65 0a 2a 2a 20 6d 61 79 20 62 65 20 72 65 61 64  e.** may be read
6f30: 20 61 6e 64 20 73 65 74 20 75 73 69 6e 67 20 74   and set using t
6f40: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6d  he following com
6f50: 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 56 46  mand:.**.**   VF
6f60: 53 4e 41 4d 45 20 73 68 6d 20 46 49 4c 45 4e 41  SNAME shm FILENA
6f70: 4d 45 20 3f 4e 45 57 56 41 4c 55 45 3f 0a 2a 2a  ME ?NEWVALUE?.**
6f80: 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 78 53 68  .** When the xSh
6f90: 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64 20 69 73 20  mLock method is 
6fa0: 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74  invoked by SQLit
6fb0: 65 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  e, the following
6fc0: 20 73 63 72 69 70 74 20 69 73 0a 2a 2a 20 72 75   script is.** ru
6fd0: 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50  n:.**.**   SCRIP
6fe0: 54 20 78 53 68 6d 4c 6f 63 6b 20 20 20 20 46 49  T xShmLock    FI
6ff0: 4c 45 4e 41 4d 45 20 49 44 20 4c 4f 43 4b 0a 2a  LENAME ID LOCK.*
7000: 2a 0a 2a 2a 20 77 68 65 72 65 20 4c 4f 43 4b 20  *.** where LOCK 
7010: 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22  is of the form "
7020: 4f 46 46 53 45 54 20 4e 42 59 54 45 20 6c 6f 63  OFFSET NBYTE loc
7030: 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61 72 65 64 2f  k/unlock shared/
7040: 65 78 63 6c 75 73 69 76 65 22 0a 2a 2f 0a 73 74  exclusive".*/.st
7050: 61 74 69 63 20 69 6e 74 20 74 65 73 74 76 66 73  atic int testvfs
7060: 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61  _cmd(.  ClientDa
7070: 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74  ta cd,.  Tcl_Int
7080: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
7090: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
70a0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
70b0: 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  .){.  static sql
70c0: 69 74 65 33 5f 76 66 73 20 74 76 66 73 5f 76 66  ite3_vfs tvfs_vf
70d0: 73 20 3d 20 7b 0a 20 20 20 20 32 2c 20 20 20 20  s = {.    2,    
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70f0: 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73          /* iVers
7100: 69 6f 6e 20 2a 2f 0a 20 20 20 20 73 69 7a 65 6f  ion */.    sizeo
7110: 66 28 54 65 73 74 76 66 73 46 69 6c 65 29 2c 20  f(TestvfsFile), 
7120: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 7a             /* sz
7130: 4f 73 46 69 6c 65 20 2a 2f 0a 20 20 20 20 30 2c  OsFile */.    0,
7140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7150: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6d              /* m
7160: 78 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 20  xPathname */.   
7170: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
7180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7190: 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20 30  * pNext */.    0
71a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
71b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
71c0: 7a 4e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20  zName */.    0, 
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41             /* pA
71f0: 70 70 44 61 74 61 20 2a 2f 0a 20 20 20 20 74 76  ppData */.    tv
7200: 66 73 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  fsOpen,         
7210: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7220: 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73  Open */.    tvfs
7230: 44 65 6c 65 74 65 2c 20 20 20 20 20 20 20 20 20  Delete,         
7240: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
7250: 6c 65 74 65 20 2a 2f 0a 20 20 20 20 74 76 66 73  lete */.    tvfs
7260: 41 63 63 65 73 73 2c 20 20 20 20 20 20 20 20 20  Access,         
7270: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63            /* xAc
7280: 63 65 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73  cess */.    tvfs
7290: 46 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20  FullPathname,   
72a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 75            /* xFu
72b0: 6c 6c 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 23 69  llPathname */.#i
72c0: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
72d0: 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e  T_LOAD_EXTENSION
72e0: 0a 20 20 20 20 74 76 66 73 44 6c 4f 70 65 6e 2c  .    tvfsDlOpen,
72f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7300: 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f     /* xDlOpen */
7310: 0a 20 20 20 20 74 76 66 73 44 6c 45 72 72 6f 72  .    tvfsDlError
7320: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7330: 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a     /* xDlError *
7340: 2f 0a 20 20 20 20 74 76 66 73 44 6c 53 79 6d 2c  /.    tvfsDlSym,
7350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7360: 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f      /* xDlSym */
7370: 0a 20 20 20 20 74 76 66 73 44 6c 43 6c 6f 73 65  .    tvfsDlClose
7380: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7390: 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a     /* xDlClose *
73a0: 2f 0a 23 65 6c 73 65 0a 20 20 20 20 30 2c 20 20  /.#else.    0,  
73b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
73d0: 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20  Open */.    0,  
73e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
7400: 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30 2c 20  Error */.    0, 
7410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7420: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
7430: 6c 53 79 6d 20 2a 2f 0a 20 20 20 20 30 2c 20 20  lSym */.    0,  
7440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7450: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
7460: 43 6c 6f 73 65 20 2a 2f 0a 23 65 6e 64 69 66 20  Close */.#endif 
7470: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  /* SQLITE_OMIT_L
7480: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f  OAD_EXTENSION */
7490: 0a 20 20 20 20 74 76 66 73 52 61 6e 64 6f 6d 6e  .    tvfsRandomn
74a0: 65 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ess,            
74b0: 20 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e 65 73     /* xRandomnes
74c0: 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 53 6c 65  s */.    tvfsSle
74d0: 65 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ep,             
74e0: 20 20 20 20 20 20 20 2f 2a 20 78 53 6c 65 65 70         /* xSleep
74f0: 20 2a 2f 0a 20 20 20 20 74 76 66 73 43 75 72 72   */.    tvfsCurr
7500: 65 6e 74 54 69 6d 65 2c 20 20 20 20 20 20 20 20  entTime,        
7510: 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e        /* xCurren
7520: 74 54 69 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20  tTime */.    0, 
7530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7540: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 47             /* xG
7550: 65 74 4c 61 73 74 45 72 72 6f 72 20 2a 2f 0a 20  etLastError */. 
7560: 20 20 20 30 2c 0a 20 20 20 20 30 2c 0a 20 20 7d     0,.    0,.  }
7570: 3b 0a 0a 20 20 54 65 73 74 76 66 73 20 2a 70 3b  ;..  Testvfs *p;
7580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7590: 20 20 20 20 20 2f 2a 20 4e 65 77 20 6f 62 6a 65       /* New obje
75a0: 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ct */.  sqlite3_
75b0: 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20  vfs *pVfs;      
75c0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 56          /* New V
75d0: 46 53 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 56  FS */.  char *zV
75e0: 66 73 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b  fs;.  int nByte;
75f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7600: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
7610: 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63  f space to alloc
7620: 61 74 65 20 61 74 20 70 20 2a 2f 0a 0a 20 20 69  ate at p */..  i
7630: 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 73 4e 6f  nt i;.  int isNo
7640: 73 68 6d 20 3d 20 30 3b 20 20 20 20 20 20 20 20  shm = 0;        
7650: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
7660: 69 66 20 2d 6e 6f 73 68 6d 20 69 73 20 70 61 73  if -noshm is pas
7670: 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69 73 44  sed */.  int isD
7680: 65 66 61 75 6c 74 20 3d 20 30 3b 20 20 20 20 20  efault = 0;     
7690: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
76a0: 20 69 66 20 2d 64 65 66 61 75 6c 74 20 69 73 20   if -default is 
76b0: 70 61 73 73 65 64 20 2a 2f 0a 0a 20 20 69 66 28  passed */..  if(
76c0: 20 6f 62 6a 63 3c 32 20 7c 7c 20 30 21 3d 28 6f   objc<2 || 0!=(o
76d0: 62 6a 63 25 32 29 20 29 20 67 6f 74 6f 20 62 61  bjc%2) ) goto ba
76e0: 64 5f 61 72 67 73 3b 0a 20 20 66 6f 72 28 69 3d  d_args;.  for(i=
76f0: 32 3b 20 69 3c 6f 62 6a 63 3b 20 69 20 2b 3d 20  2; i<objc; i += 
7700: 32 29 7b 0a 20 20 20 20 69 6e 74 20 6e 53 77 69  2){.    int nSwi
7710: 74 63 68 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  tch;.    char *z
7720: 53 77 69 74 63 68 3b 0a 0a 20 20 20 20 7a 53 77  Switch;..    zSw
7730: 69 74 63 68 20 3d 20 54 63 6c 5f 47 65 74 53 74  itch = Tcl_GetSt
7740: 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76  ringFromObj(objv
7750: 5b 69 5d 2c 20 26 6e 53 77 69 74 63 68 29 3b 20  [i], &nSwitch); 
7760: 0a 20 20 20 20 69 66 28 20 6e 53 77 69 74 63 68  .    if( nSwitch
7770: 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70  >2 && 0==strncmp
7780: 28 22 2d 6e 6f 73 68 6d 22 2c 20 7a 53 77 69 74  ("-noshm", zSwit
7790: 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a  ch, nSwitch) ){.
77a0: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
77b0: 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28  tBooleanFromObj(
77c0: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31  interp, objv[i+1
77d0: 5d 2c 20 26 69 73 4e 6f 73 68 6d 29 20 29 7b 0a  ], &isNoshm) ){.
77e0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
77f0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
7800: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  }.    }.    else
7810: 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26   if( nSwitch>2 &
7820: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 64  & 0==strncmp("-d
7830: 65 66 61 75 6c 74 22 2c 20 7a 53 77 69 74 63 68  efault", zSwitch
7840: 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20  , nSwitch) ){.  
7850: 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 42      if( Tcl_GetB
7860: 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e  ooleanFromObj(in
7870: 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c  terp, objv[i+1],
7880: 20 26 69 73 44 65 66 61 75 6c 74 29 20 29 7b 0a   &isDefault) ){.
7890: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
78a0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
78b0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  }.    }.    else
78c0: 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 62 61 64  {.      goto bad
78d0: 5f 61 72 67 73 3b 0a 20 20 20 20 7d 0a 20 20 7d  _args;.    }.  }
78e0: 0a 0a 20 20 7a 56 66 73 20 3d 20 54 63 6c 5f 47  ..  zVfs = Tcl_G
78f0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
7900: 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a  );.  nByte = siz
7910: 65 6f 66 28 54 65 73 74 76 66 73 29 20 2b 20 73  eof(Testvfs) + s
7920: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 3b 0a 20  trlen(zVfs)+1;. 
7930: 20 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29   p = (Testvfs *)
7940: 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  ckalloc(nByte);.
7950: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e    memset(p, 0, n
7960: 42 79 74 65 29 3b 0a 0a 20 20 2f 2a 20 43 72 65  Byte);..  /* Cre
7970: 61 74 65 20 74 68 65 20 6e 65 77 20 6f 62 6a 65  ate the new obje
7980: 63 74 20 63 6f 6d 6d 61 6e 64 20 62 65 66 6f 72  ct command befor
7990: 65 20 71 75 65 72 79 69 6e 67 20 53 51 4c 69 74  e querying SQLit
79a0: 65 20 66 6f 72 20 61 20 64 65 66 61 75 6c 74 20  e for a default 
79b0: 56 46 53 0a 20 20 2a 2a 20 74 6f 20 75 73 65 20  VFS.  ** to use 
79c0: 66 6f 72 20 27 72 65 61 6c 27 20 49 4f 20 6f 70  for 'real' IO op
79d0: 65 72 61 74 69 6f 6e 73 2e 20 54 68 69 73 20 69  erations. This i
79e0: 73 20 62 65 63 61 75 73 65 20 63 72 65 61 74 69  s because creati
79f0: 6e 67 20 74 68 65 20 6e 65 77 20 56 46 53 0a 20  ng the new VFS. 
7a00: 20 2a 2a 20 6d 61 79 20 64 65 6c 65 74 65 20 61   ** may delete a
7a10: 6e 20 65 78 69 73 74 69 6e 67 20 5b 74 65 73 74  n existing [test
7a20: 76 66 73 5d 20 56 46 53 20 6f 66 20 74 68 65 20  vfs] VFS of the 
7a30: 73 61 6d 65 20 6e 61 6d 65 2e 20 49 66 20 73 75  same name. If su
7a40: 63 68 20 61 20 56 46 53 0a 20 20 2a 2a 20 69 73  ch a VFS.  ** is
7a50: 20 63 75 72 72 65 6e 74 6c 79 20 74 68 65 20 64   currently the d
7a60: 65 66 61 75 6c 74 2c 20 74 68 65 20 6e 65 77 20  efault, the new 
7a70: 5b 74 65 73 74 76 66 73 5d 20 6d 61 79 20 65 6e  [testvfs] may en
7a80: 64 20 75 70 20 63 61 6c 6c 69 6e 67 20 74 68 65  d up calling the
7a90: 20 0a 20 20 2a 2a 20 6d 65 74 68 6f 64 73 20 6f   .  ** methods o
7aa0: 66 20 61 20 64 65 6c 65 74 65 64 20 6f 62 6a 65  f a deleted obje
7ab0: 63 74 2e 0a 20 20 2a 2f 0a 20 20 54 63 6c 5f 43  ct..  */.  Tcl_C
7ac0: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
7ad0: 69 6e 74 65 72 70 2c 20 7a 56 66 73 2c 20 74 65  interp, zVfs, te
7ae0: 73 74 76 66 73 5f 6f 62 6a 5f 63 6d 64 2c 20 70  stvfs_obj_cmd, p
7af0: 2c 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 64 65  , testvfs_obj_de
7b00: 6c 29 3b 0a 20 20 70 2d 3e 70 50 61 72 65 6e 74  l);.  p->pParent
7b10: 20 3d 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 66   = sqlite3_vfs_f
7b20: 69 6e 64 28 30 29 3b 0a 20 20 70 2d 3e 69 6e 74  ind(0);.  p->int
7b30: 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 0a 20  erp = interp;.. 
7b40: 20 70 2d 3e 7a 4e 61 6d 65 20 3d 20 28 63 68 61   p->zName = (cha
7b50: 72 20 2a 29 26 70 5b 31 5d 3b 0a 20 20 6d 65 6d  r *)&p[1];.  mem
7b60: 63 70 79 28 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 56  cpy(p->zName, zV
7b70: 66 73 2c 20 73 74 72 6c 65 6e 28 7a 56 66 73 29  fs, strlen(zVfs)
7b80: 2b 31 29 3b 0a 0a 20 20 70 56 66 73 20 3d 20 28  +1);..  pVfs = (
7b90: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29 63 6b  sqlite3_vfs *)ck
7ba0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73 71 6c  alloc(sizeof(sql
7bb0: 69 74 65 33 5f 76 66 73 29 29 3b 0a 20 20 6d 65  ite3_vfs));.  me
7bc0: 6d 63 70 79 28 70 56 66 73 2c 20 26 74 76 66 73  mcpy(pVfs, &tvfs
7bd0: 5f 76 66 73 2c 20 73 69 7a 65 6f 66 28 73 71 6c  _vfs, sizeof(sql
7be0: 69 74 65 33 5f 76 66 73 29 29 3b 0a 20 20 70 56  ite3_vfs));.  pV
7bf0: 66 73 2d 3e 70 41 70 70 44 61 74 61 20 3d 20 28  fs->pAppData = (
7c00: 76 6f 69 64 20 2a 29 70 3b 0a 20 20 70 56 66 73  void *)p;.  pVfs
7c10: 2d 3e 7a 4e 61 6d 65 20 3d 20 70 2d 3e 7a 4e 61  ->zName = p->zNa
7c20: 6d 65 3b 0a 20 20 70 56 66 73 2d 3e 6d 78 50 61  me;.  pVfs->mxPa
7c30: 74 68 6e 61 6d 65 20 3d 20 70 2d 3e 70 50 61 72  thname = p->pPar
7c40: 65 6e 74 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 3b  ent->mxPathname;
7c50: 0a 20 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c  .  pVfs->szOsFil
7c60: 65 20 2b 3d 20 70 2d 3e 70 50 61 72 65 6e 74 2d  e += p->pParent-
7c70: 3e 73 7a 4f 73 46 69 6c 65 3b 0a 20 20 70 2d 3e  >szOsFile;.  p->
7c80: 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70  pVfs = pVfs;.  p
7c90: 2d 3e 69 73 4e 6f 73 68 6d 20 3d 20 69 73 4e 6f  ->isNoshm = isNo
7ca0: 73 68 6d 3b 0a 20 20 70 2d 3e 6d 61 73 6b 20 3d  shm;.  p->mask =
7cb0: 20 54 45 53 54 56 46 53 5f 41 4c 4c 5f 4d 41 53   TESTVFS_ALL_MAS
7cc0: 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  K;..  sqlite3_vf
7cd0: 73 5f 72 65 67 69 73 74 65 72 28 70 56 66 73 2c  s_register(pVfs,
7ce0: 20 69 73 44 65 66 61 75 6c 74 29 3b 0a 0a 20 20   isDefault);..  
7cf0: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 0a  return TCL_OK;..
7d00: 20 62 61 64 5f 61 72 67 73 3a 0a 20 20 54 63 6c   bad_args:.  Tcl
7d10: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
7d20: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
7d30: 56 46 53 4e 41 4d 45 20 3f 2d 6e 6f 73 68 6d 20  VFSNAME ?-noshm 
7d40: 42 4f 4f 4c 3f 20 3f 2d 64 65 66 61 75 6c 74 20  BOOL? ?-default 
7d50: 42 4f 4f 4c 3f 22 29 3b 0a 20 20 72 65 74 75 72  BOOL?");.  retur
7d60: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a 0a  n TCL_ERROR;.}..
7d70: 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 76 66  int Sqlitetestvf
7d80: 73 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72  s_Init(Tcl_Inter
7d90: 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 54 63  p *interp){.  Tc
7da0: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
7db0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 74 65 73 74  nd(interp, "test
7dc0: 76 66 73 22 2c 20 74 65 73 74 76 66 73 5f 63 6d  vfs", testvfs_cm
7dd0: 64 2c 20 30 2c 20 30 29 3b 0a 20 20 72 65 74 75  d, 0, 0);.  retu
7de0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65  rn TCL_OK;.}..#e
7df0: 6e 64 69 66 0a                                   ndif.