/ Hex Artifact Content
Login

Artifact b83206d2c04b3ba84d8d85420c4c7573c58feba5:


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 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a   ckalloc(pgsz);.
4760: 20 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 61 50      memset(p->aP
4770: 61 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c 20 70  age[iPage], 0, p
4780: 67 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70 67 73  gsz);.    p->pgs
4790: 7a 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a 7d 0a  z = pgsz;.  }.}.
47a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
47b0: 53 68 6d 50 61 67 65 28 0a 20 20 73 71 6c 69 74  ShmPage(.  sqlit
47c0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
47d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61             /* Ha
47e0: 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74  ndle open on dat
47f0: 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20  abase file */.  
4800: 69 6e 74 20 69 50 61 67 65 2c 20 20 20 20 20 20  int iPage,      
4810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4820: 2f 2a 20 50 61 67 65 20 74 6f 20 72 65 74 72 69  /* Page to retri
4830: 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73  eve */.  int pgs
4840: 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  z,              
4850: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4860: 20 6f 66 20 70 61 67 65 73 20 2a 2f 0a 20 20 69   of pages */.  i
4870: 6e 74 20 69 73 57 72 69 74 65 2c 20 20 20 20 20  nt isWrite,     
4880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4890: 2a 20 54 72 75 65 20 74 6f 20 65 78 74 65 6e 64  * True to extend
48a0: 20 66 69 6c 65 20 69 66 20 6e 65 63 65 73 73 61   file if necessa
48b0: 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f 6c  ry */.  void vol
48c0: 61 74 69 6c 65 20 2a 2a 70 70 20 20 20 20 20 20  atile **pp      
48d0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
48e0: 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a 2f  Mapped memory */
48f0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
4900: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74  QLITE_OK;.  Test
4910: 76 66 73 46 69 6c 65 20 2a 70 46 64 20 3d 20 28  vfsFile *pFd = (
4920: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46  TestvfsFile *)pF
4930: 69 6c 65 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  ile;.  Testvfs *
4940: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28  p = (Testvfs *)(
4950: 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44  pFd->pVfs->pAppD
4960: 61 74 61 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  ata);..  if( p->
4970: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
4980: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 50 41  sk&TESTVFS_SHMPA
4990: 47 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54  GE_MASK ){.    T
49a0: 63 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54  cl_Obj *pArg = T
49b0: 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20  cl_NewObj();.   
49c0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
49d0: 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74  ndElement(p->int
49e0: 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e  erp, pArg, Tcl_N
49f0: 65 77 49 6e 74 4f 62 6a 28 69 50 61 67 65 29 29  ewIntObj(iPage))
4a00: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
4a10: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70  jAppendElement(p
4a20: 2d 3e 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20  ->interp, pArg, 
4a30: 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 67  Tcl_NewIntObj(pg
4a40: 73 7a 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69  sz));.    Tcl_Li
4a50: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
4a60: 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41  nt(p->interp, pA
4a70: 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62  rg, Tcl_NewIntOb
4a80: 6a 28 69 73 57 72 69 74 65 29 29 3b 0a 20 20 20  j(isWrite));.   
4a90: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
4aa0: 22 78 53 68 6d 50 61 67 65 22 2c 20 0a 20 20 20  "xShmPage", .   
4ab0: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
4ac0: 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d 2d  ngObj(pFd->pShm-
4ad0: 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46 64  >zFile, -1), pFd
4ae0: 2d 3e 70 53 68 6d 49 64 2c 20 70 41 72 67 0a 20  ->pShmId, pArg. 
4af0: 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65     );.    tvfsRe
4b00: 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29  sultCode(p, &rc)
4b10: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d  ;.  }.  if( rc==
4b20: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e  SQLITE_OK && p->
4b30: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d  mask&TESTVFS_SHM
4b40: 50 41 47 45 5f 4d 41 53 4b 20 26 26 20 74 76 66  PAGE_MASK && tvf
4b50: 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20  sInjectIoerr(p) 
4b60: 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  ){.    rc = SQLI
4b70: 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20  TE_IOERR;.  }.. 
4b80: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4b90: 4f 4b 20 26 26 20 69 73 57 72 69 74 65 20 26 26  OK && isWrite &&
4ba0: 20 21 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61   !pFd->pShm->aPa
4bb0: 67 65 5b 69 50 61 67 65 5d 20 29 7b 0a 20 20 20  ge[iPage] ){.   
4bc0: 20 74 76 66 73 41 6c 6c 6f 63 50 61 67 65 28 70   tvfsAllocPage(p
4bd0: 46 64 2d 3e 70 53 68 6d 2c 20 69 50 61 67 65 2c  Fd->pShm, iPage,
4be0: 20 70 67 73 7a 29 3b 0a 20 20 7d 0a 20 20 2a 70   pgsz);.  }.  *p
4bf0: 70 20 3d 20 28 76 6f 69 64 20 76 6f 6c 61 74 69  p = (void volati
4c00: 6c 65 20 2a 29 70 46 64 2d 3e 70 53 68 6d 2d 3e  le *)pFd->pShm->
4c10: 61 50 61 67 65 5b 69 50 61 67 65 5d 3b 0a 0a 20  aPage[iPage];.. 
4c20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
4c30: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
4c40: 68 6d 4c 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65  hmLock(.  sqlite
4c50: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20  3_file *pFile,. 
4c60: 20 69 6e 74 20 6f 66 73 74 2c 0a 20 20 69 6e 74   int ofst,.  int
4c70: 20 6e 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 0a   n,.  int flags.
4c80: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
4c90: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76  LITE_OK;.  Testv
4ca0: 66 73 46 69 6c 65 20 2a 70 46 64 20 3d 20 28 54  fsFile *pFd = (T
4cb0: 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69  estvfsFile *)pFi
4cc0: 6c 65 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  le;.  Testvfs *p
4cd0: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28 70   = (Testvfs *)(p
4ce0: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
4cf0: 74 61 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b  ta);.  int nLock
4d00: 3b 0a 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 38  ;.  char zLock[8
4d10: 30 5d 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  0];..  if( p->pS
4d20: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
4d30: 26 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b  &TESTVFS_SHMLOCK
4d40: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 73 71 6c  _MASK ){.    sql
4d50: 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69  ite3_snprintf(si
4d60: 7a 65 6f 66 28 7a 4c 6f 63 6b 29 2c 20 7a 4c 6f  zeof(zLock), zLo
4d70: 63 6b 2c 20 22 25 64 20 25 64 22 2c 20 6f 66 73  ck, "%d %d", ofs
4d80: 74 2c 20 6e 29 3b 0a 20 20 20 20 6e 4c 6f 63 6b  t, n);.    nLock
4d90: 20 3d 20 73 74 72 6c 65 6e 28 7a 4c 6f 63 6b 29   = strlen(zLock)
4da0: 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73 20  ;.    if( flags 
4db0: 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43  & SQLITE_SHM_LOC
4dc0: 4b 20 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70  K ){.      strcp
4dd0: 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c  y(&zLock[nLock],
4de0: 20 22 20 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d   " lock");.    }
4df0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 74 72 63  else{.      strc
4e00: 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d  py(&zLock[nLock]
4e10: 2c 20 22 20 75 6e 6c 6f 63 6b 22 29 3b 0a 20 20  , " unlock");.  
4e20: 20 20 7d 0a 20 20 20 20 6e 4c 6f 63 6b 20 2b 3d    }.    nLock +=
4e30: 20 73 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e   strlen(&zLock[n
4e40: 4c 6f 63 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20  Lock]);.    if( 
4e50: 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  flags & SQLITE_S
4e60: 48 4d 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20  HM_SHARED ){.   
4e70: 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b     strcpy(&zLock
4e80: 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65  [nLock], " share
4e90: 64 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  d");.    }else{.
4ea0: 20 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c        strcpy(&zL
4eb0: 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78  ock[nLock], " ex
4ec0: 63 6c 75 73 69 76 65 22 29 3b 0a 20 20 20 20 7d  clusive");.    }
4ed0: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
4ee0: 28 70 2c 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20  (p, "xShmLock", 
4ef0: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77  .        Tcl_New
4f00: 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70  StringObj(pFd->p
4f10: 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c  Shm->zFile, -1),
4f20: 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20   pFd->pShmId,.  
4f30: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
4f40: 69 6e 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31  ingObj(zLock, -1
4f50: 29 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66  ).    );.    tvf
4f60: 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26  sResultCode(p, &
4f70: 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  rc);.  }..  if( 
4f80: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
4f90: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
4fa0: 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 26 26  _SHMLOCK_MASK &&
4fb0: 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72   tvfsInjectIoerr
4fc0: 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  (p) ){.    rc = 
4fd0: 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20  SQLITE_IOERR;.  
4fe0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
4ff0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e  ITE_OK ){.    in
5000: 74 20 69 73 4c 6f 63 6b 20 3d 20 28 66 6c 61 67  t isLock = (flag
5010: 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c  s & SQLITE_SHM_L
5020: 4f 43 4b 29 3b 0a 20 20 20 20 69 6e 74 20 69 73  OCK);.    int is
5030: 45 78 63 6c 20 3d 20 28 66 6c 61 67 73 20 26 20  Excl = (flags & 
5040: 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55  SQLITE_SHM_EXCLU
5050: 53 49 56 45 29 3b 0a 20 20 20 20 75 33 32 20 6d  SIVE);.    u32 m
5060: 61 73 6b 20 3d 20 28 28 28 31 3c 3c 6e 29 2d 31  ask = (((1<<n)-1
5070: 29 20 3c 3c 20 6f 66 73 74 29 3b 0a 20 20 20 20  ) << ofst);.    
5080: 69 66 28 20 69 73 4c 6f 63 6b 20 29 7b 0a 20 20  if( isLock ){.  
5090: 20 20 20 20 54 65 73 74 76 66 73 46 69 6c 65 20      TestvfsFile 
50a0: 2a 70 32 3b 0a 20 20 20 20 20 20 66 6f 72 28 70  *p2;.      for(p
50b0: 32 3d 70 46 64 2d 3e 70 53 68 6d 2d 3e 70 46 69  2=pFd->pShm->pFi
50c0: 6c 65 3b 20 70 32 3b 20 70 32 3d 70 32 2d 3e 70  le; p2; p2=p2->p
50d0: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20 69  Next){.        i
50e0: 66 28 20 70 32 3d 3d 70 46 64 20 29 20 63 6f 6e  f( p2==pFd ) con
50f0: 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 69  tinue;.        i
5100: 66 28 20 28 70 32 2d 3e 65 78 63 6c 6c 6f 63 6b  f( (p2->excllock
5110: 26 6d 61 73 6b 29 20 7c 7c 20 28 69 73 45 78 63  &mask) || (isExc
5120: 6c 20 26 26 20 70 32 2d 3e 73 68 61 72 65 64 6c  l && p2->sharedl
5130: 6f 63 6b 26 6d 61 73 6b 29 20 29 7b 0a 20 20 20  ock&mask) ){.   
5140: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
5150: 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 20 20 20  TE_BUSY;.       
5160: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
5170: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
5180: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
5190: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
51a0: 66 28 20 69 73 45 78 63 6c 20 29 20 20 70 46 64  f( isExcl )  pFd
51b0: 2d 3e 65 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d 61  ->excllock |= ma
51c0: 73 6b 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  sk;.        if( 
51d0: 21 69 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73  !isExcl ) pFd->s
51e0: 68 61 72 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61 73  haredlock |= mas
51f0: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
5200: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
5210: 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65  isExcl )  pFd->e
5220: 78 63 6c 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73  xcllock &= (~mas
5230: 6b 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69  k);.      if( !i
5240: 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61  sExcl ) pFd->sha
5250: 72 65 64 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73  redlock &= (~mas
5260: 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  k);.    }.  }.. 
5270: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
5280: 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 53  tatic void tvfsS
5290: 68 6d 42 61 72 72 69 65 72 28 73 71 6c 69 74 65  hmBarrier(sqlite
52a0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
52b0: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
52c0: 46 64 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c  Fd = (TestvfsFil
52d0: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73  e *)pFile;.  Tes
52e0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
52f0: 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d  fs *)(pFd->pVfs-
5300: 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69  >pAppData);..  i
5310: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
5320: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
5330: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
5340: 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63   ){.    tvfsExec
5350: 54 63 6c 28 70 2c 20 22 78 53 68 6d 42 61 72 72  Tcl(p, "xShmBarr
5360: 69 65 72 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ier", .        T
5370: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
5380: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
5390: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
53a0: 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d  Id, 0.    );.  }
53b0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
53c0: 76 66 73 53 68 6d 43 6c 6f 73 65 28 0a 20 20 73  vfsShmClose(.  s
53d0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
53e0: 6c 65 2c 0a 20 20 69 6e 74 20 64 65 6c 65 74 65  le,.  int delete
53f0: 46 6c 61 67 0a 29 7b 0a 20 20 69 6e 74 20 72 63  Flag.){.  int rc
5400: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
5410: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70 46 64  TestvfsFile *pFd
5420: 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65 20   = (TestvfsFile 
5430: 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73 74 76  *)pFile;.  Testv
5440: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
5450: 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70   *)(pFd->pVfs->p
5460: 41 70 70 44 61 74 61 29 3b 0a 20 20 54 65 73 74  AppData);.  Test
5470: 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66 66  vfsBuffer *pBuff
5480: 65 72 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b 0a  er = pFd->pShm;.
5490: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 2a    TestvfsFile **
54a0: 70 70 46 64 3b 0a 0a 20 20 61 73 73 65 72 74 28  ppFd;..  assert(
54b0: 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26 26 20   pFd->pShmId && 
54c0: 70 46 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a 20 20  pFd->pShm );..  
54d0: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
54e0: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
54f0: 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20  S_SHMCLOSE_MASK 
5500: 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54  ){.    tvfsExecT
5510: 63 6c 28 70 2c 20 22 78 53 68 6d 43 6c 6f 73 65  cl(p, "xShmClose
5520: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
5530: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
5540: 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d  ->pShm->zFile, -
5550: 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c  1), pFd->pShmId,
5560: 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76   0.    );.    tv
5570: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
5580: 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  &rc);.  }..  for
5590: 28 70 70 46 64 3d 26 70 42 75 66 66 65 72 2d 3e  (ppFd=&pBuffer->
55a0: 70 46 69 6c 65 3b 20 2a 70 70 46 64 21 3d 70 46  pFile; *ppFd!=pF
55b0: 64 3b 20 70 70 46 64 3d 26 28 28 2a 70 70 46 64  d; ppFd=&((*ppFd
55c0: 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 61 73  )->pNext));.  as
55d0: 73 65 72 74 28 20 28 2a 70 70 46 64 29 3d 3d 70  sert( (*ppFd)==p
55e0: 46 64 20 29 3b 0a 20 20 2a 70 70 46 64 20 3d 20  Fd );.  *ppFd = 
55f0: 70 46 64 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 69  pFd->pNext;..  i
5600: 66 28 20 70 42 75 66 66 65 72 2d 3e 70 46 69 6c  f( pBuffer->pFil
5610: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20  e==0 ){.    int 
5620: 69 3b 0a 20 20 20 20 54 65 73 74 76 66 73 42 75  i;.    TestvfsBu
5630: 66 66 65 72 20 2a 2a 70 70 3b 0a 20 20 20 20 66  ffer **pp;.    f
5640: 6f 72 28 70 70 3d 26 70 2d 3e 70 42 75 66 66 65  or(pp=&p->pBuffe
5650: 72 3b 20 2a 70 70 21 3d 70 42 75 66 66 65 72 3b  r; *pp!=pBuffer;
5660: 20 70 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65   pp=&((*pp)->pNe
5670: 78 74 29 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20  xt));.    *pp = 
5680: 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20  (*pp)->pNext;.  
5690: 20 20 66 6f 72 28 69 3d 30 3b 20 70 42 75 66 66    for(i=0; pBuff
56a0: 65 72 2d 3e 61 50 61 67 65 5b 69 5d 3b 20 69 2b  er->aPage[i]; i+
56b0: 2b 29 7b 0a 20 20 20 20 20 20 63 6b 66 72 65 65  +){.      ckfree
56c0: 28 28 63 68 61 72 20 2a 29 70 42 75 66 66 65 72  ((char *)pBuffer
56d0: 2d 3e 61 50 61 67 65 5b 69 5d 29 3b 0a 20 20 20  ->aPage[i]);.   
56e0: 20 7d 0a 20 20 20 20 63 6b 66 72 65 65 28 28 63   }.    ckfree((c
56f0: 68 61 72 20 2a 29 70 42 75 66 66 65 72 29 3b 0a  har *)pBuffer);.
5700: 20 20 7d 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20    }.  pFd->pShm 
5710: 3d 20 30 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72  = 0;..  return r
5720: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
5730: 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63 6d 64   testvfs_obj_cmd
5740: 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63  (.  ClientData c
5750: 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  d,.  Tcl_Interp 
5760: 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f  *interp,.  int o
5770: 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  bjc,.  Tcl_Obj *
5780: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a  CONST objv[].){.
5790: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
57a0: 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a 0a 20  Testvfs *)cd;.. 
57b0: 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68   static const ch
57c0: 61 72 20 2a 43 4d 44 5f 73 74 72 73 5b 5d 20 3d  ar *CMD_strs[] =
57d0: 20 7b 20 0a 20 20 20 20 22 73 68 6d 22 2c 20 20   { .    "shm",  
57e0: 20 22 64 65 6c 65 74 65 22 2c 20 20 20 22 66 69   "delete",   "fi
57f0: 6c 74 65 72 22 2c 20 20 20 22 69 6f 65 72 72 22  lter",   "ioerr"
5800: 2c 20 20 20 22 73 63 72 69 70 74 22 2c 20 30 20  ,   "script", 0 
5810: 0a 20 20 7d 3b 0a 20 20 65 6e 75 6d 20 44 42 5f  .  };.  enum DB_
5820: 65 6e 75 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f  enum { .    CMD_
5830: 53 48 4d 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c  SHM, CMD_DELETE,
5840: 20 43 4d 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44   CMD_FILTER, CMD
5850: 5f 49 4f 45 52 52 2c 20 43 4d 44 5f 53 43 52 49  _IOERR, CMD_SCRI
5860: 50 54 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74 20 69  PT.  };..  int i
5870: 3b 0a 20 20 0a 20 20 69 66 28 20 6f 62 6a 63 3c  ;.  .  if( objc<
5880: 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  2 ){.    Tcl_Wro
5890: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
58a0: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 53 55 42 43  , 1, objv, "SUBC
58b0: 4f 4d 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20  OMMAND ...");.  
58c0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
58d0: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 54 63  OR;.  }.  if( Tc
58e0: 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62  l_GetIndexFromOb
58f0: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31  j(interp, objv[1
5900: 5d 2c 20 43 4d 44 5f 73 74 72 73 2c 20 22 73 75  ], CMD_strs, "su
5910: 62 63 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69  bcommand", 0, &i
5920: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
5930: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
5940: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
5950: 28 69 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77 69  (interp);..  swi
5960: 74 63 68 28 20 28 65 6e 75 6d 20 44 42 5f 65 6e  tch( (enum DB_en
5970: 75 6d 29 69 20 29 7b 0a 20 20 20 20 63 61 73 65  um)i ){.    case
5980: 20 43 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20 20   CMD_SHM: {.    
5990: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b    Tcl_Obj *pObj;
59a0: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  .      int i;.  
59b0: 20 20 20 20 54 65 73 74 76 66 73 42 75 66 66 65      TestvfsBuffe
59c0: 72 20 2a 70 42 75 66 66 65 72 3b 0a 20 20 20 20  r *pBuffer;.    
59d0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
59e0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21 3d 33       if( objc!=3
59f0: 20 26 26 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20   && objc!=4 ){. 
5a00: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
5a10: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
5a20: 32 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45 20 3f  2, objv, "FILE ?
5a30: 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20 20  VALUE?");.      
5a40: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
5a50: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
5a60: 20 20 7a 4e 61 6d 65 20 3d 20 54 63 6c 5f 47 65    zName = Tcl_Ge
5a70: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29  tString(objv[2])
5a80: 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 42 75 66  ;.      for(pBuf
5a90: 66 65 72 3d 70 2d 3e 70 42 75 66 66 65 72 3b 20  fer=p->pBuffer; 
5aa0: 70 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72  pBuffer; pBuffer
5ab0: 3d 70 42 75 66 66 65 72 2d 3e 70 4e 65 78 74 29  =pBuffer->pNext)
5ac0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 30 3d  {.        if( 0=
5ad0: 3d 73 74 72 63 6d 70 28 70 42 75 66 66 65 72 2d  =strcmp(pBuffer-
5ae0: 3e 7a 46 69 6c 65 2c 20 7a 4e 61 6d 65 29 20 29  >zFile, zName) )
5af0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
5b00: 20 20 20 20 20 20 69 66 28 20 21 70 42 75 66 66        if( !pBuff
5b10: 65 72 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63  er ){.        Tc
5b20: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
5b30: 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68 20  nterp, "no such 
5b40: 66 69 6c 65 3a 20 22 2c 20 7a 4e 61 6d 65 2c 20  file: ", zName, 
5b50: 30 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  0);.        retu
5b60: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
5b70: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
5b80: 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20  objc==4 ){.     
5b90: 20 20 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20     int n;.      
5ba0: 20 20 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47 65    u8 *a = Tcl_Ge
5bb0: 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62  tByteArrayFromOb
5bc0: 6a 28 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b 0a  j(objv[3], &n);.
5bd0: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
5be0: 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3d 3d 30  pBuffer->pgsz==0
5bf0: 20 7c 7c 20 70 42 75 66 66 65 72 2d 3e 70 67 73   || pBuffer->pgs
5c00: 7a 3d 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20  z==32768 );.    
5c10: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 2a 33      for(i=0; i*3
5c20: 32 37 36 38 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20  2768<n; i++){.  
5c30: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74          int nByt
5c40: 65 20 3d 20 33 32 37 36 38 3b 0a 20 20 20 20 20  e = 32768;.     
5c50: 20 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50 61       tvfsAllocPa
5c60: 67 65 28 70 42 75 66 66 65 72 2c 20 69 2c 20 33  ge(pBuffer, i, 3
5c70: 32 37 36 38 29 3b 0a 20 20 20 20 20 20 20 20 20  2768);.         
5c80: 20 69 66 28 20 6e 2d 69 2a 33 32 37 36 38 3c 33   if( n-i*32768<3
5c90: 32 37 36 38 20 29 7b 0a 20 20 20 20 20 20 20 20  2768 ){.        
5ca0: 20 20 20 20 6e 42 79 74 65 20 3d 20 6e 3b 0a 20      nByte = n;. 
5cb0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
5cc0: 20 20 20 20 20 6d 65 6d 63 70 79 28 70 42 75 66       memcpy(pBuf
5cd0: 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20 26  fer->aPage[i], &
5ce0: 61 5b 69 2a 33 32 37 36 38 5d 2c 20 6e 42 79 74  a[i*32768], nByt
5cf0: 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  e);.        }.  
5d00: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70 4f 62      }..      pOb
5d10: 6a 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29  j = Tcl_NewObj()
5d20: 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b  ;.      for(i=0;
5d30: 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b   pBuffer->aPage[
5d40: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  i]; i++){.      
5d50: 20 20 54 63 6c 5f 41 70 70 65 6e 64 4f 62 6a 54    Tcl_AppendObjT
5d60: 6f 4f 62 6a 28 70 4f 62 6a 2c 20 54 63 6c 5f 4e  oObj(pObj, Tcl_N
5d70: 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28 70  ewByteArrayObj(p
5d80: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
5d90: 2c 20 33 32 37 36 38 29 29 3b 0a 20 20 20 20 20  , 32768));.     
5da0: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74   }.      Tcl_Set
5db0: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
5dc0: 2c 20 70 4f 62 6a 29 3b 0a 20 20 20 20 20 20 62  , pObj);.      b
5dd0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
5de0: 20 63 61 73 65 20 43 4d 44 5f 46 49 4c 54 45 52   case CMD_FILTER
5df0: 3a 20 7b 0a 20 20 20 20 20 20 73 74 61 74 69 63  : {.      static
5e00: 20 73 74 72 75 63 74 20 56 66 73 4d 65 74 68 6f   struct VfsMetho
5e10: 64 20 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72  d {.        char
5e20: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20   *zName;.       
5e30: 20 69 6e 74 20 6d 61 73 6b 3b 0a 20 20 20 20 20   int mask;.     
5e40: 20 7d 20 76 66 73 6d 65 74 68 6f 64 20 5b 5d 20   } vfsmethod [] 
5e50: 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 78  = {.        { "x
5e60: 53 68 6d 4f 70 65 6e 22 2c 20 20 20 20 54 45 53  ShmOpen",    TES
5e70: 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53  TVFS_SHMOPEN_MAS
5e80: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
5e90: 78 53 68 6d 53 69 7a 65 22 2c 20 20 20 20 54 45  xShmSize",    TE
5ea0: 53 54 56 46 53 5f 53 48 4d 53 49 5a 45 5f 4d 41  STVFS_SHMSIZE_MA
5eb0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
5ec0: 22 78 53 68 6d 47 65 74 22 2c 20 20 20 20 20 54  "xShmGet",     T
5ed0: 45 53 54 56 46 53 5f 53 48 4d 47 45 54 5f 4d 41  ESTVFS_SHMGET_MA
5ee0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
5ef0: 22 78 53 68 6d 52 65 6c 65 61 73 65 22 2c 20 54  "xShmRelease", T
5f00: 45 53 54 56 46 53 5f 53 48 4d 52 45 4c 45 41 53  ESTVFS_SHMRELEAS
5f10: 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20  E_MASK },.      
5f20: 20 20 7b 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20    { "xShmLock", 
5f30: 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f     TESTVFS_SHMLO
5f40: 43 4b 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  CK_MASK },.     
5f50: 20 20 20 7b 20 22 78 53 68 6d 42 61 72 72 69 65     { "xShmBarrie
5f60: 72 22 2c 20 54 45 53 54 56 46 53 5f 53 48 4d 42  r", TESTVFS_SHMB
5f70: 41 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a 20  ARRIER_MASK },. 
5f80: 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 43 6c         { "xShmCl
5f90: 6f 73 65 22 2c 20 20 20 54 45 53 54 56 46 53 5f  ose",   TESTVFS_
5fa0: 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c  SHMCLOSE_MASK },
5fb0: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 79 6e  .        { "xSyn
5fc0: 63 22 2c 20 20 20 20 20 20 20 54 45 53 54 56 46  c",       TESTVF
5fd0: 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 7d 2c 0a 20  S_SYNC_MASK },. 
5fe0: 20 20 20 20 20 20 20 7b 20 22 78 4f 70 65 6e 22         { "xOpen"
5ff0: 2c 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f  ,       TESTVFS_
6000: 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  OPEN_MASK },.   
6010: 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f     };.      Tcl_
6020: 4f 62 6a 20 2a 2a 61 70 45 6c 65 6d 20 3d 20 30  Obj **apElem = 0
6030: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6c 65  ;.      int nEle
6040: 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  m = 0;.      int
6050: 20 69 3b 0a 20 20 20 20 20 20 69 6e 74 20 6d 61   i;.      int ma
6060: 73 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66  sk = 0;.      if
6070: 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20  ( objc!=3 ){.   
6080: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
6090: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
60a0: 20 6f 62 6a 76 2c 20 22 4c 49 53 54 22 29 3b 0a   objv, "LIST");.
60b0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
60c0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
60d0: 7d 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f  }.      if( Tcl_
60e0: 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e  ListObjGetElemen
60f0: 74 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  ts(interp, objv[
6100: 32 5d 2c 20 26 6e 45 6c 65 6d 2c 20 26 61 70 45  2], &nElem, &apE
6110: 6c 65 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  lem) ){.        
6120: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6130: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6140: 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28  Tcl_ResetResult(
6150: 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20 20 66  interp);.      f
6160: 6f 72 28 69 3d 30 3b 20 69 3c 6e 45 6c 65 6d 3b  or(i=0; i<nElem;
6170: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69   i++){.        i
6180: 6e 74 20 69 4d 65 74 68 6f 64 3b 0a 20 20 20 20  nt iMethod;.    
6190: 20 20 20 20 63 68 61 72 20 2a 7a 45 6c 65 6d 20      char *zElem 
61a0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
61b0: 61 70 45 6c 65 6d 5b 69 5d 29 3b 0a 20 20 20 20  apElem[i]);.    
61c0: 20 20 20 20 66 6f 72 28 69 4d 65 74 68 6f 64 3d      for(iMethod=
61d0: 30 3b 20 69 4d 65 74 68 6f 64 3c 41 72 72 61 79  0; iMethod<Array
61e0: 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64 29 3b  Size(vfsmethod);
61f0: 20 69 4d 65 74 68 6f 64 2b 2b 29 7b 0a 20 20 20   iMethod++){.   
6200: 20 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d         if( strcm
6210: 70 28 7a 45 6c 65 6d 2c 20 76 66 73 6d 65 74 68  p(zElem, vfsmeth
6220: 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e 7a 4e 61 6d  od[iMethod].zNam
6230: 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  e)==0 ){.       
6240: 20 20 20 20 20 6d 61 73 6b 20 7c 3d 20 76 66 73       mask |= vfs
6250: 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e  method[iMethod].
6260: 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  mask;.          
6270: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
6280: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
6290: 20 20 20 20 20 20 20 69 66 28 20 69 4d 65 74 68         if( iMeth
62a0: 6f 64 3d 3d 41 72 72 61 79 53 69 7a 65 28 76 66  od==ArraySize(vf
62b0: 73 6d 65 74 68 6f 64 29 20 29 7b 0a 20 20 20 20  smethod) ){.    
62c0: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
62d0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
62e0: 75 6e 6b 6e 6f 77 6e 20 6d 65 74 68 6f 64 3a 20  unknown method: 
62f0: 22 2c 20 7a 45 6c 65 6d 2c 20 30 29 3b 0a 20 20  ", zElem, 0);.  
6300: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
6310: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
6320: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
6330: 20 20 70 2d 3e 6d 61 73 6b 20 3d 20 6d 61 73 6b    p->mask = mask
6340: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
6350: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43     }..    case C
6360: 4d 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20 20 20  MD_SCRIPT: {.   
6370: 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29     if( objc==3 )
6380: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42  {.        int nB
6390: 79 74 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28  yte;.        if(
63a0: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 7b 0a 20   p->pScript ){. 
63b0: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 44 65 63           Tcl_Dec
63c0: 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63  rRefCount(p->pSc
63d0: 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 20  ript);.         
63e0: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
63f0: 70 2d 3e 61 70 53 63 72 69 70 74 29 3b 0a 20 20  p->apScript);.  
6400: 20 20 20 20 20 20 20 20 70 2d 3e 61 70 53 63 72          p->apScr
6410: 69 70 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ipt = 0;.       
6420: 20 20 20 70 2d 3e 6e 53 63 72 69 70 74 20 3d 20     p->nScript = 
6430: 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  0;.        }.   
6440: 20 20 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69       Tcl_GetStri
6450: 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32  ngFromObj(objv[2
6460: 5d 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20  ], &nByte);.    
6470: 20 20 20 20 69 66 28 20 6e 42 79 74 65 3e 30 20      if( nByte>0 
6480: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  ){.          p->
6490: 70 53 63 72 69 70 74 20 3d 20 54 63 6c 5f 44 75  pScript = Tcl_Du
64a0: 70 6c 69 63 61 74 65 4f 62 6a 28 6f 62 6a 76 5b  plicateObj(objv[
64b0: 32 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 54  2]);.          T
64c0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
64d0: 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 20  p->pScript);.   
64e0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c       }.      }el
64f0: 73 65 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29  se if( objc!=2 )
6500: 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72  {.        Tcl_Wr
6510: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
6520: 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 53 43  p, 2, objv, "?SC
6530: 52 49 50 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  RIPT?");.       
6540: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
6550: 52 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  R;.      }..    
6560: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
6570: 74 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20  t(interp);.     
6580: 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20   if( p->pScript 
6590: 29 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75  ) Tcl_SetObjResu
65a0: 6c 74 28 69 6e 74 65 72 70 2c 20 70 2d 3e 70 53  lt(interp, p->pS
65b0: 63 72 69 70 74 29 3b 0a 0a 20 20 20 20 20 20 62  cript);..      b
65c0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
65d0: 20 2f 2a 0a 20 20 20 20 2a 2a 20 54 45 53 54 56   /*.    ** TESTV
65e0: 46 53 20 69 6f 65 72 72 20 3f 49 46 41 49 4c 20  FS ioerr ?IFAIL 
65f0: 50 45 52 53 49 53 54 3f 0a 20 20 20 20 2a 2a 0a  PERSIST?.    **.
6600: 20 20 20 20 2a 2a 20 20 20 57 68 65 72 65 20 49      **   Where I
6610: 46 41 49 4c 20 69 73 20 61 6e 20 69 6e 74 65 67  FAIL is an integ
6620: 65 72 20 61 6e 64 20 50 45 52 53 49 53 54 20 69  er and PERSIST i
6630: 73 20 62 6f 6f 6c 65 61 6e 2e 0a 20 20 20 20 2a  s boolean..    *
6640: 2f 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 49  /.    case CMD_I
6650: 4f 45 52 52 3a 20 7b 0a 20 20 20 20 20 20 69 6e  OERR: {.      in
6660: 74 20 69 52 65 74 20 3d 20 70 2d 3e 6e 49 6f 65  t iRet = p->nIoe
6670: 72 72 46 61 69 6c 3b 0a 0a 20 20 20 20 20 20 70  rrFail;..      p
6680: 2d 3e 6e 49 6f 65 72 72 46 61 69 6c 20 3d 20 30  ->nIoerrFail = 0
6690: 3b 0a 20 20 20 20 20 20 70 2d 3e 69 6f 65 72 72  ;.      p->ioerr
66a0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 2d 3e 69   = 0;.      p->i
66b0: 49 6f 65 72 72 43 6e 74 20 3d 20 30 3b 0a 0a 20  IoerrCnt = 0;.. 
66c0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34       if( objc==4
66d0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
66e0: 69 43 6e 74 2c 20 69 50 65 72 73 69 73 74 3b 0a  iCnt, iPersist;.
66f0: 20 20 20 20 20 20 20 20 69 66 28 20 54 43 4c 5f          if( TCL_
6700: 4f 4b 21 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72  OK!=Tcl_GetIntFr
6710: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
6720: 6a 76 5b 32 5d 2c 20 26 69 43 6e 74 29 0a 20 20  jv[2], &iCnt).  
6730: 20 20 20 20 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b         || TCL_OK
6740: 21 3d 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e  !=Tcl_GetBoolean
6750: 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20  FromObj(interp, 
6760: 6f 62 6a 76 5b 33 5d 2c 20 26 69 50 65 72 73 69  objv[3], &iPersi
6770: 73 74 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  st).        ){. 
6780: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
6790: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
67a0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 2d 3e     }.        p->
67b0: 69 6f 65 72 72 20 3d 20 28 69 43 6e 74 3e 30 29  ioerr = (iCnt>0)
67c0: 20 2b 20 69 50 65 72 73 69 73 74 3b 0a 20 20 20   + iPersist;.   
67d0: 20 20 20 20 20 70 2d 3e 69 49 6f 65 72 72 43 6e       p->iIoerrCn
67e0: 74 20 3d 20 69 43 6e 74 3b 0a 20 20 20 20 20 20  t = iCnt;.      
67f0: 7d 65 6c 73 65 20 69 66 28 20 6f 62 6a 63 21 3d  }else if( objc!=
6800: 32 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c  2 ){.        Tcl
6810: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
6820: 74 65 72 70 2c 20 22 42 61 64 20 61 72 67 73 22  terp, "Bad args"
6830: 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 72 65  , 0);.        re
6840: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
6850: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63        }.      Tc
6860: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
6870: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e  nterp, Tcl_NewIn
6880: 74 4f 62 6a 28 69 52 65 74 29 29 3b 0a 20 20 20  tObj(iRet));.   
6890: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
68a0: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 44 45  .    case CMD_DE
68b0: 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20 20 54 63  LETE: {.      Tc
68c0: 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61 6e 64 28  l_DeleteCommand(
68d0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53  interp, Tcl_GetS
68e0: 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 29 3b  tring(objv[0]));
68f0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
6900: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
6910: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  n TCL_OK;.}..sta
6920: 74 69 63 20 76 6f 69 64 20 74 65 73 74 76 66 73  tic void testvfs
6930: 5f 6f 62 6a 5f 64 65 6c 28 43 6c 69 65 6e 74 44  _obj_del(ClientD
6940: 61 74 61 20 63 64 29 7b 0a 20 20 54 65 73 74 76  ata cd){.  Testv
6950: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
6960: 20 2a 29 63 64 3b 0a 20 20 69 66 28 20 70 2d 3e   *)cd;.  if( p->
6970: 70 53 63 72 69 70 74 20 29 20 54 63 6c 5f 44 65  pScript ) Tcl_De
6980: 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53  crRefCount(p->pS
6990: 63 72 69 70 74 29 3b 0a 20 20 73 71 6c 69 74 65  cript);.  sqlite
69a0: 33 5f 76 66 73 5f 75 6e 72 65 67 69 73 74 65 72  3_vfs_unregister
69b0: 28 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63 6b 66  (p->pVfs);.  ckf
69c0: 72 65 65 28 28 63 68 61 72 20 2a 29 70 2d 3e 61  ree((char *)p->a
69d0: 70 53 63 72 69 70 74 29 3b 0a 20 20 63 6b 66 72  pScript);.  ckfr
69e0: 65 65 28 28 63 68 61 72 20 2a 29 70 2d 3e 70 56  ee((char *)p->pV
69f0: 66 73 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63  fs);.  ckfree((c
6a00: 68 61 72 20 2a 29 70 29 3b 0a 7d 0a 0a 2f 2a 0a  har *)p);.}../*.
6a10: 2a 2a 20 55 73 61 67 65 3a 20 20 74 65 73 74 76  ** Usage:  testv
6a20: 66 73 20 56 46 53 4e 41 4d 45 20 3f 53 57 49 54  fs VFSNAME ?SWIT
6a30: 43 48 45 53 3f 0a 2a 2a 0a 2a 2a 20 53 77 69 74  CHES?.**.** Swit
6a40: 63 68 65 73 20 61 72 65 3a 0a 2a 2a 0a 2a 2a 20  ches are:.**.** 
6a50: 20 20 2d 6e 6f 73 68 6d 20 20 20 42 4f 4f 4c 45    -noshm   BOOLE
6a60: 41 4e 20 20 20 20 20 20 20 20 20 20 20 20 20 28  AN             (
6a70: 54 72 75 65 20 74 6f 20 6f 6d 69 74 20 73 68 6d  True to omit shm
6a80: 20 6d 65 74 68 6f 64 73 2e 20 44 65 66 61 75 6c   methods. Defaul
6a90: 74 20 66 61 6c 73 65 29 0a 2a 2a 20 20 20 2d 64  t false).**   -d
6aa0: 65 66 61 75 6c 74 20 42 4f 4f 4c 45 41 4e 20 20  efault BOOLEAN  
6ab0: 20 20 20 20 20 20 20 20 20 20 20 28 54 72 75 65             (True
6ac0: 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 76 66 73   to make the vfs
6ad0: 20 64 65 66 61 75 6c 74 2e 20 44 65 66 61 75 6c   default. Defaul
6ae0: 74 20 66 61 6c 73 65 29 0a 2a 2a 0a 2a 2a 20 54  t false).**.** T
6af0: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 63 72 65 61  his command crea
6b00: 74 65 73 20 74 77 6f 20 74 68 69 6e 67 73 20 77  tes two things w
6b10: 68 65 6e 20 69 74 20 69 73 20 69 6e 76 6f 6b 65  hen it is invoke
6b20: 64 3a 20 61 6e 20 53 51 4c 69 74 65 20 56 46 53  d: an SQLite VFS
6b30: 2c 20 61 6e 64 0a 2a 2a 20 61 20 54 63 6c 20 63  , and.** a Tcl c
6b40: 6f 6d 6d 61 6e 64 2e 20 42 6f 74 68 20 61 72 65  ommand. Both are
6b50: 20 6e 61 6d 65 64 20 56 46 53 4e 41 4d 45 2e 20   named VFSNAME. 
6b60: 54 68 65 20 56 46 53 20 69 73 20 69 6e 73 74 61  The VFS is insta
6b70: 6c 6c 65 64 2e 20 49 74 20 69 73 20 6e 6f 74 0a  lled. It is not.
6b80: 2a 2a 20 69 6e 73 74 61 6c 6c 65 64 20 61 73 20  ** installed as 
6b90: 74 68 65 20 64 65 66 61 75 6c 74 20 56 46 53 2e  the default VFS.
6ba0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 56 46 53 20 70  .**.** The VFS p
6bb0: 61 73 73 65 73 20 61 6c 6c 20 66 69 6c 65 20 49  asses all file I
6bc0: 2f 4f 20 63 61 6c 6c 73 20 74 68 72 6f 75 67 68  /O calls through
6bd0: 20 74 6f 20 74 68 65 20 75 6e 64 65 72 6c 79 69   to the underlyi
6be0: 6e 67 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 57 68  ng VFS..**.** Wh
6bf0: 65 6e 65 76 65 72 20 6f 6e 65 20 6f 66 20 74 68  enever one of th
6c00: 65 20 78 53 68 6d 53 69 7a 65 2c 20 78 53 68 6d  e xShmSize, xShm
6c10: 47 65 74 20 6f 72 20 78 53 68 6d 52 65 6c 65 61  Get or xShmRelea
6c20: 73 65 20 6d 65 74 68 6f 64 73 20 6f 66 20 74 68  se methods of th
6c30: 65 20 56 46 53 0a 2a 2a 20 61 72 65 20 69 6e 76  e VFS.** are inv
6c40: 6f 6b 65 64 2c 20 74 68 65 20 53 43 52 49 50 54  oked, the SCRIPT
6c50: 20 69 73 20 65 78 65 63 75 74 65 64 20 61 73 20   is executed as 
6c60: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
6c70: 20 53 43 52 49 50 54 20 78 53 68 6d 53 69 7a 65   SCRIPT xShmSize
6c80: 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49 44 0a      FILENAME ID.
6c90: 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53 68 6d  **   SCRIPT xShm
6ca0: 47 65 74 20 20 20 20 20 46 49 4c 45 4e 41 4d 45  Get     FILENAME
6cb0: 20 49 44 0a 2a 2a 20 20 20 53 43 52 49 50 54 20   ID.**   SCRIPT 
6cc0: 78 53 68 6d 52 65 6c 65 61 73 65 20 46 49 4c 45  xShmRelease FILE
6cd0: 4e 41 4d 45 20 49 44 0a 2a 2a 0a 2a 2a 20 54 68  NAME ID.**.** Th
6ce0: 65 20 76 61 6c 75 65 20 72 65 74 75 72 6e 65 64  e value returned
6cf0: 20 62 79 20 74 68 65 20 69 6e 76 6f 63 61 74 69   by the invocati
6d00: 6f 6e 20 6f 66 20 53 43 52 49 50 54 20 61 62 6f  on of SCRIPT abo
6d10: 76 65 20 69 73 20 69 6e 74 65 72 70 72 65 74 65  ve is interprete
6d20: 64 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 69 74  d as.** an SQLit
6d30: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 61 6e 64  e error code and
6d40: 20 72 65 74 75 72 6e 65 64 20 74 6f 20 53 51 4c   returned to SQL
6d50: 69 74 65 2e 20 45 69 74 68 65 72 20 61 20 73 79  ite. Either a sy
6d60: 6d 62 6f 6c 69 63 20 0a 2a 2a 20 22 53 51 4c 49  mbolic .** "SQLI
6d70: 54 45 5f 4f 4b 22 20 6f 72 20 6e 75 6d 65 72 69  TE_OK" or numeri
6d80: 63 20 22 30 22 20 76 61 6c 75 65 20 6d 61 79 20  c "0" value may 
6d90: 62 65 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  be returned..**.
6da0: 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20  ** The contents 
6db0: 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65  of the shared-me
6dc0: 6d 6f 72 79 20 62 75 66 66 65 72 20 61 73 73 6f  mory buffer asso
6dd0: 63 69 61 74 65 64 20 77 69 74 68 20 61 20 67 69  ciated with a gi
6de0: 76 65 6e 20 66 69 6c 65 0a 2a 2a 20 6d 61 79 20  ven file.** may 
6df0: 62 65 20 72 65 61 64 20 61 6e 64 20 73 65 74 20  be read and set 
6e00: 75 73 69 6e 67 20 74 68 65 20 66 6f 6c 6c 6f 77  using the follow
6e10: 69 6e 67 20 63 6f 6d 6d 61 6e 64 3a 0a 2a 2a 0a  ing command:.**.
6e20: 2a 2a 20 20 20 56 46 53 4e 41 4d 45 20 73 68 6d  **   VFSNAME shm
6e30: 20 46 49 4c 45 4e 41 4d 45 20 3f 4e 45 57 56 41   FILENAME ?NEWVA
6e40: 4c 55 45 3f 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20  LUE?.**.** When 
6e50: 74 68 65 20 78 53 68 6d 4c 6f 63 6b 20 6d 65 74  the xShmLock met
6e60: 68 6f 64 20 69 73 20 69 6e 76 6f 6b 65 64 20 62  hod is invoked b
6e70: 79 20 53 51 4c 69 74 65 2c 20 74 68 65 20 66 6f  y SQLite, the fo
6e80: 6c 6c 6f 77 69 6e 67 20 73 63 72 69 70 74 20 69  llowing script i
6e90: 73 0a 2a 2a 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20  s.** run:.**.** 
6ea0: 20 20 53 43 52 49 50 54 20 78 53 68 6d 4c 6f 63    SCRIPT xShmLoc
6eb0: 6b 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49 44  k    FILENAME ID
6ec0: 20 4c 4f 43 4b 0a 2a 2a 0a 2a 2a 20 77 68 65 72   LOCK.**.** wher
6ed0: 65 20 4c 4f 43 4b 20 69 73 20 6f 66 20 74 68 65  e LOCK is of the
6ee0: 20 66 6f 72 6d 20 22 4f 46 46 53 45 54 20 4e 42   form "OFFSET NB
6ef0: 59 54 45 20 6c 6f 63 6b 2f 75 6e 6c 6f 63 6b 20  YTE lock/unlock 
6f00: 73 68 61 72 65 64 2f 65 78 63 6c 75 73 69 76 65  shared/exclusive
6f10: 22 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ".*/.static int 
6f20: 74 65 73 74 76 66 73 5f 63 6d 64 28 0a 20 20 43  testvfs_cmd(.  C
6f30: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a 20 20  lientData cd,.  
6f40: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6f50: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
6f60: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
6f70: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 73 74 61   objv[].){.  sta
6f80: 74 69 63 20 73 71 6c 69 74 65 33 5f 76 66 73 20  tic sqlite3_vfs 
6f90: 74 76 66 73 5f 76 66 73 20 3d 20 7b 0a 20 20 20  tvfs_vfs = {.   
6fa0: 20 32 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   2,             
6fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6fc0: 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20  * iVersion */.  
6fd0: 20 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73    sizeof(Testvfs
6fe0: 46 69 6c 65 29 2c 20 20 20 20 20 20 20 20 20 20  File),          
6ff0: 20 20 2f 2a 20 73 7a 4f 73 46 69 6c 65 20 2a 2f    /* szOsFile */
7000: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
7010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7020: 20 20 20 2f 2a 20 6d 78 50 61 74 68 6e 61 6d 65     /* mxPathname
7030: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
7040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7050: 20 20 20 20 20 20 2f 2a 20 70 4e 65 78 74 20 2a        /* pNext *
7060: 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  /.    0,        
7070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7080: 20 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f 0a      /* zName */.
7090: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
70a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70b0: 20 20 2f 2a 20 70 41 70 70 44 61 74 61 20 2a 2f    /* pAppData */
70c0: 0a 20 20 20 20 74 76 66 73 4f 70 65 6e 2c 20 20  .    tvfsOpen,  
70d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70e0: 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2a 2f 0a 20     /* xOpen */. 
70f0: 20 20 20 74 76 66 73 44 65 6c 65 74 65 2c 20 20     tvfsDelete,  
7100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7110: 20 2f 2a 20 78 44 65 6c 65 74 65 20 2a 2f 0a 20   /* xDelete */. 
7120: 20 20 20 74 76 66 73 41 63 63 65 73 73 2c 20 20     tvfsAccess,  
7130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7140: 20 2f 2a 20 78 41 63 63 65 73 73 20 2a 2f 0a 20   /* xAccess */. 
7150: 20 20 20 74 76 66 73 46 75 6c 6c 50 61 74 68 6e     tvfsFullPathn
7160: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ame,            
7170: 20 2f 2a 20 78 46 75 6c 6c 50 61 74 68 6e 61 6d   /* xFullPathnam
7180: 65 20 2a 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c  e */.#ifndef SQL
7190: 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58  ITE_OMIT_LOAD_EX
71a0: 54 45 4e 53 49 4f 4e 0a 20 20 20 20 74 76 66 73  TENSION.    tvfs
71b0: 44 6c 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  DlOpen,         
71c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
71d0: 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73  Open */.    tvfs
71e0: 44 6c 45 72 72 6f 72 2c 20 20 20 20 20 20 20 20  DlError,        
71f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
7200: 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 74 76 66  Error */.    tvf
7210: 73 44 6c 53 79 6d 2c 20 20 20 20 20 20 20 20 20  sDlSym,         
7220: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
7230: 6c 53 79 6d 20 2a 2f 0a 20 20 20 20 74 76 66 73  lSym */.    tvfs
7240: 44 6c 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20  DlClose,        
7250: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
7260: 43 6c 6f 73 65 20 2a 2f 0a 23 65 6c 73 65 0a 20  Close */.#else. 
7270: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
7280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7290: 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a 20   /* xDlOpen */. 
72a0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
72b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72c0: 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f 0a   /* xDlError */.
72d0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
72e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72f0: 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20    /* xDlSym */. 
7300: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
7310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7320: 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a   /* xDlClose */.
7330: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
7340: 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e  _OMIT_LOAD_EXTEN
7350: 53 49 4f 4e 20 2a 2f 0a 20 20 20 20 74 76 66 73  SION */.    tvfs
7360: 52 61 6e 64 6f 6d 6e 65 73 73 2c 20 20 20 20 20  Randomness,     
7370: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 61            /* xRa
7380: 6e 64 6f 6d 6e 65 73 73 20 2a 2f 0a 20 20 20 20  ndomness */.    
7390: 74 76 66 73 53 6c 65 65 70 2c 20 20 20 20 20 20  tvfsSleep,      
73a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
73b0: 20 78 53 6c 65 65 70 20 2a 2f 0a 20 20 20 20 74   xSleep */.    t
73c0: 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 2c 20  vfsCurrentTime, 
73d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
73e0: 78 43 75 72 72 65 6e 74 54 69 6d 65 20 2a 2f 0a  xCurrentTime */.
73f0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
7400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7410: 20 20 2f 2a 20 78 47 65 74 4c 61 73 74 45 72 72    /* xGetLastErr
7420: 6f 72 20 2a 2f 0a 20 20 20 20 30 2c 0a 20 20 20  or */.    0,.   
7430: 20 30 2c 0a 20 20 7d 3b 0a 0a 20 20 54 65 73 74   0,.  };..  Test
7440: 76 66 73 20 2a 70 3b 20 20 20 20 20 20 20 20 20  vfs *p;         
7450: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
7460: 65 77 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73  ew object */.  s
7470: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
7480: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
7490: 2a 20 4e 65 77 20 56 46 53 20 2a 2f 0a 20 20 63  * New VFS */.  c
74a0: 68 61 72 20 2a 7a 56 66 73 3b 0a 20 20 69 6e 74  har *zVfs;.  int
74b0: 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20   nByte;         
74c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
74d0: 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74  Bytes of space t
74e0: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 74 20 70 20  o allocate at p 
74f0: 2a 2f 0a 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  */..  int i;.  i
7500: 6e 74 20 69 73 4e 6f 73 68 6d 20 3d 20 30 3b 20  nt isNoshm = 0; 
7510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7520: 2a 20 54 72 75 65 20 69 66 20 2d 6e 6f 73 68 6d  * True if -noshm
7530: 20 69 73 20 70 61 73 73 65 64 20 2a 2f 0a 20 20   is passed */.  
7540: 69 6e 74 20 69 73 44 65 66 61 75 6c 74 20 3d 20  int isDefault = 
7550: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
7560: 2f 2a 20 54 72 75 65 20 69 66 20 2d 64 65 66 61  /* True if -defa
7570: 75 6c 74 20 69 73 20 70 61 73 73 65 64 20 2a 2f  ult is passed */
7580: 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20 7c  ..  if( objc<2 |
7590: 7c 20 30 21 3d 28 6f 62 6a 63 25 32 29 20 29 20  | 0!=(objc%2) ) 
75a0: 67 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b 0a 20  goto bad_args;. 
75b0: 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6f 62 6a 63   for(i=2; i<objc
75c0: 3b 20 69 20 2b 3d 20 32 29 7b 0a 20 20 20 20 69  ; i += 2){.    i
75d0: 6e 74 20 6e 53 77 69 74 63 68 3b 0a 20 20 20 20  nt nSwitch;.    
75e0: 63 68 61 72 20 2a 7a 53 77 69 74 63 68 3b 0a 0a  char *zSwitch;..
75f0: 20 20 20 20 7a 53 77 69 74 63 68 20 3d 20 54 63      zSwitch = Tc
7600: 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f  l_GetStringFromO
7610: 62 6a 28 6f 62 6a 76 5b 69 5d 2c 20 26 6e 53 77  bj(objv[i], &nSw
7620: 69 74 63 68 29 3b 20 0a 20 20 20 20 69 66 28 20  itch); .    if( 
7630: 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d  nSwitch>2 && 0==
7640: 73 74 72 6e 63 6d 70 28 22 2d 6e 6f 73 68 6d 22  strncmp("-noshm"
7650: 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74  , zSwitch, nSwit
7660: 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ch) ){.      if(
7670: 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46   Tcl_GetBooleanF
7680: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
7690: 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 4e 6f 73  bjv[i+1], &isNos
76a0: 68 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72  hm) ){.        r
76b0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
76c0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
76d0: 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69     else if( nSwi
76e0: 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e  tch>2 && 0==strn
76f0: 63 6d 70 28 22 2d 64 65 66 61 75 6c 74 22 2c 20  cmp("-default", 
7700: 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68  zSwitch, nSwitch
7710: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54  ) ){.      if( T
7720: 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f  cl_GetBooleanFro
7730: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
7740: 76 5b 69 2b 31 5d 2c 20 26 69 73 44 65 66 61 75  v[i+1], &isDefau
7750: 6c 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72  lt) ){.        r
7760: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
7770: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
7780: 20 20 20 65 6c 73 65 7b 0a 20 20 20 20 20 20 67     else{.      g
7790: 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b 0a 20 20  oto bad_args;.  
77a0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 56 66 73 20    }.  }..  zVfs 
77b0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
77c0: 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 6e 42 79 74  objv[1]);.  nByt
77d0: 65 20 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76  e = sizeof(Testv
77e0: 66 73 29 20 2b 20 73 74 72 6c 65 6e 28 7a 56 66  fs) + strlen(zVf
77f0: 73 29 2b 31 3b 0a 20 20 70 20 3d 20 28 54 65 73  s)+1;.  p = (Tes
7800: 74 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e  tvfs *)ckalloc(n
7810: 42 79 74 65 29 3b 0a 20 20 6d 65 6d 73 65 74 28  Byte);.  memset(
7820: 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a 20  p, 0, nByte);.. 
7830: 20 70 2d 3e 70 50 61 72 65 6e 74 20 3d 20 73 71   p->pParent = sq
7840: 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30  lite3_vfs_find(0
7850: 29 3b 0a 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d  );.  p->interp =
7860: 20 69 6e 74 65 72 70 3b 0a 0a 20 20 70 2d 3e 7a   interp;..  p->z
7870: 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29 26  Name = (char *)&
7880: 70 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70  p[1];.  memcpy(p
7890: 2d 3e 7a 4e 61 6d 65 2c 20 7a 56 66 73 2c 20 73  ->zName, zVfs, s
78a0: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 29 3b 0a  trlen(zVfs)+1);.
78b0: 0a 20 20 70 56 66 73 20 3d 20 28 73 71 6c 69 74  .  pVfs = (sqlit
78c0: 65 33 5f 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63  e3_vfs *)ckalloc
78d0: 28 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f  (sizeof(sqlite3_
78e0: 76 66 73 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28  vfs));.  memcpy(
78f0: 70 56 66 73 2c 20 26 74 76 66 73 5f 76 66 73 2c  pVfs, &tvfs_vfs,
7900: 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f   sizeof(sqlite3_
7910: 76 66 73 29 29 3b 0a 20 20 70 56 66 73 2d 3e 70  vfs));.  pVfs->p
7920: 41 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20  AppData = (void 
7930: 2a 29 70 3b 0a 20 20 70 56 66 73 2d 3e 7a 4e 61  *)p;.  pVfs->zNa
7940: 6d 65 20 3d 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 20  me = p->zName;. 
7950: 20 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e 61 6d   pVfs->mxPathnam
7960: 65 20 3d 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e  e = p->pParent->
7970: 6d 78 50 61 74 68 6e 61 6d 65 3b 0a 20 20 70 56  mxPathname;.  pV
7980: 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20 2b 3d 20  fs->szOsFile += 
7990: 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 73 7a 4f 73  p->pParent->szOs
79a0: 46 69 6c 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20  File;.  p->pVfs 
79b0: 3d 20 70 56 66 73 3b 0a 20 20 70 2d 3e 69 73 4e  = pVfs;.  p->isN
79c0: 6f 73 68 6d 20 3d 20 69 73 4e 6f 73 68 6d 3b 0a  oshm = isNoshm;.
79d0: 20 20 70 2d 3e 6d 61 73 6b 20 3d 20 54 45 53 54    p->mask = TEST
79e0: 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 3b 0a 0a 20  VFS_ALL_MASK;.. 
79f0: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
7a00: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 7a 56  mmand(interp, zV
7a10: 66 73 2c 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f  fs, testvfs_obj_
7a20: 63 6d 64 2c 20 70 2c 20 74 65 73 74 76 66 73 5f  cmd, p, testvfs_
7a30: 6f 62 6a 5f 64 65 6c 29 3b 0a 20 20 73 71 6c 69  obj_del);.  sqli
7a40: 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74 65 72  te3_vfs_register
7a50: 28 70 56 66 73 2c 20 69 73 44 65 66 61 75 6c 74  (pVfs, isDefault
7a60: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  );..  return TCL
7a70: 5f 4f 4b 3b 0a 0a 20 62 61 64 5f 61 72 67 73 3a  _OK;.. bad_args:
7a80: 0a 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41  .  Tcl_WrongNumA
7a90: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
7aa0: 62 6a 76 2c 20 22 56 46 53 4e 41 4d 45 20 3f 2d  bjv, "VFSNAME ?-
7ab0: 6e 6f 73 68 6d 20 42 4f 4f 4c 3f 20 3f 2d 64 65  noshm BOOL? ?-de
7ac0: 66 61 75 6c 74 20 42 4f 4f 4c 3f 22 29 3b 0a 20  fault BOOL?");. 
7ad0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7ae0: 52 3b 0a 7d 0a 0a 69 6e 74 20 53 71 6c 69 74 65  R;.}..int Sqlite
7af0: 74 65 73 74 76 66 73 5f 49 6e 69 74 28 54 63 6c  testvfs_Init(Tcl
7b00: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29  _Interp *interp)
7b10: 7b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62  {.  Tcl_CreateOb
7b20: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
7b30: 20 22 74 65 73 74 76 66 73 22 2c 20 74 65 73 74   "testvfs", test
7b40: 76 66 73 5f 63 6d 64 2c 20 30 2c 20 30 29 3b 0a  vfs_cmd, 0, 0);.
7b50: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
7b60: 0a 7d 0a 0a 23 65 6e 64 69 66 0a                 .}..#endif.