/ Hex Artifact Content
Login

Artifact e7855568dfa1e0ba73668d273b65605d9f8b77e8:


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 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74   file contains t
0190: 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  he implementatio
01a0: 6e 20 6f 66 20 74 68 65 20 54 63 6c 20 5b 74 65  n of the Tcl [te
01b0: 73 74 76 66 73 5d 20 63 6f 6d 6d 61 6e 64 2c 0a  stvfs] command,.
01c0: 2a 2a 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  ** used to creat
01d0: 65 20 53 51 4c 69 74 65 20 56 46 53 20 69 6d 70  e SQLite VFS imp
01e0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20 77 69 74  lementations wit
01f0: 68 20 76 61 72 69 6f 75 73 20 70 72 6f 70 65 72  h various proper
0200: 74 69 65 73 20 61 6e 64 0a 2a 2a 20 69 6e 73 74  ties and.** inst
0210: 72 75 6d 65 6e 74 61 74 69 6f 6e 20 74 6f 20 73  rumentation to s
0220: 75 70 70 6f 72 74 20 74 65 73 74 69 6e 67 20 53  upport testing S
0230: 51 4c 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 74  QLite..**.**   t
0240: 65 73 74 76 66 73 20 56 46 53 4e 41 4d 45 20 3f  estvfs VFSNAME ?
0250: 4f 50 54 49 4f 4e 53 3f 0a 2a 2a 0a 2a 2a 20 41  OPTIONS?.**.** A
0260: 76 61 69 6c 61 62 6c 65 20 6f 70 74 69 6f 6e 73  vailable options
0270: 20 61 72 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e   are:.**.**   -n
0280: 6f 73 68 6d 20 20 20 20 20 20 42 4f 4f 4c 45 41  oshm      BOOLEA
0290: 4e 20 20 20 20 20 20 20 20 28 54 72 75 65 20 74  N        (True t
02a0: 6f 20 6f 6d 69 74 20 73 68 6d 20 6d 65 74 68 6f  o omit shm metho
02b0: 64 73 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73  ds. Default fals
02c0: 65 29 0a 2a 2a 20 20 20 2d 64 65 66 61 75 6c 74  e).**   -default
02d0: 20 20 20 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20      BOOLEAN     
02e0: 20 20 20 28 54 72 75 65 20 74 6f 20 6d 61 6b 65     (True to make
02f0: 20 74 68 65 20 76 66 73 20 64 65 66 61 75 6c 74   the vfs default
0300: 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29  . Default false)
0310: 0a 2a 2a 20 20 20 2d 73 7a 6f 73 66 69 6c 65 20  .**   -szosfile 
0320: 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20 20    INTEGER       
0330: 20 28 56 61 6c 75 65 20 66 6f 72 20 73 71 6c 69   (Value for sqli
0340: 74 65 33 5f 76 66 73 2e 73 7a 4f 73 46 69 6c 65  te3_vfs.szOsFile
0350: 29 0a 2a 2a 20 20 20 2d 6d 78 70 61 74 68 6e 61  ).**   -mxpathna
0360: 6d 65 20 49 4e 54 45 47 45 52 20 20 20 20 20 20  me INTEGER      
0370: 20 20 28 56 61 6c 75 65 20 66 6f 72 20 73 71 6c    (Value for sql
0380: 69 74 65 33 5f 76 66 73 2e 6d 78 50 61 74 68 6e  ite3_vfs.mxPathn
0390: 61 6d 65 29 0a 2a 2a 20 20 20 2d 69 76 65 72 73  ame).**   -ivers
03a0: 69 6f 6e 20 20 20 49 4e 54 45 47 45 52 20 20 20  ion   INTEGER   
03b0: 20 20 20 20 20 28 56 61 6c 75 65 20 66 6f 72 20       (Value for 
03c0: 73 71 6c 69 74 65 33 5f 76 66 73 2e 69 56 65 72  sqlite3_vfs.iVer
03d0: 73 69 6f 6e 29 0a 2a 2f 0a 23 69 66 20 53 51 4c  sion).*/.#if SQL
03e0: 49 54 45 5f 54 45 53 54 20 20 20 20 20 20 20 20  ITE_TEST        
03f0: 20 20 2f 2a 20 54 68 69 73 20 66 69 6c 65 20 69    /* This file i
0400: 73 20 75 73 65 64 20 66 6f 72 20 74 65 73 74 69  s used for testi
0410: 6e 67 20 6f 6e 6c 79 20 2a 2f 0a 0a 23 69 6e 63  ng only */..#inc
0420: 6c 75 64 65 20 22 73 71 6c 69 74 65 33 2e 68 22  lude "sqlite3.h"
0430: 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74  .#include "sqlit
0440: 65 49 6e 74 2e 68 22 0a 0a 74 79 70 65 64 65 66  eInt.h"..typedef
0450: 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73 20   struct Testvfs 
0460: 54 65 73 74 76 66 73 3b 0a 74 79 70 65 64 65 66  Testvfs;.typedef
0470: 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73 53   struct TestvfsS
0480: 68 6d 20 54 65 73 74 76 66 73 53 68 6d 3b 0a 74  hm TestvfsShm;.t
0490: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54 65  ypedef struct Te
04a0: 73 74 76 66 73 42 75 66 66 65 72 20 54 65 73 74  stvfsBuffer Test
04b0: 76 66 73 42 75 66 66 65 72 3b 0a 74 79 70 65 64  vfsBuffer;.typed
04c0: 65 66 20 73 74 72 75 63 74 20 54 65 73 74 76 66  ef struct Testvf
04d0: 73 46 69 6c 65 20 54 65 73 74 76 66 73 46 69 6c  sFile TestvfsFil
04e0: 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  e;.typedef struc
04f0: 74 20 54 65 73 74 76 66 73 46 64 20 54 65 73 74  t TestvfsFd Test
0500: 76 66 73 46 64 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e  vfsFd;../*.** An
0510: 20 6f 70 65 6e 20 66 69 6c 65 20 68 61 6e 64 6c   open file handl
0520: 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73  e..*/.struct Tes
0530: 74 76 66 73 46 69 6c 65 20 7b 0a 20 20 73 71 6c  tvfsFile {.  sql
0540: 69 74 65 33 5f 66 69 6c 65 20 62 61 73 65 3b 20  ite3_file base; 
0550: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0560: 42 61 73 65 20 63 6c 61 73 73 2e 20 20 4d 75 73  Base class.  Mus
0570: 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20 20  t be first */.  
0580: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 3b 20  TestvfsFd *pFd; 
0590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05a0: 2f 2a 20 46 69 6c 65 20 64 61 74 61 20 2a 2f 0a  /* File data */.
05b0: 7d 3b 0a 23 64 65 66 69 6e 65 20 74 76 66 73 47  };.#define tvfsG
05c0: 65 74 46 64 28 70 46 69 6c 65 29 20 28 28 28 54  etFd(pFile) (((T
05d0: 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69  estvfsFile *)pFi
05e0: 6c 65 29 2d 3e 70 46 64 29 0a 0a 73 74 72 75 63  le)->pFd)..struc
05f0: 74 20 54 65 73 74 76 66 73 46 64 20 7b 0a 20 20  t TestvfsFd {.  
0600: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
0610: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
0620: 2f 2a 20 54 68 65 20 56 46 53 20 2a 2f 0a 20 20  /* The VFS */.  
0630: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c  const char *zFil
0640: 65 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  ename;          
0650: 2f 2a 20 46 69 6c 65 6e 61 6d 65 20 61 73 20 70  /* Filename as p
0660: 61 73 73 65 64 20 74 6f 20 78 4f 70 65 6e 28 29  assed to xOpen()
0670: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
0680: 6c 65 20 2a 70 52 65 61 6c 3b 20 20 20 20 20 20  le *pReal;      
0690: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 72 65 61        /* The rea
06a0: 6c 2c 20 75 6e 64 65 72 6c 79 69 6e 67 20 66 69  l, underlying fi
06b0: 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 2a 2f  le descriptor */
06c0: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 68 6d  .  Tcl_Obj *pShm
06d0: 49 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  Id;             
06e0: 20 20 20 2f 2a 20 53 68 61 72 65 64 20 6d 65 6d     /* Shared mem
06f0: 6f 72 79 20 69 64 20 66 6f 72 20 54 63 6c 20 63  ory id for Tcl c
0700: 61 6c 6c 62 61 63 6b 73 20 2a 2f 0a 0a 20 20 54  allbacks */..  T
0710: 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 53  estvfsBuffer *pS
0720: 68 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  hm;            /
0730: 2a 20 53 68 61 72 65 64 20 6d 65 6d 6f 72 79 20  * Shared memory 
0740: 62 75 66 66 65 72 20 2a 2f 0a 20 20 75 33 32 20  buffer */.  u32 
0750: 65 78 63 6c 6c 6f 63 6b 3b 20 20 20 20 20 20 20  excllock;       
0760: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
0770: 61 73 6b 20 6f 66 20 65 78 63 6c 75 73 69 76 65  ask of exclusive
0780: 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20 75 33 32 20   locks */.  u32 
0790: 73 68 61 72 65 64 6c 6f 63 6b 3b 20 20 20 20 20  sharedlock;     
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
07b0: 61 73 6b 20 6f 66 20 73 68 61 72 65 64 20 6c 6f  ask of shared lo
07c0: 63 6b 73 20 2a 2f 0a 20 20 54 65 73 74 76 66 73  cks */.  Testvfs
07d0: 46 64 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20  Fd *pNext;      
07e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
07f0: 20 68 61 6e 64 6c 65 20 6f 70 65 6e 65 64 20 6f   handle opened o
0800: 6e 20 74 68 65 20 73 61 6d 65 20 66 69 6c 65 20  n the same file 
0810: 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69 6e 65 20  */.};...#define 
0820: 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 4e 4f 4e  FAULT_INJECT_NON
0830: 45 20 20 20 20 20 20 20 30 0a 23 64 65 66 69 6e  E       0.#defin
0840: 65 20 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 54  e FAULT_INJECT_T
0850: 52 41 4e 53 49 45 4e 54 20 20 31 0a 23 64 65 66  RANSIENT  1.#def
0860: 69 6e 65 20 46 41 55 4c 54 5f 49 4e 4a 45 43 54  ine FAULT_INJECT
0870: 5f 50 45 52 53 49 53 54 45 4e 54 20 32 0a 0a 74  _PERSISTENT 2..t
0880: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54 65  ypedef struct Te
0890: 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 54 65  stFaultInject Te
08a0: 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 3b 0a 73  stFaultInject;.s
08b0: 74 72 75 63 74 20 54 65 73 74 46 61 75 6c 74 49  truct TestFaultI
08c0: 6e 6a 65 63 74 20 7b 0a 20 20 69 6e 74 20 69 43  nject {.  int iC
08d0: 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  nt;             
08e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 6d            /* Rem
08f0: 61 69 6e 69 6e 67 20 63 61 6c 6c 73 20 62 65 66  aining calls bef
0900: 6f 72 65 20 66 61 75 6c 74 20 69 6e 6a 65 63 74  ore fault inject
0910: 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 65 46 61  ion */.  int eFa
0920: 75 6c 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ult;            
0930: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 20 46 41           /* A FA
0940: 55 4c 54 5f 49 4e 4a 45 43 54 5f 2a 20 76 61 6c  ULT_INJECT_* val
0950: 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 61 69  ue */.  int nFai
0960: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
0970: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0980: 72 20 6f 66 20 66 61 75 6c 74 73 20 69 6e 6a 65  r of faults inje
0990: 63 74 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  cted */.};../*.*
09a0: 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  * An instance of
09b0: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20   this structure 
09c0: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72  is allocated for
09d0: 20 65 61 63 68 20 56 46 53 20 63 72 65 61 74 65   each VFS create
09e0: 64 2e 20 54 68 65 0a 2a 2a 20 73 71 6c 69 74 65  d. The.** sqlite
09f0: 33 5f 76 66 73 2e 70 41 70 70 44 61 74 61 20 66  3_vfs.pAppData f
0a00: 69 65 6c 64 20 6f 66 20 74 68 65 20 56 46 53 20  ield of the VFS 
0a10: 73 74 72 75 63 74 75 72 65 20 72 65 67 69 73 74  structure regist
0a20: 65 72 65 64 20 77 69 74 68 20 53 51 4c 69 74 65  ered with SQLite
0a30: 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f 20 70 6f  .** is set to po
0a40: 69 6e 74 20 74 6f 20 69 74 2e 0a 2a 2f 0a 73 74  int to it..*/.st
0a50: 72 75 63 74 20 54 65 73 74 76 66 73 20 7b 0a 20  ruct Testvfs {. 
0a60: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20   char *zName;   
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a80: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 69 73   /* Name of this
0a90: 20 56 46 53 20 2a 2f 0a 20 20 73 71 6c 69 74 65   VFS */.  sqlite
0aa0: 33 5f 76 66 73 20 2a 70 50 61 72 65 6e 74 3b 20  3_vfs *pParent; 
0ab0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
0ac0: 20 56 46 53 20 74 6f 20 75 73 65 20 66 6f 72 20   VFS to use for 
0ad0: 66 69 6c 65 20 49 4f 20 2a 2f 0a 20 20 73 71 6c  file IO */.  sql
0ae0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 20  ite3_vfs *pVfs; 
0af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0b00: 54 68 65 20 74 65 73 74 76 66 73 20 72 65 67 69  The testvfs regi
0b10: 73 74 65 72 65 64 20 77 69 74 68 20 53 51 4c 69  stered with SQLi
0b20: 74 65 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  te */.  Tcl_Inte
0b30: 72 70 20 2a 69 6e 74 65 72 70 3b 20 20 20 20 20  rp *interp;     
0b40: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 74 65 72          /* Inter
0b50: 70 72 65 74 65 72 20 74 6f 20 72 75 6e 20 73 63  preter to run sc
0b60: 72 69 70 74 20 69 6e 20 2a 2f 0a 20 20 54 63 6c  ript in */.  Tcl
0b70: 5f 4f 62 6a 20 2a 70 53 63 72 69 70 74 3b 20 20  _Obj *pScript;  
0b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0b90: 53 63 72 69 70 74 20 74 6f 20 65 78 65 63 75 74  Script to execut
0ba0: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69  e */.  int nScri
0bb0: 70 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  pt;             
0bc0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
0bd0: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
0be0: 61 72 72 61 79 20 61 70 53 63 72 69 70 74 20 2a  array apScript *
0bf0: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70  /.  Tcl_Obj **ap
0c00: 53 63 72 69 70 74 3b 20 20 20 20 20 20 20 20 20  Script;         
0c10: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 76 65 72      /* Array ver
0c20: 73 69 6f 6e 20 6f 66 20 70 53 63 72 69 70 74 20  sion of pScript 
0c30: 2a 2f 0a 20 20 54 65 73 74 76 66 73 42 75 66 66  */.  TestvfsBuff
0c40: 65 72 20 2a 70 42 75 66 66 65 72 3b 20 20 20 20  er *pBuffer;    
0c50: 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20       /* List of 
0c60: 73 68 61 72 65 64 20 62 75 66 66 65 72 73 20 2a  shared buffers *
0c70: 2f 0a 20 20 69 6e 74 20 69 73 4e 6f 73 68 6d 3b  /.  int isNoshm;
0c80: 0a 0a 20 20 69 6e 74 20 6d 61 73 6b 3b 20 20 20  ..  int mask;   
0c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ca0: 20 20 20 20 2f 2a 20 4d 61 73 6b 20 63 6f 6e 74      /* Mask cont
0cb0: 72 6f 6c 6c 69 6e 67 20 5b 73 63 72 69 70 74 5d  rolling [script]
0cc0: 20 61 6e 64 20 5b 69 6f 65 72 72 5d 20 2a 2f 0a   and [ioerr] */.
0cd0: 0a 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65  .  TestFaultInje
0ce0: 63 74 20 69 6f 65 72 72 5f 65 72 72 3b 0a 20 20  ct ioerr_err;.  
0cf0: 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20  TestFaultInject 
0d00: 66 75 6c 6c 5f 65 72 72 3b 0a 20 20 54 65 73 74  full_err;.  Test
0d10: 46 61 75 6c 74 49 6e 6a 65 63 74 20 63 61 6e 74  FaultInject cant
0d20: 6f 70 65 6e 5f 65 72 72 3b 0a 0a 23 69 66 20 30  open_err;..#if 0
0d30: 0a 20 20 69 6e 74 20 69 49 6f 65 72 72 43 6e 74  .  int iIoerrCnt
0d40: 3b 0a 20 20 69 6e 74 20 69 6f 65 72 72 3b 0a 20  ;.  int ioerr;. 
0d50: 20 69 6e 74 20 6e 49 6f 65 72 72 46 61 69 6c 3b   int nIoerrFail;
0d60: 0a 20 20 69 6e 74 20 69 46 75 6c 6c 43 6e 74 3b  .  int iFullCnt;
0d70: 0a 20 20 69 6e 74 20 66 75 6c 6c 65 72 72 3b 0a  .  int fullerr;.
0d80: 20 20 69 6e 74 20 6e 46 75 6c 6c 46 61 69 6c 3b    int nFullFail;
0d90: 0a 23 65 6e 64 69 66 0a 0a 20 20 69 6e 74 20 69  .#endif..  int i
0da0: 44 65 76 63 68 61 72 3b 0a 20 20 69 6e 74 20 69  Devchar;.  int i
0db0: 53 65 63 74 6f 72 73 69 7a 65 3b 0a 7d 3b 0a 0a  Sectorsize;.};..
0dc0: 2f 2a 0a 2a 2a 20 54 68 65 20 54 65 73 74 76 66  /*.** The Testvf
0dd0: 73 2e 6d 61 73 6b 20 76 61 72 69 61 62 6c 65 20  s.mask variable 
0de0: 69 73 20 73 65 74 20 74 6f 20 61 20 63 6f 6d 62  is set to a comb
0df0: 69 6e 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 66  ination of the f
0e00: 6f 6c 6c 6f 77 69 6e 67 2e 0a 2a 2a 20 49 66 20  ollowing..** If 
0e10: 61 20 62 69 74 20 69 73 20 63 6c 65 61 72 20 69  a bit is clear i
0e20: 6e 20 54 65 73 74 76 66 73 2e 6d 61 73 6b 2c 20  n Testvfs.mask, 
0e30: 74 68 65 6e 20 63 61 6c 6c 73 20 6d 61 64 65 20  then calls made 
0e40: 62 79 20 53 51 4c 69 74 65 20 74 6f 20 74 68 65  by SQLite to the
0e50: 20 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69   .** correspondi
0e60: 6e 67 20 56 46 53 20 6d 65 74 68 6f 64 20 69 73  ng VFS method is
0e70: 20 69 67 6e 6f 72 65 64 20 66 6f 72 20 70 75 72   ignored for pur
0e80: 70 6f 73 65 73 20 6f 66 3a 0a 2a 2a 0a 2a 2a 20  poses of:.**.** 
0e90: 20 20 2b 20 53 69 6d 75 6c 61 74 69 6e 67 20 49    + Simulating I
0ea0: 4f 20 65 72 72 6f 72 73 2c 20 61 6e 64 0a 2a 2a  O errors, and.**
0eb0: 20 20 20 2b 20 49 6e 76 6f 6b 69 6e 67 20 74 68     + Invoking th
0ec0: 65 20 54 63 6c 20 63 61 6c 6c 62 61 63 6b 20 73  e Tcl callback s
0ed0: 63 72 69 70 74 2e 0a 2a 2f 0a 23 64 65 66 69 6e  cript..*/.#defin
0ee0: 65 20 54 45 53 54 56 46 53 5f 53 48 4d 4f 50 45  e TESTVFS_SHMOPE
0ef0: 4e 5f 4d 41 53 4b 20 20 20 20 20 20 30 78 30 30  N_MASK      0x00
0f00: 30 30 30 30 30 31 0a 23 64 65 66 69 6e 65 20 54  000001.#define T
0f10: 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d  ESTVFS_SHMLOCK_M
0f20: 41 53 4b 20 20 20 20 20 20 30 78 30 30 30 30 30  ASK      0x00000
0f30: 30 31 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  010.#define TEST
0f40: 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20  VFS_SHMMAP_MASK 
0f50: 20 20 20 20 20 20 30 78 30 30 30 30 30 30 32 30        0x00000020
0f60: 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53  .#define TESTVFS
0f70: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
0f80: 20 20 20 30 78 30 30 30 30 30 30 34 30 0a 23 64     0x00000040.#d
0f90: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48  efine TESTVFS_SH
0fa0: 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 20 20 20 20  MCLOSE_MASK     
0fb0: 30 78 30 30 30 30 30 30 38 30 0a 0a 23 64 65 66  0x00000080..#def
0fc0: 69 6e 65 20 54 45 53 54 56 46 53 5f 4f 50 45 4e  ine TESTVFS_OPEN
0fd0: 5f 4d 41 53 4b 20 20 20 20 20 20 20 20 20 30 78  _MASK         0x
0fe0: 30 30 30 30 30 31 30 30 0a 23 64 65 66 69 6e 65  00000100.#define
0ff0: 20 54 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41   TESTVFS_SYNC_MA
1000: 53 4b 20 20 20 20 20 20 20 20 20 30 78 30 30 30  SK         0x000
1010: 30 30 32 30 30 0a 23 64 65 66 69 6e 65 20 54 45  00200.#define TE
1020: 53 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d 41 53  STVFS_DELETE_MAS
1030: 4b 20 20 20 20 20 20 20 30 78 30 30 30 30 30 34  K       0x000004
1040: 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  00.#define TESTV
1050: 46 53 5f 43 4c 4f 53 45 5f 4d 41 53 4b 20 20 20  FS_CLOSE_MASK   
1060: 20 20 20 20 20 30 78 30 30 30 30 30 38 30 30 0a       0x00000800.
1070: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
1080: 57 52 49 54 45 5f 4d 41 53 4b 20 20 20 20 20 20  WRITE_MASK      
1090: 20 20 30 78 30 30 30 30 31 30 30 30 0a 23 64 65    0x00001000.#de
10a0: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 54 52 55  fine TESTVFS_TRU
10b0: 4e 43 41 54 45 5f 4d 41 53 4b 20 20 20 20 20 30  NCATE_MASK     0
10c0: 78 30 30 30 30 32 30 30 30 0a 23 64 65 66 69 6e  x00002000.#defin
10d0: 65 20 54 45 53 54 56 46 53 5f 41 43 43 45 53 53  e TESTVFS_ACCESS
10e0: 5f 4d 41 53 4b 20 20 20 20 20 20 20 30 78 30 30  _MASK       0x00
10f0: 30 30 34 30 30 30 0a 23 64 65 66 69 6e 65 20 54  004000.#define T
1100: 45 53 54 56 46 53 5f 46 55 4c 4c 50 41 54 48 4e  ESTVFS_FULLPATHN
1110: 41 4d 45 5f 4d 41 53 4b 20 30 78 30 30 30 30 38  AME_MASK 0x00008
1120: 30 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  000.#define TEST
1130: 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20 20 20 20  VFS_ALL_MASK    
1140: 20 20 20 20 20 20 30 78 30 30 30 31 46 46 46 46        0x0001FFFF
1150: 0a 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  ...#define TESTV
1160: 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 31 30 32  FS_MAX_PAGES 102
1170: 34 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72 65  4../*.** A share
1180: 64 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e  d-memory buffer.
1190: 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f 66   There is one of
11a0: 20 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20 66   these objects f
11b0: 6f 72 20 65 61 63 68 20 73 68 61 72 65 64 0a 2a  or each shared.*
11c0: 2a 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20  * memory region 
11d0: 6f 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74  opened by client
11e0: 73 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e 74  s. If two client
11f0: 73 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65 20  s open the same 
1200: 66 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20 61  file,.** there a
1210: 72 65 20 74 77 6f 20 54 65 73 74 76 66 73 46 69  re two TestvfsFi
1220: 6c 65 20 73 74 72 75 63 74 75 72 65 73 20 62 75  le structures bu
1230: 74 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74 76  t only one Testv
1240: 66 73 42 75 66 66 65 72 20 73 74 72 75 63 74 75  fsBuffer structu
1250: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65  re..*/.struct Te
1260: 73 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20 20  stvfsBuffer {.  
1270: 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20 20  char *zFile;    
1280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1290: 2f 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66 69  /* Associated fi
12a0: 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74  le name */.  int
12b0: 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20   pgsz;          
12c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12d0: 50 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 75  Page size */.  u
12e0: 38 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46 53  8 *aPage[TESTVFS
12f0: 5f 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20 2f  _MAX_PAGES];   /
1300: 2a 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c 6c  * Array of ckall
1310: 6f 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20 20  oc'd pages */.  
1320: 54 65 73 74 76 66 73 46 64 20 2a 70 46 69 6c 65  TestvfsFd *pFile
1330: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1340: 2f 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e 20  /* List of open 
1350: 68 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65 73  handles */.  Tes
1360: 74 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65 78  tvfsBuffer *pNex
1370: 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t;           /* 
1380: 4e 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c  Next in linked l
1390: 69 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66 65  ist of all buffe
13a0: 72 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69  rs */.};...#defi
13b0: 6e 65 20 50 41 52 45 4e 54 56 46 53 28 78 29 20  ne PARENTVFS(x) 
13c0: 28 28 28 54 65 73 74 76 66 73 20 2a 29 28 28 78  (((Testvfs *)((x
13d0: 29 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e 70  )->pAppData))->p
13e0: 50 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e 65  Parent)..#define
13f0: 20 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52 47   TESTVFS_MAX_ARG
1400: 53 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  S 12.../*.** Met
1410: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
1420: 20 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c 65   for TestvfsFile
1430: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1440: 74 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65  tvfsClose(sqlite
1450: 33 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63  3_file*);.static
1460: 20 69 6e 74 20 74 76 66 73 52 65 61 64 28 73 71   int tvfsRead(sq
1470: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f 69  lite3_file*, voi
1480: 64 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73 71  d*, int iAmt, sq
1490: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
14a0: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
14b0: 76 66 73 57 72 69 74 65 28 73 71 6c 69 74 65 33  vfsWrite(sqlite3
14c0: 5f 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f 69  _file*,const voi
14d0: 64 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c  d*,int iAmt, sql
14e0: 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74  ite3_int64 iOfst
14f0: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1500: 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74  fsTruncate(sqlit
1510: 65 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74 65  e3_file*, sqlite
1520: 33 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a 73  3_int64 size);.s
1530: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 79  tatic int tvfsSy
1540: 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  nc(sqlite3_file*
1550: 2c 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74  , int flags);.st
1560: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 69 6c  atic int tvfsFil
1570: 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69  eSize(sqlite3_fi
1580: 6c 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  le*, sqlite3_int
1590: 36 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61 74  64 *pSize);.stat
15a0: 69 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28  ic int tvfsLock(
15b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69  sqlite3_file*, i
15c0: 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  nt);.static int 
15d0: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
15e0: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a  e3_file*, int);.
15f0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43  static int tvfsC
1600: 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b  heckReservedLock
1610: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
1620: 69 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69  int *);.static i
1630: 6e 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72  nt tvfsFileContr
1640: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  ol(sqlite3_file*
1650: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
1660: 70 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69 6e  pArg);.static in
1670: 74 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65  t tvfsSectorSize
1680: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b  (sqlite3_file*);
1690: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
16a0: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
16b0: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
16c0: 6c 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  le*);../*.** Met
16d0: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
16e0: 20 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a 2a   for tvfs_vfs..*
16f0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
1700: 73 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66  sOpen(sqlite3_vf
1710: 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  s*, const char *
1720: 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  , sqlite3_file*,
1730: 20 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73   int , int *);.s
1740: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65  tatic int tvfsDe
1750: 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73  lete(sqlite3_vfs
1760: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  *, const char *z
1770: 4e 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69  Name, int syncDi
1780: 72 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  r);.static int t
1790: 76 66 73 41 63 63 65 73 73 28 73 71 6c 69 74 65  vfsAccess(sqlite
17a0: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
17b0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66  ar *zName, int f
17c0: 6c 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  lags, int *);.st
17d0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c  atic int tvfsFul
17e0: 6c 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65  lPathname(sqlite
17f0: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
1800: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20  ar *zName, int, 
1810: 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69 66  char *zOut);.#if
1820: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
1830: 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a  _LOAD_EXTENSION.
1840: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66  static void *tvf
1850: 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  sDlOpen(sqlite3_
1860: 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72  vfs*, const char
1870: 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73 74   *zFilename);.st
1880: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
1890: 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66  Error(sqlite3_vf
18a0: 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  s*, int nByte, c
18b0: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a 73  har *zErrMsg);.s
18c0: 74 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66  tatic void (*tvf
18d0: 73 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76  sDlSym(sqlite3_v
18e0: 66 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73 74  fs*,void*, const
18f0: 20 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29 29   char *zSymbol))
1900: 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76  (void);.static v
1910: 6f 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28  oid tvfsDlClose(
1920: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f  sqlite3_vfs*, vo
1930: 69 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20  id*);.#endif /* 
1940: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
1950: 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73 74  _EXTENSION */.st
1960: 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e  atic int tvfsRan
1970: 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f  domness(sqlite3_
1980: 76 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c  vfs*, int nByte,
1990: 20 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74   char *zOut);.st
19a0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65  atic int tvfsSle
19b0: 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  ep(sqlite3_vfs*,
19c0: 20 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e 64   int microsecond
19d0: 73 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  s);.static int t
19e0: 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73  vfsCurrentTime(s
19f0: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f 75  qlite3_vfs*, dou
1a00: 62 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69  ble*);..static i
1a10: 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73  nt tvfsShmOpen(s
1a20: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73  qlite3_file*);.s
1a30: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68  tatic int tvfsSh
1a40: 6d 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  mLock(sqlite3_fi
1a50: 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 2c 20  le*, int , int, 
1a60: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
1a70: 20 74 76 66 73 53 68 6d 4d 61 70 28 73 71 6c 69   tvfsShmMap(sqli
1a80: 74 65 33 5f 66 69 6c 65 2a 2c 69 6e 74 2c 69 6e  te3_file*,int,in
1a90: 74 2c 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c 61  t,int, void vola
1aa0: 74 69 6c 65 20 2a 2a 29 3b 0a 73 74 61 74 69 63  tile **);.static
1ab0: 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72   void tvfsShmBar
1ac0: 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c  rier(sqlite3_fil
1ad0: 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  e*);.static int 
1ae0: 74 76 66 73 53 68 6d 55 6e 6d 61 70 28 73 71 6c  tvfsShmUnmap(sql
1af0: 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29  ite3_file*, int)
1b00: 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  ;..static sqlite
1b10: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 74 76 66  3_io_methods tvf
1b20: 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 3d 20 7b  s_io_methods = {
1b30: 0a 20 20 32 2c 20 20 20 20 20 20 20 20 20 20 20  .  2,           
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b50: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
1b60: 2f 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20 20  /.  tvfsClose,  
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b80: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a 2f      /* xClose */
1b90: 0a 20 20 74 76 66 73 52 65 61 64 2c 20 20 20 20  .  tvfsRead,    
1ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb0: 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a 20     /* xRead */. 
1bc0: 20 74 76 66 73 57 72 69 74 65 2c 20 20 20 20 20   tvfsWrite,     
1bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1be0: 20 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20 20   /* xWrite */.  
1bf0: 74 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20 20  tvfsTruncate,   
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a  /* xTruncate */.
1c20: 20 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20 20    tvfsSync,     
1c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c40: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
1c50: 74 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20 20  tvfsFileSize,   
1c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c70: 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f 0a  /* xFileSize */.
1c80: 20 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20 20    tvfsLock,     
1c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ca0: 20 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20    /* xLock */.  
1cb0: 74 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20 20  tvfsUnlock,     
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cd0: 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20  /* xUnlock */.  
1ce0: 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76 65  tvfsCheckReserve
1cf0: 64 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20  dLock,          
1d00: 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  /* xCheckReserve
1d10: 64 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73 46  dLock */.  tvfsF
1d20: 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20 20  ileControl,     
1d30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
1d40: 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20  ileControl */.  
1d50: 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c 20  tvfsSectorSize, 
1d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d70: 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20 2a  /* xSectorSize *
1d80: 2f 0a 20 20 74 76 66 73 44 65 76 69 63 65 43 68  /.  tvfsDeviceCh
1d90: 61 72 61 63 74 65 72 69 73 74 69 63 73 2c 20 20  aracteristics,  
1da0: 20 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43 68      /* xDeviceCh
1db0: 61 72 61 63 74 65 72 69 73 74 69 63 73 20 2a 2f  aracteristics */
1dc0: 0a 20 20 74 76 66 73 53 68 6d 4d 61 70 2c 20 20  .  tvfsShmMap,  
1dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1de0: 20 20 20 2f 2a 20 78 53 68 6d 4d 61 70 20 2a 2f     /* xShmMap */
1df0: 0a 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c 20  .  tvfsShmLock, 
1e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e10: 20 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a     /* xShmLock *
1e20: 2f 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72 69  /.  tvfsShmBarri
1e30: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
1e40: 20 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69      /* xShmBarri
1e50: 65 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 55  er */.  tvfsShmU
1e60: 6e 6d 61 70 20 20 20 20 20 20 20 20 20 20 20 20  nmap            
1e70: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55          /* xShmU
1e80: 6e 6d 61 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74  nmap */.};..stat
1e90: 69 63 20 69 6e 74 20 74 76 66 73 52 65 73 75 6c  ic int tvfsResul
1ea0: 74 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a 70  tCode(Testvfs *p
1eb0: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 73  , int *pRc){.  s
1ec0: 74 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b 0a  truct errcode {.
1ed0: 20 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a 20      int eCode;. 
1ee0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
1ef0: 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65 5b  Code;.  } aCode[
1f00: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c 49  ] = {.    { SQLI
1f10: 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c 49  TE_OK,     "SQLI
1f20: 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20 20  TE_OK"     },.  
1f30: 20 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f 52    { SQLITE_ERROR
1f40: 2c 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52  ,  "SQLITE_ERROR
1f50: 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  "  },.    { SQLI
1f60: 54 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c 49  TE_IOERR,  "SQLI
1f70: 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20 20  TE_IOERR"  },.  
1f80: 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45    { SQLITE_LOCKE
1f90: 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b 45  D, "SQLITE_LOCKE
1fa0: 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  D" },.    { SQLI
1fb0: 54 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c 49  TE_BUSY,   "SQLI
1fc0: 54 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20 20  TE_BUSY"   },.  
1fd0: 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  };..  const char
1fe0: 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20   *z;.  int i;.. 
1ff0: 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69   z = Tcl_GetStri
2000: 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  ngResult(p->inte
2010: 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  rp);.  for(i=0; 
2020: 69 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f 64  i<ArraySize(aCod
2030: 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  e); i++){.    if
2040: 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 61  ( 0==strcmp(z, a
2050: 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20 29  Code[i].zCode) )
2060: 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 61  {.      *pRc = a
2070: 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a 20  Code[i].eCode;. 
2080: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
2090: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
20a0: 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 0;.}..static 
20b0: 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 61  int tvfsInjectFa
20c0: 75 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e 6a  ult(TestFaultInj
20d0: 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ect *p){.  int r
20e0: 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d  et = 0;.  if( p-
20f0: 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20 70  >eFault ){.    p
2100: 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69 66  ->iCnt--;.    if
2110: 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c 20  ( p->iCnt==0 || 
2120: 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70 2d  (p->iCnt<0 && p-
2130: 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f 49  >eFault==FAULT_I
2140: 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e 54  NJECT_PERSISTENT
2150: 20 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20   ) ){.      ret 
2160: 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46  = 1;.      p->nF
2170: 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  ail++;.    }.  }
2180: 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d  .  return ret;.}
2190: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  ...static int tv
21a0: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54 65  fsInjectIoerr(Te
21b0: 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74  stvfs *p){.  ret
21c0: 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61  urn tvfsInjectFa
21d0: 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65 72  ult(&p->ioerr_er
21e0: 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  r);.}..static in
21f0: 74 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c  t tvfsInjectFull
2200: 65 72 72 28 54 65 73 74 76 66 73 20 2a 70 29 7b  err(Testvfs *p){
2210: 0a 20 20 72 65 74 75 72 6e 20 74 76 66 73 49 6e  .  return tvfsIn
2220: 6a 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66 75  jectFault(&p->fu
2230: 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74 69  ll_err);.}.stati
2240: 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74  c int tvfsInject
2250: 43 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73 74  Cantopenerr(Test
2260: 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  vfs *p){.  retur
2270: 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75 6c  n tvfsInjectFaul
2280: 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65  t(&p->cantopen_e
2290: 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20  rr);.}...static 
22a0: 76 6f 69 64 20 74 76 66 73 45 78 65 63 54 63 6c  void tvfsExecTcl
22b0: 28 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c 20  (.  Testvfs *p, 
22c0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
22d0: 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f 62  Method,.  Tcl_Ob
22e0: 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f 4f  j *arg1,.  Tcl_O
22f0: 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c 5f  bj *arg2,.  Tcl_
2300: 4f 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20 69  Obj *arg3.){.  i
2310: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
2320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2330: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72  * Return code fr
2340: 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28 29  om Tcl_EvalObj()
2350: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 3b 20   */.  int nArg; 
2360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2370: 20 20 20 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74        /* Element
2380: 73 20 69 6e 20 65 76 61 6c 27 64 20 6c 69 73 74  s in eval'd list
2390: 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70   */.  int nScrip
23a0: 74 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 20  t;.  Tcl_Obj ** 
23b0: 61 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  ap;..  assert( p
23c0: 2d 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a 20 20  ->pScript );..  
23d0: 69 66 28 20 21 70 2d 3e 61 70 53 63 72 69 70 74  if( !p->apScript
23e0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   ){.    int nByt
23f0: 65 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  e;.    int i;.  
2400: 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63    if( TCL_OK!=Tc
2410: 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d  l_ListObjGetElem
2420: 65 6e 74 73 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ents(p->interp, 
2430: 70 2d 3e 70 53 63 72 69 70 74 2c 20 26 6e 53 63  p->pScript, &nSc
2440: 72 69 70 74 2c 20 26 61 70 29 20 29 7b 0a 20 20  ript, &ap) ){.  
2450: 20 20 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75      Tcl_Backgrou
2460: 6e 64 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72  ndError(p->inter
2470: 70 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 52 65  p);.      Tcl_Re
2480: 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  setResult(p->int
2490: 65 72 70 29 3b 0a 20 20 20 20 20 20 72 65 74 75  erp);.      retu
24a0: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  rn;.    }.    p-
24b0: 3e 6e 53 63 72 69 70 74 20 3d 20 6e 53 63 72 69  >nScript = nScri
24c0: 70 74 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20  pt;.    nByte = 
24d0: 28 6e 53 63 72 69 70 74 2b 54 45 53 54 56 46 53  (nScript+TESTVFS
24e0: 5f 4d 41 58 5f 41 52 47 53 29 2a 73 69 7a 65 6f  _MAX_ARGS)*sizeo
24f0: 66 28 54 63 6c 5f 4f 62 6a 20 2a 29 3b 0a 20 20  f(Tcl_Obj *);.  
2500: 20 20 70 2d 3e 61 70 53 63 72 69 70 74 20 3d 20    p->apScript = 
2510: 28 54 63 6c 5f 4f 62 6a 20 2a 2a 29 63 6b 61 6c  (Tcl_Obj **)ckal
2520: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
2530: 6d 65 6d 73 65 74 28 70 2d 3e 61 70 53 63 72 69  memset(p->apScri
2540: 70 74 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  pt, 0, nByte);. 
2550: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53     for(i=0; i<nS
2560: 63 72 69 70 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  cript; i++){.   
2570: 20 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 69     p->apScript[i
2580: 5d 20 3d 20 61 70 5b 69 5d 3b 0a 20 20 20 20 7d  ] = ap[i];.    }
2590: 0a 20 20 7d 0a 0a 20 20 70 2d 3e 61 70 53 63 72  .  }..  p->apScr
25a0: 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 5d 20  ipt[p->nScript] 
25b0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
25c0: 62 6a 28 7a 4d 65 74 68 6f 64 2c 20 2d 31 29 3b  bj(zMethod, -1);
25d0: 0a 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 70  .  p->apScript[p
25e0: 2d 3e 6e 53 63 72 69 70 74 2b 31 5d 20 3d 20 61  ->nScript+1] = a
25f0: 72 67 31 3b 0a 20 20 70 2d 3e 61 70 53 63 72 69  rg1;.  p->apScri
2600: 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 2b 32 5d  pt[p->nScript+2]
2610: 20 3d 20 61 72 67 32 3b 0a 20 20 70 2d 3e 61 70   = arg2;.  p->ap
2620: 53 63 72 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70  Script[p->nScrip
2630: 74 2b 33 5d 20 3d 20 61 72 67 33 3b 0a 0a 20 20  t+3] = arg3;..  
2640: 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53 63 72  for(nArg=p->nScr
2650: 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69 70 74  ipt; p->apScript
2660: 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b 29 7b  [nArg]; nArg++){
2670: 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  .    Tcl_IncrRef
2680: 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72 69 70  Count(p->apScrip
2690: 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 7d 0a 0a 20  t[nArg]);.  }.. 
26a0: 20 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62   rc = Tcl_EvalOb
26b0: 6a 76 28 70 2d 3e 69 6e 74 65 72 70 2c 20 6e 41  jv(p->interp, nA
26c0: 72 67 2c 20 70 2d 3e 61 70 53 63 72 69 70 74 2c  rg, p->apScript,
26d0: 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c   TCL_EVAL_GLOBAL
26e0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c  );.  if( rc!=TCL
26f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42  _OK ){.    Tcl_B
2700: 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70  ackgroundError(p
2710: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54  ->interp);.    T
2720: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70  cl_ResetResult(p
2730: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 0a  ->interp);.  }..
2740: 20 20 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53    for(nArg=p->nS
2750: 63 72 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69  cript; p->apScri
2760: 70 74 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b  pt[nArg]; nArg++
2770: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2780: 65 66 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72  efCount(p->apScr
2790: 69 70 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 20 20  ipt[nArg]);.    
27a0: 70 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67  p->apScript[nArg
27b0: 5d 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f  ] = 0;.  }.}.../
27c0: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 74 76  *.** Close an tv
27d0: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
27e0: 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f 73 65  ic int tvfsClose
27f0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
2800: 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b  File){.  int rc;
2810: 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a  .  TestvfsFile *
2820: 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73  pTestfile = (Tes
2830: 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65  tvfsFile *)pFile
2840: 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70  ;.  TestvfsFd *p
2850: 46 64 20 3d 20 70 54 65 73 74 66 69 6c 65 2d 3e  Fd = pTestfile->
2860: 70 46 64 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  pFd;.  Testvfs *
2870: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
2880: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
2890: 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  ta;..  if( p->pS
28a0: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
28b0: 26 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d  &TESTVFS_CLOSE_M
28c0: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
28d0: 78 65 63 54 63 6c 28 70 2c 20 22 78 43 6c 6f 73  xecTcl(p, "xClos
28e0: 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  e", .        Tcl
28f0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
2900: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
2910: 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20  ), pFd->pShmId, 
2920: 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20  0.    );.  }..  
2930: 69 66 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20  if( pFd->pShmId 
2940: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2950: 65 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70 53 68  efCount(pFd->pSh
2960: 6d 49 64 29 3b 0a 20 20 20 20 70 46 64 2d 3e 70  mId);.    pFd->p
2970: 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  ShmId = 0;.  }. 
2980: 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d 65 74   if( pFile->pMet
2990: 68 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b 66 72  hods ){.    ckfr
29a0: 65 65 28 28 63 68 61 72 20 2a 29 70 46 69 6c 65  ee((char *)pFile
29b0: 2d 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20 20 7d  ->pMethods);.  }
29c0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
29d0: 73 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52 65 61  sClose(pFd->pRea
29e0: 6c 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68  l);.  ckfree((ch
29f0: 61 72 20 2a 29 70 46 64 29 3b 0a 20 20 70 54 65  ar *)pFd);.  pTe
2a00: 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 30 3b  stfile->pFd = 0;
2a10: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2a20: 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61 74 61  ./*.** Read data
2a30: 20 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d 66 69   from an tvfs-fi
2a40: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2a50: 74 20 74 76 66 73 52 65 61 64 28 0a 20 20 73 71  t tvfsRead(.  sq
2a60: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
2a70: 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42 75 66  e, .  void *zBuf
2a80: 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 0a  , .  int iAmt, .
2a90: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
2aa0: 4f 66 73 74 0a 29 7b 0a 20 20 54 65 73 74 76 66  Ofst.){.  Testvf
2ab0: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
2ac0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
2ad0: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61  urn sqlite3OsRea
2ae0: 64 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66  d(p->pReal, zBuf
2af0: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
2b00: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64  }../*.** Write d
2b10: 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73 2d 66  ata to an tvfs-f
2b20: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
2b30: 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a 20 20  nt tvfsWrite(.  
2b40: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2b50: 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 76 6f  ile, .  const vo
2b60: 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74  id *zBuf, .  int
2b70: 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65   iAmt, .  sqlite
2b80: 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a  _int64 iOfst.){.
2b90: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2ba0: 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46  E_OK;.  TestvfsF
2bb0: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
2bc0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
2bd0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
2be0: 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e  fs *)pFd->pVfs->
2bf0: 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28  pAppData;..  if(
2c00: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
2c10: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 57  ->mask&TESTVFS_W
2c20: 52 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  RITE_MASK ){.   
2c30: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
2c40: 22 78 57 72 69 74 65 22 2c 20 0a 20 20 20 20 20  "xWrite", .     
2c50: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
2c60: 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61  Obj(pFd->zFilena
2c70: 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53  me, -1), pFd->pS
2c80: 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20  hmId, 0.    );. 
2c90: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
2ca0: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  e(p, &rc);.  }..
2cb0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2cc0: 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63  _OK && tvfsInjec
2cd0: 74 46 75 6c 6c 65 72 72 28 70 29 20 29 7b 0a 20  tFullerr(p) ){. 
2ce0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46     rc = SQLITE_F
2cf0: 55 4c 4c 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  ULL;.  }.  if( r
2d00: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2d10: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
2d20: 57 52 49 54 45 5f 4d 41 53 4b 20 26 26 20 74 76  WRITE_MASK && tv
2d30: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29  fsInjectIoerr(p)
2d40: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
2d50: 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 20  ITE_IOERR;.  }. 
2d60: 20 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49   .  if( rc==SQLI
2d70: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
2d80: 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
2d90: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a 42 75  (pFd->pReal, zBu
2da0: 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b  f, iAmt, iOfst);
2db0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
2dc0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63  ;.}../*.** Trunc
2dd0: 61 74 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ate an tvfs-file
2de0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2df0: 74 76 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c  tvfsTruncate(sql
2e00: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
2e10: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 73  , sqlite_int64 s
2e20: 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ize){.  int rc =
2e30: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
2e40: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
2e50: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
2e60: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
2e70: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
2e80: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
2e90: 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70  .  if( p->pScrip
2ea0: 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  t && p->mask&TES
2eb0: 54 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41  TVFS_TRUNCATE_MA
2ec0: 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78  SK ){.    tvfsEx
2ed0: 65 63 54 63 6c 28 70 2c 20 22 78 54 72 75 6e 63  ecTcl(p, "xTrunc
2ee0: 61 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ate", .        T
2ef0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2f00: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
2f10: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
2f20: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74  , 0.    );.    t
2f30: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
2f40: 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 0a 20 20   &rc);.  }.  .  
2f50: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2f60: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
2f70: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
2f80: 70 46 64 2d 3e 70 52 65 61 6c 2c 20 73 69 7a 65  pFd->pReal, size
2f90: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
2fa0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e  rc;.}../*.** Syn
2fb0: 63 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  c an tvfs-file..
2fc0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2fd0: 66 73 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 66  fsSync(sqlite3_f
2fe0: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
2ff0: 66 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20 72 63  flags){.  int rc
3000: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3010: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
3020: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
3030: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
3040: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
3050: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
3060: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
3070: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
3080: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
3090: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46   ){.    char *zF
30a0: 6c 61 67 73 3b 0a 0a 20 20 20 20 73 77 69 74 63  lags;..    switc
30b0: 68 28 20 66 6c 61 67 73 20 29 7b 0a 20 20 20 20  h( flags ){.    
30c0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59    case SQLITE_SY
30d0: 4e 43 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20 20 20  NC_NORMAL:.     
30e0: 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72     zFlags = "nor
30f0: 6d 61 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72  mal";.        br
3100: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
3110: 53 51 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c  SQLITE_SYNC_FULL
3120: 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73  :.        zFlags
3130: 20 3d 20 22 66 75 6c 6c 22 3b 0a 20 20 20 20 20   = "full";.     
3140: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3150: 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43  case SQLITE_SYNC
3160: 5f 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53  _NORMAL|SQLITE_S
3170: 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20  YNC_DATAONLY:.  
3180: 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22        zFlags = "
3190: 6e 6f 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c 79 22  normal|dataonly"
31a0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
31b0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
31c0: 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53 51 4c  TE_SYNC_FULL|SQL
31d0: 49 54 45 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c  ITE_SYNC_DATAONL
31e0: 59 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67  Y:.        zFlag
31f0: 73 20 3d 20 22 66 75 6c 6c 7c 64 61 74 61 6f 6e  s = "full|dataon
3200: 6c 79 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65  ly";.        bre
3210: 61 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c  ak;.      defaul
3220: 74 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  t:.        asser
3230: 74 28 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  t(0);.    }..   
3240: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
3250: 22 78 53 79 6e 63 22 2c 20 0a 20 20 20 20 20 20  "xSync", .      
3260: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
3270: 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  bj(pFd->zFilenam
3280: 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68  e, -1), pFd->pSh
3290: 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c  mId,.        Tcl
32a0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 46  _NewStringObj(zF
32b0: 6c 61 67 73 2c 20 2d 31 29 0a 20 20 20 20 29 3b  lags, -1).    );
32c0: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
32d0: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
32e0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
32f0: 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a  TE_OK && tvfsInj
3300: 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 20  ectFullerr(p) ) 
3310: 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c 4c  rc = SQLITE_FULL
3320: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
3330: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
3340: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
3350: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c 61  (pFd->pReal, fla
3360: 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  gs);.  }..  retu
3370: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
3380: 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 72 65  Return the curre
3390: 6e 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f 66 20  nt file-size of 
33a0: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
33b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
33c0: 46 69 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33  FileSize(sqlite3
33d0: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71  _file *pFile, sq
33e0: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53 69 7a  lite_int64 *pSiz
33f0: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20  e){.  TestvfsFd 
3400: 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64 28 70  *p = tvfsGetFd(p
3410: 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e 20  File);.  return 
3420: 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a  sqlite3OsFileSiz
3430: 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69 7a  e(p->pReal, pSiz
3440: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63  e);.}../*.** Loc
3450: 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  k an tvfs-file..
3460: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3470: 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  fsLock(sqlite3_f
3480: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
3490: 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76 66  eLock){.  Testvf
34a0: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
34b0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
34c0: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63  urn sqlite3OsLoc
34d0: 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63  k(p->pReal, eLoc
34e0: 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e 6c  k);.}../*.** Unl
34f0: 6f 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ock an tvfs-file
3500: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3510: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
3520: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
3530: 69 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65  int eLock){.  Te
3540: 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66  stvfsFd *p = tvf
3550: 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20  sGetFd(pFile);. 
3560: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
3570: 73 55 6e 6c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  sUnlock(p->pReal
3580: 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a  , eLock);.}../*.
3590: 2a 2a 20 43 68 65 63 6b 20 69 66 20 61 6e 6f 74  ** Check if anot
35a0: 68 65 72 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  her file-handle 
35b0: 68 6f 6c 64 73 20 61 20 52 45 53 45 52 56 45 44  holds a RESERVED
35c0: 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 74 76 66 73   lock on an tvfs
35d0: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
35e0: 20 69 6e 74 20 74 76 66 73 43 68 65 63 6b 52 65   int tvfsCheckRe
35f0: 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74  servedLock(sqlit
3600: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
3610: 69 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20  int *pResOut){. 
3620: 20 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20   TestvfsFd *p = 
3630: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
3640: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
3650: 65 33 4f 73 43 68 65 63 6b 52 65 73 65 72 76 65  e3OsCheckReserve
3660: 64 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20  dLock(p->pReal, 
3670: 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a  pResOut);.}../*.
3680: 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f 6c 20  ** File control 
3690: 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75 73 74  method. For cust
36a0: 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e  om operations on
36b0: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
36c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
36d0: 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c  sFileControl(sql
36e0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
36f0: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
3700: 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76 66 73  pArg){.  Testvfs
3710: 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46  Fd *p = tvfsGetF
3720: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
3730: 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65  rn sqlite3OsFile
3740: 43 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65 61 6c  Control(p->pReal
3750: 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d 0a 0a  , op, pArg);.}..
3760: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3770: 20 73 65 63 74 6f 72 2d 73 69 7a 65 20 69 6e 20   sector-size in 
3780: 62 79 74 65 73 20 66 6f 72 20 61 6e 20 74 76 66  bytes for an tvf
3790: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
37a0: 63 20 69 6e 74 20 74 76 66 73 53 65 63 74 6f 72  c int tvfsSector
37b0: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
37c0: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73  e *pFile){.  Tes
37d0: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
37e0: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
37f0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
3800: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
3810: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
3820: 20 69 66 28 20 70 2d 3e 69 53 65 63 74 6f 72 73   if( p->iSectors
3830: 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65  ize>=0 ){.    re
3840: 74 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f 72 73  turn p->iSectors
3850: 69 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ize;.  }.  retur
3860: 6e 20 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f  n sqlite3OsSecto
3870: 72 53 69 7a 65 28 70 46 64 2d 3e 70 52 65 61 6c  rSize(pFd->pReal
3880: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
3890: 72 6e 20 74 68 65 20 64 65 76 69 63 65 20 63 68  rn the device ch
38a0: 61 72 61 63 74 65 72 69 73 74 69 63 20 66 6c 61  aracteristic fla
38b0: 67 73 20 73 75 70 70 6f 72 74 65 64 20 62 79 20  gs supported by 
38c0: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
38d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
38e0: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
38f0: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
3900: 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65  le *pFile){.  Te
3910: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
3920: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
3930: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
3940: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
3950: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
3960: 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61    if( p->iDevcha
3970: 72 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  r>=0 ){.    retu
3980: 72 6e 20 70 2d 3e 69 44 65 76 63 68 61 72 3b 0a  rn p->iDevchar;.
3990: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c    }.  return sql
39a0: 69 74 65 33 4f 73 44 65 76 69 63 65 43 68 61 72  ite3OsDeviceChar
39b0: 61 63 74 65 72 69 73 74 69 63 73 28 70 46 64 2d  acteristics(pFd-
39c0: 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  >pReal);.}../*.*
39d0: 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73 20 66  * Open an tvfs f
39e0: 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73  ile handle..*/.s
39f0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 4f 70  tatic int tvfsOp
3a00: 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  en(.  sqlite3_vf
3a10: 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74  s *pVfs,.  const
3a20: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20   char *zName,.  
3a30: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
3a40: 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73  ile,.  int flags
3a50: 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61  ,.  int *pOutFla
3a60: 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  gs.){.  int rc;.
3a70: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
3a80: 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73 74  Testfile = (Test
3a90: 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  vfsFile *)pFile;
3aa0: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
3ab0: 64 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 49  d;.  Tcl_Obj *pI
3ac0: 64 20 3d 20 30 3b 0a 20 20 54 65 73 74 76 66 73  d = 0;.  Testvfs
3ad0: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
3ae0: 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  )pVfs->pAppData;
3af0: 0a 0a 20 20 70 46 64 20 3d 20 28 54 65 73 74 76  ..  pFd = (Testv
3b00: 66 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63 28 73  fsFd *)ckalloc(s
3b10: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64 29  izeof(TestvfsFd)
3b20: 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56 66   + PARENTVFS(pVf
3b30: 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20  s)->szOsFile);. 
3b40: 20 6d 65 6d 73 65 74 28 70 46 64 2c 20 30 2c 20   memset(pFd, 0, 
3b50: 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64  sizeof(TestvfsFd
3b60: 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56  ) + PARENTVFS(pV
3b70: 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a  fs)->szOsFile);.
3b80: 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30 3b    pFd->pShm = 0;
3b90: 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d  .  pFd->pShmId =
3ba0: 20 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69 6c 65   0;.  pFd->zFile
3bb0: 6e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20  name = zName;.  
3bc0: 70 46 64 2d 3e 70 56 66 73 20 3d 20 70 56 66 73  pFd->pVfs = pVfs
3bd0: 3b 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c 20 3d  ;.  pFd->pReal =
3be0: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a   (sqlite3_file *
3bf0: 29 26 70 46 64 5b 31 5d 3b 0a 20 20 6d 65 6d 73  )&pFd[1];.  mems
3c00: 65 74 28 70 54 65 73 74 66 69 6c 65 2c 20 30 2c  et(pTestfile, 0,
3c10: 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46   sizeof(TestvfsF
3c20: 69 6c 65 29 29 3b 0a 20 20 70 54 65 73 74 66 69  ile));.  pTestfi
3c30: 6c 65 2d 3e 70 46 64 20 3d 20 70 46 64 3b 0a 0a  le->pFd = pFd;..
3c40: 20 20 2f 2a 20 45 76 61 6c 75 61 74 65 20 74 68    /* Evaluate th
3c50: 65 20 54 63 6c 20 73 63 72 69 70 74 3a 20 0a 20  e Tcl script: . 
3c60: 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43 52 49 50   **.  **   SCRIP
3c70: 54 20 78 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45  T xOpen FILENAME
3c80: 20 4b 45 59 2d 56 41 4c 55 45 2d 41 52 47 53 0a   KEY-VALUE-ARGS.
3c90: 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 74 68 65    **.  ** If the
3ca0: 20 73 63 72 69 70 74 20 72 65 74 75 72 6e 73 20   script returns 
3cb0: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
3cc0: 63 6f 64 65 20 6f 74 68 65 72 20 74 68 61 6e 20  code other than 
3cd0: 53 51 4c 49 54 45 5f 4f 4b 2c 20 61 6e 0a 20 20  SQLITE_OK, an.  
3ce0: 2a 2a 20 65 72 72 6f 72 20 69 73 20 72 65 74 75  ** error is retu
3cf0: 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c 6c  rned to the call
3d00: 65 72 2e 20 49 66 20 69 74 20 72 65 74 75 72 6e  er. If it return
3d10: 73 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 74 68 65  s SQLITE_OK, the
3d20: 20 6e 65 77 0a 20 20 2a 2a 20 63 6f 6e 6e 65 63   new.  ** connec
3d30: 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 61  tion is named "a
3d40: 6e 6f 6e 22 2e 20 4f 74 68 65 72 77 69 73 65 2c  non". Otherwise,
3d50: 20 74 68 65 20 76 61 6c 75 65 20 72 65 74 75 72   the value retur
3d60: 6e 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a 20  ned by the.  ** 
3d70: 73 63 72 69 70 74 20 69 73 20 75 73 65 64 20 61  script is used a
3d80: 73 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  s the connection
3d90: 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 54 63   name..  */.  Tc
3da0: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d  l_ResetResult(p-
3db0: 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66 28 20  >interp);.  if( 
3dc0: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
3dd0: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 4f 50  >mask&TESTVFS_OP
3de0: 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54  EN_MASK ){.    T
3df0: 63 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54  cl_Obj *pArg = T
3e00: 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20  cl_NewObj();.   
3e10: 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e   Tcl_IncrRefCoun
3e20: 74 28 70 41 72 67 29 3b 0a 20 20 20 20 69 66 28  t(pArg);.    if(
3e30: 20 66 6c 61 67 73 26 53 51 4c 49 54 45 5f 4f 50   flags&SQLITE_OP
3e40: 45 4e 5f 4d 41 49 4e 5f 44 42 20 29 7b 0a 20 20  EN_MAIN_DB ){.  
3e50: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
3e60: 7a 20 3d 20 26 7a 4e 61 6d 65 5b 73 74 72 6c 65  z = &zName[strle
3e70: 6e 28 7a 4e 61 6d 65 29 2b 31 5d 3b 0a 20 20 20  n(zName)+1];.   
3e80: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a     while( *z ){.
3e90: 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74          Tcl_List
3ea0: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
3eb0: 28 30 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65  (0, pArg, Tcl_Ne
3ec0: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20 2d 31  wStringObj(z, -1
3ed0: 29 29 3b 0a 20 20 20 20 20 20 20 20 7a 20 2b 3d  ));.        z +=
3ee0: 20 73 74 72 6c 65 6e 28 7a 29 20 2b 20 31 3b 0a   strlen(z) + 1;.
3ef0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74          Tcl_List
3f00: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
3f10: 28 30 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65  (0, pArg, Tcl_Ne
3f20: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20 2d 31  wStringObj(z, -1
3f30: 29 29 3b 0a 20 20 20 20 20 20 20 20 7a 20 2b 3d  ));.        z +=
3f40: 20 73 74 72 6c 65 6e 28 7a 29 20 2b 20 31 3b 0a   strlen(z) + 1;.
3f50: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
3f60: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
3f70: 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c 5f 4e 65   "xOpen", Tcl_Ne
3f80: 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e  wStringObj(pFd->
3f90: 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20  zFilename, -1), 
3fa0: 70 41 72 67 2c 20 30 29 3b 0a 20 20 20 20 54 63  pArg, 0);.    Tc
3fb0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
3fc0: 41 72 67 29 3b 0a 20 20 20 20 69 66 28 20 74 76  Arg);.    if( tv
3fd0: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
3fe0: 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20 69 66  &rc) ){.      if
3ff0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
4000: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
4010: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 49   }else{.      pI
4020: 64 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  d = Tcl_GetObjRe
4030: 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b  sult(p->interp);
4040: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
4050: 28 20 28 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56  ( (p->mask&TESTV
4060: 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 29 20 26 26  FS_OPEN_MASK) &&
4070: 20 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72    tvfsInjectIoer
4080: 72 28 70 29 20 29 20 72 65 74 75 72 6e 20 53 51  r(p) ) return SQ
4090: 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 69 66  LITE_IOERR;.  if
40a0: 28 20 74 76 66 73 49 6e 6a 65 63 74 43 61 6e 74  ( tvfsInjectCant
40b0: 6f 70 65 6e 65 72 72 28 70 29 20 29 20 72 65 74  openerr(p) ) ret
40c0: 75 72 6e 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f  urn SQLITE_CANTO
40d0: 50 45 4e 3b 0a 20 20 69 66 28 20 74 76 66 73 49  PEN;.  if( tvfsI
40e0: 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20  njectFullerr(p) 
40f0: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
4100: 46 55 4c 4c 3b 0a 0a 20 20 69 66 28 20 21 70 49  FULL;..  if( !pI
4110: 64 20 29 7b 0a 20 20 20 20 70 49 64 20 3d 20 54  d ){.    pId = T
4120: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
4130: 22 61 6e 6f 6e 22 2c 20 2d 31 29 3b 0a 20 20 7d  "anon", -1);.  }
4140: 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  .  Tcl_IncrRefCo
4150: 75 6e 74 28 70 49 64 29 3b 0a 20 20 70 46 64 2d  unt(pId);.  pFd-
4160: 3e 70 53 68 6d 49 64 20 3d 20 70 49 64 3b 0a 20  >pShmId = pId;. 
4170: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
4180: 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 0a 20 20  (p->interp);..  
4190: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70  rc = sqlite3OsOp
41a0: 65 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56 66  en(PARENTVFS(pVf
41b0: 73 29 2c 20 7a 4e 61 6d 65 2c 20 70 46 64 2d 3e  s), zName, pFd->
41c0: 70 52 65 61 6c 2c 20 66 6c 61 67 73 2c 20 70 4f  pReal, flags, pO
41d0: 75 74 46 6c 61 67 73 29 3b 0a 20 20 69 66 28 20  utFlags);.  if( 
41e0: 70 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d 65 74  pFd->pReal->pMet
41f0: 68 6f 64 73 20 29 7b 0a 20 20 20 20 73 71 6c 69  hods ){.    sqli
4200: 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a  te3_io_methods *
4210: 70 4d 65 74 68 6f 64 73 3b 0a 20 20 20 20 69 6e  pMethods;.    in
4220: 74 20 6e 42 79 74 65 3b 0a 0a 20 20 20 20 69 66  t nByte;..    if
4230: 28 20 70 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e  ( pVfs->iVersion
4240: 3e 31 20 29 7b 0a 20 20 20 20 20 20 6e 42 79 74  >1 ){.      nByt
4250: 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69 74  e = sizeof(sqlit
4260: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29 3b 0a  e3_io_methods);.
4270: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4280: 20 6e 42 79 74 65 20 3d 20 6f 66 66 73 65 74 6f   nByte = offseto
4290: 66 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74  f(sqlite3_io_met
42a0: 68 6f 64 73 2c 20 78 53 68 6d 4d 61 70 29 3b 0a  hods, xShmMap);.
42b0: 20 20 20 20 7d 0a 0a 20 20 20 20 70 4d 65 74 68      }..    pMeth
42c0: 6f 64 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 69  ods = (sqlite3_i
42d0: 6f 5f 6d 65 74 68 6f 64 73 20 2a 29 63 6b 61 6c  o_methods *)ckal
42e0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
42f0: 6d 65 6d 63 70 79 28 70 4d 65 74 68 6f 64 73 2c  memcpy(pMethods,
4300: 20 26 74 76 66 73 5f 69 6f 5f 6d 65 74 68 6f 64   &tvfs_io_method
4310: 73 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  s, nByte);.    p
4320: 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69 6f  Methods->iVersio
4330: 6e 20 3d 20 70 56 66 73 2d 3e 69 56 65 72 73 69  n = pVfs->iVersi
4340: 6f 6e 3b 0a 20 20 20 20 69 66 28 20 70 56 66 73  on;.    if( pVfs
4350: 2d 3e 69 56 65 72 73 69 6f 6e 3e 31 20 26 26 20  ->iVersion>1 && 
4360: 28 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73  ((Testvfs *)pVfs
4370: 2d 3e 70 41 70 70 44 61 74 61 29 2d 3e 69 73 4e  ->pAppData)->isN
4380: 6f 73 68 6d 20 29 7b 0a 20 20 20 20 20 20 70 4d  oshm ){.      pM
4390: 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e 6d 61  ethods->xShmUnma
43a0: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65  p = 0;.      pMe
43b0: 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63 6b 20  thods->xShmLock 
43c0: 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74 68  = 0;.      pMeth
43d0: 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72 69 65 72  ods->xShmBarrier
43e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74   = 0;.      pMet
43f0: 68 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 20 3d 20  hods->xShmMap = 
4400: 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 46 69  0;.    }.    pFi
4410: 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 20 3d 20 70  le->pMethods = p
4420: 4d 65 74 68 6f 64 73 3b 0a 20 20 7d 0a 0a 20 20  Methods;.  }..  
4430: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
4440: 0a 2a 2a 20 44 65 6c 65 74 65 20 74 68 65 20 66  .** Delete the f
4450: 69 6c 65 20 6c 6f 63 61 74 65 64 20 61 74 20 7a  ile located at z
4460: 50 61 74 68 2e 20 49 66 20 74 68 65 20 64 69 72  Path. If the dir
4470: 53 79 6e 63 20 61 72 67 75 6d 65 6e 74 20 69 73  Sync argument is
4480: 20 74 72 75 65 2c 0a 2a 2a 20 65 6e 73 75 72 65   true,.** ensure
4490: 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65 6d   the file-system
44a0: 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73 20 61   modifications a
44b0: 72 65 20 73 79 6e 63 65 64 20 74 6f 20 64 69 73  re synced to dis
44c0: 6b 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75  k before.** retu
44d0: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
44e0: 20 69 6e 74 20 74 76 66 73 44 65 6c 65 74 65 28   int tvfsDelete(
44f0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4500: 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  s, const char *z
4510: 50 61 74 68 2c 20 69 6e 74 20 64 69 72 53 79 6e  Path, int dirSyn
4520: 63 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  c){.  int rc = S
4530: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74  QLITE_OK;.  Test
4540: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
4550: 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61  s *)pVfs->pAppDa
4560: 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  ta;..  if( p->pS
4570: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
4580: 26 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45 5f  &TESTVFS_DELETE_
4590: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73  MASK ){.    tvfs
45a0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 44 65 6c  ExecTcl(p, "xDel
45b0: 65 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ete", .        T
45c0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
45d0: 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f  zPath, -1), Tcl_
45e0: 4e 65 77 49 6e 74 4f 62 6a 28 64 69 72 53 79 6e  NewIntObj(dirSyn
45f0: 63 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20  c), 0.    );.   
4600: 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28   tvfsResultCode(
4610: 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 69  p, &rc);.  }.  i
4620: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4630: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
4640: 69 74 65 33 4f 73 44 65 6c 65 74 65 28 50 41 52  ite3OsDelete(PAR
4650: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50  ENTVFS(pVfs), zP
4660: 61 74 68 2c 20 64 69 72 53 79 6e 63 29 3b 0a 20  ath, dirSync);. 
4670: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
4680: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 66 6f  }../*.** Test fo
4690: 72 20 61 63 63 65 73 73 20 70 65 72 6d 69 73 73  r access permiss
46a0: 69 6f 6e 73 2e 20 52 65 74 75 72 6e 20 74 72 75  ions. Return tru
46b0: 65 20 69 66 20 74 68 65 20 72 65 71 75 65 73 74  e if the request
46c0: 65 64 20 70 65 72 6d 69 73 73 69 6f 6e 0a 2a 2a  ed permission.**
46d0: 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2c 20 6f   is available, o
46e0: 72 20 66 61 6c 73 65 20 6f 74 68 65 72 77 69 73  r false otherwis
46f0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
4700: 20 74 76 66 73 41 63 63 65 73 73 28 0a 20 20 73   tvfsAccess(.  s
4710: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4720: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
4730: 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74 20 66  *zPath, .  int f
4740: 6c 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70 52  lags, .  int *pR
4750: 65 73 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74 76  esOut.){.  Testv
4760: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
4770: 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74   *)pVfs->pAppDat
4780: 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  a;.  if( p->pScr
4790: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
47a0: 45 53 54 56 46 53 5f 41 43 43 45 53 53 5f 4d 41  ESTVFS_ACCESS_MA
47b0: 53 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63  SK ){.    int rc
47c0: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 72 67  ;.    char *zArg
47d0: 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 66 6c   = 0;.    if( fl
47e0: 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45  ags==SQLITE_ACCE
47f0: 53 53 5f 45 58 49 53 54 53 20 29 20 7a 41 72 67  SS_EXISTS ) zArg
4800: 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53   = "SQLITE_ACCES
4810: 53 5f 45 58 49 53 54 53 22 3b 0a 20 20 20 20 69  S_EXISTS";.    i
4820: 66 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45  f( flags==SQLITE
4830: 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49 54  _ACCESS_READWRIT
4840: 45 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c 49  E ) zArg = "SQLI
4850: 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52  TE_ACCESS_READWR
4860: 49 54 45 22 3b 0a 20 20 20 20 69 66 28 20 66 6c  ITE";.    if( fl
4870: 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45  ags==SQLITE_ACCE
4880: 53 53 5f 52 45 41 44 20 29 20 7a 41 72 67 20 3d  SS_READ ) zArg =
4890: 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f   "SQLITE_ACCESS_
48a0: 52 45 41 44 22 3b 0a 20 20 20 20 74 76 66 73 45  READ";.    tvfsE
48b0: 78 65 63 54 63 6c 28 70 2c 20 22 78 41 63 63 65  xecTcl(p, "xAcce
48c0: 73 73 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  ss", .        Tc
48d0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a  l_NewStringObj(z
48e0: 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f 4e  Path, -1), Tcl_N
48f0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 41 72 67  ewStringObj(zArg
4900: 2c 20 2d 31 29 2c 20 30 0a 20 20 20 20 29 3b 0a  , -1), 0.    );.
4910: 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73 75      if( tvfsResu
4920: 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20 29  ltCode(p, &rc) )
4930: 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  {.      if( rc!=
4940: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
4950: 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73 65  rn rc;.    }else
4960: 7b 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 74 65  {.      Tcl_Inte
4970: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d 3e  rp *interp = p->
4980: 69 6e 74 65 72 70 3b 0a 20 20 20 20 20 20 69 66  interp;.      if
4990: 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f 47 65  ( TCL_OK==Tcl_Ge
49a0: 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28  tBooleanFromObj(
49b0: 30 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73  0, Tcl_GetObjRes
49c0: 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 70 52 65  ult(interp), pRe
49d0: 73 4f 75 74 29 20 29 7b 0a 20 20 20 20 20 20 20  sOut) ){.       
49e0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
49f0: 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  K;.      }.    }
4a00: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71  .  }.  return sq
4a10: 6c 69 74 65 33 4f 73 41 63 63 65 73 73 28 50 41  lite3OsAccess(PA
4a20: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a  RENTVFS(pVfs), z
4a30: 50 61 74 68 2c 20 66 6c 61 67 73 2c 20 70 52 65  Path, flags, pRe
4a40: 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  sOut);.}../*.** 
4a50: 50 6f 70 75 6c 61 74 65 20 62 75 66 66 65 72 20  Populate buffer 
4a60: 7a 4f 75 74 20 77 69 74 68 20 74 68 65 20 66 75  zOut with the fu
4a70: 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61 74  ll canonical pat
4a80: 68 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f 6e 64  hname correspond
4a90: 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 70 61  ing.** to the pa
4aa0: 74 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74 68 2e  thname in zPath.
4ab0: 20 7a 4f 75 74 20 69 73 20 67 75 61 72 61 6e 74   zOut is guarant
4ac0: 65 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  eed to point to 
4ad0: 61 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66 20 61  a buffer.** of a
4ae0: 74 20 6c 65 61 73 74 20 28 44 45 56 53 59 4d 5f  t least (DEVSYM_
4af0: 4d 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31 29 20  MAX_PATHNAME+1) 
4b00: 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  bytes..*/.static
4b10: 20 69 6e 74 20 74 76 66 73 46 75 6c 6c 50 61 74   int tvfsFullPat
4b20: 68 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74 65 33  hname(.  sqlite3
4b30: 5f 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20 63  _vfs *pVfs, .  c
4b40: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68  onst char *zPath
4b50: 2c 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20 0a  , .  int nOut, .
4b60: 20 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29 7b 0a    char *zOut.){.
4b70: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
4b80: 54 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d 3e  Testvfs *)pVfs->
4b90: 70 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20  pAppData;.  if( 
4ba0: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
4bb0: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 46 55  >mask&TESTVFS_FU
4bc0: 4c 4c 50 41 54 48 4e 41 4d 45 5f 4d 41 53 4b 20  LLPATHNAME_MASK 
4bd0: 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20  ){.    int rc;. 
4be0: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
4bf0: 2c 20 22 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65  , "xFullPathname
4c00: 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  ", Tcl_NewString
4c10: 4f 62 6a 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20  Obj(zPath, -1), 
4c20: 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 74  0, 0);.    if( t
4c30: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
4c40: 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20 69   &rc) ){.      i
4c50: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
4c60: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
4c70: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
4c80: 20 73 71 6c 69 74 65 33 4f 73 46 75 6c 6c 50 61   sqlite3OsFullPa
4c90: 74 68 6e 61 6d 65 28 50 41 52 45 4e 54 56 46 53  thname(PARENTVFS
4ca0: 28 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 6e  (pVfs), zPath, n
4cb0: 4f 75 74 2c 20 7a 4f 75 74 29 3b 0a 7d 0a 0a 23  Out, zOut);.}..#
4cc0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
4cd0: 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f  IT_LOAD_EXTENSIO
4ce0: 4e 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 74 68 65  N./*.** Open the
4cf0: 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72 79   dynamic library
4d00: 20 6c 6f 63 61 74 65 64 20 61 74 20 7a 50 61 74   located at zPat
4d10: 68 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 68  h and return a h
4d20: 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  andle..*/.static
4d30: 20 76 6f 69 64 20 2a 74 76 66 73 44 6c 4f 70 65   void *tvfsDlOpe
4d40: 6e 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  n(sqlite3_vfs *p
4d50: 56 66 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Vfs, const char 
4d60: 2a 7a 50 61 74 68 29 7b 0a 20 20 72 65 74 75 72  *zPath){.  retur
4d70: 6e 20 73 71 6c 69 74 65 33 4f 73 44 6c 4f 70 65  n sqlite3OsDlOpe
4d80: 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  n(PARENTVFS(pVfs
4d90: 29 2c 20 7a 50 61 74 68 29 3b 0a 7d 0a 0a 2f 2a  ), zPath);.}../*
4da0: 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 65  .** Populate the
4db0: 20 62 75 66 66 65 72 20 7a 45 72 72 4d 73 67 20   buffer zErrMsg 
4dc0: 28 73 69 7a 65 20 6e 42 79 74 65 20 62 79 74 65  (size nByte byte
4dd0: 73 29 20 77 69 74 68 20 61 20 68 75 6d 61 6e 20  s) with a human 
4de0: 72 65 61 64 61 62 6c 65 0a 2a 2a 20 75 74 66 2d  readable.** utf-
4df0: 38 20 73 74 72 69 6e 67 20 64 65 73 63 72 69 62  8 string describ
4e00: 69 6e 67 20 74 68 65 20 6d 6f 73 74 20 72 65 63  ing the most rec
4e10: 65 6e 74 20 65 72 72 6f 72 20 65 6e 63 6f 75 6e  ent error encoun
4e20: 74 65 72 65 64 20 61 73 73 6f 63 69 61 74 65 64  tered associated
4e30: 20 0a 2a 2a 20 77 69 74 68 20 64 79 6e 61 6d 69   .** with dynami
4e40: 63 20 6c 69 62 72 61 72 69 65 73 2e 0a 2a 2f 0a  c libraries..*/.
4e50: 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73  static void tvfs
4e60: 44 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f  DlError(sqlite3_
4e70: 76 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e  vfs *pVfs, int n
4e80: 42 79 74 65 2c 20 63 68 61 72 20 2a 7a 45 72 72  Byte, char *zErr
4e90: 4d 73 67 29 7b 0a 20 20 73 71 6c 69 74 65 33 4f  Msg){.  sqlite3O
4ea0: 73 44 6c 45 72 72 6f 72 28 50 41 52 45 4e 54 56  sDlError(PARENTV
4eb0: 46 53 28 70 56 66 73 29 2c 20 6e 42 79 74 65 2c  FS(pVfs), nByte,
4ec0: 20 7a 45 72 72 4d 73 67 29 3b 0a 7d 0a 0a 2f 2a   zErrMsg);.}../*
4ed0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
4ee0: 6e 74 65 72 20 74 6f 20 74 68 65 20 73 79 6d 62  nter to the symb
4ef0: 6f 6c 20 7a 53 79 6d 62 6f 6c 20 69 6e 20 74 68  ol zSymbol in th
4f00: 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72  e dynamic librar
4f10: 79 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  y pHandle..*/.st
4f20: 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66 73  atic void (*tvfs
4f30: 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76 66  DlSym(sqlite3_vf
4f40: 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70  s *pVfs, void *p
4f50: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53  , const char *zS
4f60: 79 6d 29 29 28 76 6f 69 64 29 7b 0a 20 20 72 65  ym))(void){.  re
4f70: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 44 6c  turn sqlite3OsDl
4f80: 53 79 6d 28 50 41 52 45 4e 54 56 46 53 28 70 56  Sym(PARENTVFS(pV
4f90: 66 73 29 2c 20 70 2c 20 7a 53 79 6d 29 3b 0a 7d  fs), p, zSym);.}
4fa0: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68  ../*.** Close th
4fb0: 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72  e dynamic librar
4fc0: 79 20 68 61 6e 64 6c 65 20 70 48 61 6e 64 6c 65  y handle pHandle
4fd0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4fe0: 20 74 76 66 73 44 6c 43 6c 6f 73 65 28 73 71 6c   tvfsDlClose(sql
4ff0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
5000: 76 6f 69 64 20 2a 70 48 61 6e 64 6c 65 29 7b 0a  void *pHandle){.
5010: 20 20 73 71 6c 69 74 65 33 4f 73 44 6c 43 6c 6f    sqlite3OsDlClo
5020: 73 65 28 50 41 52 45 4e 54 56 46 53 28 70 56 66  se(PARENTVFS(pVf
5030: 73 29 2c 20 70 48 61 6e 64 6c 65 29 3b 0a 7d 0a  s), pHandle);.}.
5040: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
5050: 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e  _OMIT_LOAD_EXTEN
5060: 53 49 4f 4e 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50  SION */../*.** P
5070: 6f 70 75 6c 61 74 65 20 74 68 65 20 62 75 66 66  opulate the buff
5080: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
5090: 20 7a 42 75 66 4f 75 74 20 77 69 74 68 20 6e 42   zBufOut with nB
50a0: 79 74 65 20 62 79 74 65 73 20 6f 66 20 0a 2a 2a  yte bytes of .**
50b0: 20 72 61 6e 64 6f 6d 20 64 61 74 61 2e 0a 2a 2f   random data..*/
50c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
50d0: 52 61 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74  Randomness(sqlit
50e0: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69 6e  e3_vfs *pVfs, in
50f0: 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a 7a  t nByte, char *z
5100: 42 75 66 4f 75 74 29 7b 0a 20 20 72 65 74 75 72  BufOut){.  retur
5110: 6e 20 73 71 6c 69 74 65 33 4f 73 52 61 6e 64 6f  n sqlite3OsRando
5120: 6d 6e 65 73 73 28 50 41 52 45 4e 54 56 46 53 28  mness(PARENTVFS(
5130: 70 56 66 73 29 2c 20 6e 42 79 74 65 2c 20 7a 42  pVfs), nByte, zB
5140: 75 66 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ufOut);.}../*.**
5150: 20 53 6c 65 65 70 20 66 6f 72 20 6e 4d 69 63 72   Sleep for nMicr
5160: 6f 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 2e 20  o microseconds. 
5170: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
5180: 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f 6e 64  r of microsecond
5190: 73 20 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 73  s .** actually s
51a0: 6c 65 70 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lept..*/.static 
51b0: 69 6e 74 20 74 76 66 73 53 6c 65 65 70 28 73 71  int tvfsSleep(sq
51c0: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
51d0: 20 69 6e 74 20 6e 4d 69 63 72 6f 29 7b 0a 20 20   int nMicro){.  
51e0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
51f0: 53 6c 65 65 70 28 50 41 52 45 4e 54 56 46 53 28  Sleep(PARENTVFS(
5200: 70 56 66 73 29 2c 20 6e 4d 69 63 72 6f 29 3b 0a  pVfs), nMicro);.
5210: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
5220: 74 68 65 20 63 75 72 72 65 6e 74 20 74 69 6d 65  the current time
5230: 20 61 73 20 61 20 4a 75 6c 69 61 6e 20 44 61 79   as a Julian Day
5240: 20 6e 75 6d 62 65 72 20 69 6e 20 2a 70 54 69 6d   number in *pTim
5250: 65 4f 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eOut..*/.static 
5260: 69 6e 74 20 74 76 66 73 43 75 72 72 65 6e 74 54  int tvfsCurrentT
5270: 69 6d 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ime(sqlite3_vfs 
5280: 2a 70 56 66 73 2c 20 64 6f 75 62 6c 65 20 2a 70  *pVfs, double *p
5290: 54 69 6d 65 4f 75 74 29 7b 0a 20 20 72 65 74 75  TimeOut){.  retu
52a0: 72 6e 20 50 41 52 45 4e 54 56 46 53 28 70 56 66  rn PARENTVFS(pVf
52b0: 73 29 2d 3e 78 43 75 72 72 65 6e 74 54 69 6d 65  s)->xCurrentTime
52c0: 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29  (PARENTVFS(pVfs)
52d0: 2c 20 70 54 69 6d 65 4f 75 74 29 3b 0a 7d 0a 0a  , pTimeOut);.}..
52e0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
52f0: 68 6d 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 66  hmOpen(sqlite3_f
5300: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
5310: 65 73 74 76 66 73 20 2a 70 3b 0a 20 20 69 6e 74  estvfs *p;.  int
5320: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
5330: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5340: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
5350: 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a   TestvfsBuffer *
5360: 70 42 75 66 66 65 72 3b 20 20 20 20 20 20 20 20  pBuffer;        
5370: 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 6f 70   /* Buffer to op
5380: 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f  en connection to
5390: 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 46 64 20   */.  TestvfsFd 
53a0: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
53b0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74 65 73        /* The tes
53c0: 74 76 66 73 20 66 69 6c 65 20 73 74 72 75 63 74  tvfs file struct
53d0: 75 72 65 20 2a 2f 0a 0a 20 20 70 46 64 20 3d 20  ure */..  pFd = 
53e0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
53f0: 3b 0a 20 20 70 20 3d 20 28 54 65 73 74 76 66 73  ;.  p = (Testvfs
5400: 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41   *)pFd->pVfs->pA
5410: 70 70 44 61 74 61 3b 0a 20 20 61 73 73 65 72 74  ppData;.  assert
5420: 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26 26  ( pFd->pShmId &&
5430: 20 70 46 64 2d 3e 70 53 68 6d 3d 3d 30 20 26 26   pFd->pShm==0 &&
5440: 20 70 46 64 2d 3e 70 4e 65 78 74 3d 3d 30 20 29   pFd->pNext==0 )
5450: 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61 74 65  ;..  /* Evaluate
5460: 20 74 68 65 20 54 63 6c 20 73 63 72 69 70 74 3a   the Tcl script:
5470: 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43   .  **.  **   SC
5480: 52 49 50 54 20 78 53 68 6d 4f 70 65 6e 20 46 49  RIPT xShmOpen FI
5490: 4c 45 4e 41 4d 45 0a 20 20 2a 2f 0a 20 20 54 63  LENAME.  */.  Tc
54a0: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d  l_ResetResult(p-
54b0: 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66 28 20  >interp);.  if( 
54c0: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
54d0: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48  >mask&TESTVFS_SH
54e0: 4d 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20  MOPEN_MASK ){.  
54f0: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
5500: 20 22 78 53 68 6d 4f 70 65 6e 22 2c 20 54 63 6c   "xShmOpen", Tcl
5510: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
5520: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
5530: 29 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66  ), 0, 0);.    if
5540: 28 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65  ( tvfsResultCode
5550: 28 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20  (p, &rc) ){.    
5560: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
5570: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
5580: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73  .    }.  }..  as
5590: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
55a0: 5f 4f 4b 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e  _OK );.  if( p->
55b0: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d  mask&TESTVFS_SHM
55c0: 4f 50 45 4e 5f 4d 41 53 4b 20 26 26 20 74 76 66  OPEN_MASK && tvf
55d0: 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20  sInjectIoerr(p) 
55e0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
55f0: 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a  LITE_IOERR;.  }.
5600: 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 66 6f 72  .  /* Search for
5610: 20 61 20 54 65 73 74 76 66 73 42 75 66 66 65 72   a TestvfsBuffer
5620: 2e 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 6f  . Create a new o
5630: 6e 65 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  ne if required. 
5640: 2a 2f 0a 20 20 66 6f 72 28 70 42 75 66 66 65 72  */.  for(pBuffer
5650: 3d 70 2d 3e 70 42 75 66 66 65 72 3b 20 70 42 75  =p->pBuffer; pBu
5660: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3d 70 42  ffer; pBuffer=pB
5670: 75 66 66 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20  uffer->pNext){. 
5680: 20 20 20 69 66 28 20 30 3d 3d 73 74 72 63 6d 70     if( 0==strcmp
5690: 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c  (pFd->zFilename,
56a0: 20 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 29   pBuffer->zFile)
56b0: 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20   ) break;.  }.  
56c0: 69 66 28 20 21 70 42 75 66 66 65 72 20 29 7b 0a  if( !pBuffer ){.
56d0: 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20      int nByte = 
56e0: 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 42 75  sizeof(TestvfsBu
56f0: 66 66 65 72 29 20 2b 20 73 74 72 6c 65 6e 28 70  ffer) + strlen(p
5700: 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 20 2b  Fd->zFilename) +
5710: 20 31 3b 0a 20 20 20 20 70 42 75 66 66 65 72 20   1;.    pBuffer 
5720: 3d 20 28 54 65 73 74 76 66 73 42 75 66 66 65 72  = (TestvfsBuffer
5730: 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65   *)ckalloc(nByte
5740: 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 42  );.    memset(pB
5750: 75 66 66 65 72 2c 20 30 2c 20 6e 42 79 74 65 29  uffer, 0, nByte)
5760: 3b 0a 20 20 20 20 70 42 75 66 66 65 72 2d 3e 7a  ;.    pBuffer->z
5770: 46 69 6c 65 20 3d 20 28 63 68 61 72 20 2a 29 26  File = (char *)&
5780: 70 42 75 66 66 65 72 5b 31 5d 3b 0a 20 20 20 20  pBuffer[1];.    
5790: 73 74 72 63 70 79 28 70 42 75 66 66 65 72 2d 3e  strcpy(pBuffer->
57a0: 7a 46 69 6c 65 2c 20 70 46 64 2d 3e 7a 46 69 6c  zFile, pFd->zFil
57b0: 65 6e 61 6d 65 29 3b 0a 20 20 20 20 70 42 75 66  ename);.    pBuf
57c0: 66 65 72 2d 3e 70 4e 65 78 74 20 3d 20 70 2d 3e  fer->pNext = p->
57d0: 70 42 75 66 66 65 72 3b 0a 20 20 20 20 70 2d 3e  pBuffer;.    p->
57e0: 70 42 75 66 66 65 72 20 3d 20 70 42 75 66 66 65  pBuffer = pBuffe
57f0: 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6e  r;.  }..  /* Con
5800: 6e 65 63 74 20 74 68 65 20 54 65 73 74 76 66 73  nect the Testvfs
5810: 42 75 66 66 65 72 20 74 6f 20 74 68 65 20 6e 65  Buffer to the ne
5820: 77 20 54 65 73 74 76 66 73 53 68 6d 20 68 61 6e  w TestvfsShm han
5830: 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 2e 20  dle and return. 
5840: 2a 2f 0a 20 20 70 46 64 2d 3e 70 4e 65 78 74 20  */.  pFd->pNext 
5850: 3d 20 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65  = pBuffer->pFile
5860: 3b 0a 20 20 70 42 75 66 66 65 72 2d 3e 70 46 69  ;.  pBuffer->pFi
5870: 6c 65 20 3d 20 70 46 64 3b 0a 20 20 70 46 64 2d  le = pFd;.  pFd-
5880: 3e 70 53 68 6d 20 3d 20 70 42 75 66 66 65 72 3b  >pShm = pBuffer;
5890: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
58a0: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  _OK;.}..static v
58b0: 6f 69 64 20 74 76 66 73 41 6c 6c 6f 63 50 61 67  oid tvfsAllocPag
58c0: 65 28 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e(TestvfsBuffer 
58d0: 2a 70 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 69  *p, int iPage, i
58e0: 6e 74 20 70 67 73 7a 29 7b 0a 20 20 61 73 73 65  nt pgsz){.  asse
58f0: 72 74 28 20 69 50 61 67 65 3c 54 45 53 54 56 46  rt( iPage<TESTVF
5900: 53 5f 4d 41 58 5f 50 41 47 45 53 20 29 3b 0a 20  S_MAX_PAGES );. 
5910: 20 69 66 28 20 70 2d 3e 61 50 61 67 65 5b 69 50   if( p->aPage[iP
5920: 61 67 65 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 70  age]==0 ){.    p
5930: 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 20 3d  ->aPage[iPage] =
5940: 20 28 75 38 20 2a 29 63 6b 61 6c 6c 6f 63 28 70   (u8 *)ckalloc(p
5950: 67 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74  gsz);.    memset
5960: 28 70 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d  (p->aPage[iPage]
5970: 2c 20 30 2c 20 70 67 73 7a 29 3b 0a 20 20 20 20  , 0, pgsz);.    
5980: 70 2d 3e 70 67 73 7a 20 3d 20 70 67 73 7a 3b 0a  p->pgsz = pgsz;.
5990: 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e    }.}..static in
59a0: 74 20 74 76 66 73 53 68 6d 4d 61 70 28 0a 20 20  t tvfsShmMap(.  
59b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
59c0: 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ile,            
59d0: 2f 2a 20 48 61 6e 64 6c 65 20 6f 70 65 6e 20 6f  /* Handle open o
59e0: 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  n database file 
59f0: 2a 2f 0a 20 20 69 6e 74 20 69 50 61 67 65 2c 20  */.  int iPage, 
5a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a10: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 74 6f 20       /* Page to 
5a20: 72 65 74 72 69 65 76 65 20 2a 2f 0a 20 20 69 6e  retrieve */.  in
5a30: 74 20 70 67 73 7a 2c 20 20 20 20 20 20 20 20 20  t pgsz,         
5a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5a50: 20 53 69 7a 65 20 6f 66 20 70 61 67 65 73 20 2a   Size of pages *
5a60: 2f 0a 20 20 69 6e 74 20 69 73 57 72 69 74 65 2c  /.  int isWrite,
5a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a80: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 65      /* True to e
5a90: 78 74 65 6e 64 20 66 69 6c 65 20 69 66 20 6e 65  xtend file if ne
5aa0: 63 65 73 73 61 72 79 20 2a 2f 0a 20 20 76 6f 69  cessary */.  voi
5ab0: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 70 70 20  d volatile **pp 
5ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5ad0: 4f 55 54 3a 20 4d 61 70 70 65 64 20 6d 65 6d 6f  OUT: Mapped memo
5ae0: 72 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  ry */.){.  int r
5af0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
5b00: 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20   TestvfsFd *pFd 
5b10: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
5b20: 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  e);.  Testvfs *p
5b30: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28 70   = (Testvfs *)(p
5b40: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
5b50: 74 61 29 3b 0a 0a 20 20 69 66 28 20 30 3d 3d 70  ta);..  if( 0==p
5b60: 46 64 2d 3e 70 53 68 6d 20 29 7b 0a 20 20 20 20  Fd->pShm ){.    
5b70: 72 63 20 3d 20 74 76 66 73 53 68 6d 4f 70 65 6e  rc = tvfsShmOpen
5b80: 28 70 46 69 6c 65 29 3b 0a 20 20 20 20 69 66 28  (pFile);.    if(
5b90: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
5ba0: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
5bb0: 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  c;.    }.  }..  
5bc0: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
5bd0: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
5be0: 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 29 7b  S_SHMMAP_MASK ){
5bf0: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 41  .    Tcl_Obj *pA
5c00: 72 67 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28  rg = Tcl_NewObj(
5c10: 29 3b 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52  );.    Tcl_IncrR
5c20: 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a 20  efCount(pArg);. 
5c30: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
5c40: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69  pendElement(p->i
5c50: 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c  nterp, pArg, Tcl
5c60: 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 50 61 67 65  _NewIntObj(iPage
5c70: 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74  ));.    Tcl_List
5c80: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
5c90: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41 72 67  (p->interp, pArg
5ca0: 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28  , Tcl_NewIntObj(
5cb0: 70 67 73 7a 29 29 3b 0a 20 20 20 20 54 63 6c 5f  pgsz));.    Tcl_
5cc0: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
5cd0: 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ment(p->interp, 
5ce0: 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pArg, Tcl_NewInt
5cf0: 4f 62 6a 28 69 73 57 72 69 74 65 29 29 3b 0a 20  Obj(isWrite));. 
5d00: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
5d10: 2c 20 22 78 53 68 6d 4d 61 70 22 2c 20 0a 20 20  , "xShmMap", .  
5d20: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
5d30: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d  ingObj(pFd->pShm
5d40: 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46  ->zFile, -1), pF
5d50: 64 2d 3e 70 53 68 6d 49 64 2c 20 70 41 72 67 0a  d->pShmId, pArg.
5d60: 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52      );.    tvfsR
5d70: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
5d80: 29 3b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  );.    Tcl_DecrR
5d90: 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a 20  efCount(pArg);. 
5da0: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
5db0: 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73  ITE_OK && p->mas
5dc0: 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41 50  k&TESTVFS_SHMMAP
5dd0: 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a  _MASK && tvfsInj
5de0: 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20  ectIoerr(p) ){. 
5df0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49     rc = SQLITE_I
5e00: 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  OERR;.  }..  if(
5e10: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
5e20: 26 20 69 73 57 72 69 74 65 20 26 26 20 21 70 46  & isWrite && !pF
5e30: 64 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65 5b 69  d->pShm->aPage[i
5e40: 50 61 67 65 5d 20 29 7b 0a 20 20 20 20 74 76 66  Page] ){.    tvf
5e50: 73 41 6c 6c 6f 63 50 61 67 65 28 70 46 64 2d 3e  sAllocPage(pFd->
5e60: 70 53 68 6d 2c 20 69 50 61 67 65 2c 20 70 67 73  pShm, iPage, pgs
5e70: 7a 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20  z);.  }.  *pp = 
5e80: 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a  (void volatile *
5e90: 29 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61 67  )pFd->pShm->aPag
5ea0: 65 5b 69 50 61 67 65 5d 3b 0a 0a 20 20 72 65 74  e[iPage];..  ret
5eb0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74  urn rc;.}...stat
5ec0: 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d 4c 6f  ic int tvfsShmLo
5ed0: 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  ck(.  sqlite3_fi
5ee0: 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69 6e 74  le *pFile,.  int
5ef0: 20 6f 66 73 74 2c 0a 20 20 69 6e 74 20 6e 2c 0a   ofst,.  int n,.
5f00: 20 20 69 6e 74 20 66 6c 61 67 73 0a 29 7b 0a 20    int flags.){. 
5f10: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
5f20: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
5f30: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
5f40: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
5f50: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
5f60: 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e  s *)(pFd->pVfs->
5f70: 70 41 70 70 44 61 74 61 29 3b 0a 20 20 69 6e 74  pAppData);.  int
5f80: 20 6e 4c 6f 63 6b 3b 0a 20 20 63 68 61 72 20 7a   nLock;.  char z
5f90: 4c 6f 63 6b 5b 38 30 5d 3b 0a 0a 20 20 69 66 28  Lock[80];..  if(
5fa0: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
5fb0: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
5fc0: 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b 0a 20  HMLOCK_MASK ){. 
5fd0: 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
5fe0: 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4c 6f 63 6b  ntf(sizeof(zLock
5ff0: 29 2c 20 7a 4c 6f 63 6b 2c 20 22 25 64 20 25 64  ), zLock, "%d %d
6000: 22 2c 20 6f 66 73 74 2c 20 6e 29 3b 0a 20 20 20  ", ofst, n);.   
6010: 20 6e 4c 6f 63 6b 20 3d 20 73 74 72 6c 65 6e 28   nLock = strlen(
6020: 7a 4c 6f 63 6b 29 3b 0a 20 20 20 20 69 66 28 20  zLock);.    if( 
6030: 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  flags & SQLITE_S
6040: 48 4d 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 20  HM_LOCK ){.     
6050: 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e   strcpy(&zLock[n
6060: 4c 6f 63 6b 5d 2c 20 22 20 6c 6f 63 6b 22 29 3b  Lock], " lock");
6070: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6080: 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b    strcpy(&zLock[
6090: 6e 4c 6f 63 6b 5d 2c 20 22 20 75 6e 6c 6f 63 6b  nLock], " unlock
60a0: 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 4c  ");.    }.    nL
60b0: 6f 63 6b 20 2b 3d 20 73 74 72 6c 65 6e 28 26 7a  ock += strlen(&z
60c0: 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 29 3b 0a 20 20  Lock[nLock]);.  
60d0: 20 20 69 66 28 20 66 6c 61 67 73 20 26 20 53 51    if( flags & SQ
60e0: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 20  LITE_SHM_SHARED 
60f0: 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79 28  ){.      strcpy(
6100: 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22  &zLock[nLock], "
6110: 20 73 68 61 72 65 64 22 29 3b 0a 20 20 20 20 7d   shared");.    }
6120: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 74 72 63  else{.      strc
6130: 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d  py(&zLock[nLock]
6140: 2c 20 22 20 65 78 63 6c 75 73 69 76 65 22 29 3b  , " exclusive");
6150: 0a 20 20 20 20 7d 0a 20 20 20 20 74 76 66 73 45  .    }.    tvfsE
6160: 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4c  xecTcl(p, "xShmL
6170: 6f 63 6b 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ock", .        T
6180: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
6190: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
61a0: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
61b0: 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  Id,.        Tcl_
61c0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 4c 6f  NewStringObj(zLo
61d0: 63 6b 2c 20 2d 31 29 0a 20 20 20 20 29 3b 0a 20  ck, -1).    );. 
61e0: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
61f0: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  e(p, &rc);.  }..
6200: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6210: 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  _OK && p->mask&T
6220: 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d  ESTVFS_SHMLOCK_M
6230: 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63  ASK && tvfsInjec
6240: 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20  tIoerr(p) ){.   
6250: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45   rc = SQLITE_IOE
6260: 52 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  RR;.  }..  if( r
6270: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6280: 20 20 20 20 69 6e 74 20 69 73 4c 6f 63 6b 20 3d      int isLock =
6290: 20 28 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45   (flags & SQLITE
62a0: 5f 53 48 4d 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20  _SHM_LOCK);.    
62b0: 69 6e 74 20 69 73 45 78 63 6c 20 3d 20 28 66 6c  int isExcl = (fl
62c0: 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d  ags & SQLITE_SHM
62d0: 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 20  _EXCLUSIVE);.   
62e0: 20 75 33 32 20 6d 61 73 6b 20 3d 20 28 28 28 31   u32 mask = (((1
62f0: 3c 3c 6e 29 2d 31 29 20 3c 3c 20 6f 66 73 74 29  <<n)-1) << ofst)
6300: 3b 0a 20 20 20 20 69 66 28 20 69 73 4c 6f 63 6b  ;.    if( isLock
6310: 20 29 7b 0a 20 20 20 20 20 20 54 65 73 74 76 66   ){.      Testvf
6320: 73 46 64 20 2a 70 32 3b 0a 20 20 20 20 20 20 66  sFd *p2;.      f
6330: 6f 72 28 70 32 3d 70 46 64 2d 3e 70 53 68 6d 2d  or(p2=pFd->pShm-
6340: 3e 70 46 69 6c 65 3b 20 70 32 3b 20 70 32 3d 70  >pFile; p2; p2=p
6350: 32 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  2->pNext){.     
6360: 20 20 20 69 66 28 20 70 32 3d 3d 70 46 64 20 29     if( p2==pFd )
6370: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
6380: 20 20 20 69 66 28 20 28 70 32 2d 3e 65 78 63 6c     if( (p2->excl
6390: 6c 6f 63 6b 26 6d 61 73 6b 29 20 7c 7c 20 28 69  lock&mask) || (i
63a0: 73 45 78 63 6c 20 26 26 20 70 32 2d 3e 73 68 61  sExcl && p2->sha
63b0: 72 65 64 6c 6f 63 6b 26 6d 61 73 6b 29 20 29 7b  redlock&mask) ){
63c0: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
63d0: 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 20  SQLITE_BUSY;.   
63e0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
63f0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
6400: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6410: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
6420: 20 20 20 69 66 28 20 69 73 45 78 63 6c 20 29 20     if( isExcl ) 
6430: 20 70 46 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20 7c   pFd->excllock |
6440: 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20 20  = mask;.        
6450: 69 66 28 20 21 69 73 45 78 63 6c 20 29 20 70 46  if( !isExcl ) pF
6460: 64 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 20 7c 3d  d->sharedlock |=
6470: 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 7d 0a 20   mask;.      }. 
6480: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6490: 69 66 28 20 69 73 45 78 63 6c 20 29 20 20 70 46  if( isExcl )  pF
64a0: 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20 26 3d 20 28  d->excllock &= (
64b0: 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 20 20 69 66  ~mask);.      if
64c0: 28 20 21 69 73 45 78 63 6c 20 29 20 70 46 64 2d  ( !isExcl ) pFd-
64d0: 3e 73 68 61 72 65 64 6c 6f 63 6b 20 26 3d 20 28  >sharedlock &= (
64e0: 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 7d 0a 20 20  ~mask);.    }.  
64f0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
6500: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74  }..static void t
6510: 76 66 73 53 68 6d 42 61 72 72 69 65 72 28 73 71  vfsShmBarrier(sq
6520: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
6530: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20  e){.  TestvfsFd 
6540: 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46 64  *pFd = tvfsGetFd
6550: 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74 76  (pFile);.  Testv
6560: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
6570: 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70   *)(pFd->pVfs->p
6580: 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69 66 28  AppData);..  if(
6590: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
65a0: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
65b0: 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 29  HMBARRIER_MASK )
65c0: 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63  {.    tvfsExecTc
65d0: 6c 28 70 2c 20 22 78 53 68 6d 42 61 72 72 69 65  l(p, "xShmBarrie
65e0: 72 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  r", .        Tcl
65f0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
6600: 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20  d->pShm->zFile, 
6610: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
6620: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 7d  , 0.    );.  }.}
6630: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ..static int tvf
6640: 73 53 68 6d 55 6e 6d 61 70 28 0a 20 20 73 71 6c  sShmUnmap(.  sql
6650: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
6660: 2c 0a 20 20 69 6e 74 20 64 65 6c 65 74 65 46 6c  ,.  int deleteFl
6670: 61 67 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ag.){.  int rc =
6680: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
6690: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
66a0: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
66b0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
66c0: 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64 2d  (Testvfs *)(pFd-
66d0: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29  >pVfs->pAppData)
66e0: 3b 0a 20 20 54 65 73 74 76 66 73 42 75 66 66 65  ;.  TestvfsBuffe
66f0: 72 20 2a 70 42 75 66 66 65 72 20 3d 20 70 46 64  r *pBuffer = pFd
6700: 2d 3e 70 53 68 6d 3b 0a 20 20 54 65 73 74 76 66  ->pShm;.  Testvf
6710: 73 46 64 20 2a 2a 70 70 46 64 3b 0a 0a 20 20 69  sFd **ppFd;..  i
6720: 66 28 20 21 70 42 75 66 66 65 72 20 29 20 72 65  f( !pBuffer ) re
6730: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
6740: 20 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e 70    assert( pFd->p
6750: 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70 53  ShmId && pFd->pS
6760: 68 6d 20 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  hm );..  if( p->
6770: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
6780: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 43 4c  sk&TESTVFS_SHMCL
6790: 4f 53 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20  OSE_MASK ){.    
67a0: 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22  tvfsExecTcl(p, "
67b0: 78 53 68 6d 55 6e 6d 61 70 22 2c 20 0a 20 20 20  xShmUnmap", .   
67c0: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
67d0: 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d 2d  ngObj(pFd->pShm-
67e0: 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46 64  >zFile, -1), pFd
67f0: 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20 20 20  ->pShmId, 0.    
6800: 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c  );.    tvfsResul
6810: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20  tCode(p, &rc);. 
6820: 20 7d 0a 0a 20 20 66 6f 72 28 70 70 46 64 3d 26   }..  for(ppFd=&
6830: 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65 3b 20  pBuffer->pFile; 
6840: 2a 70 70 46 64 21 3d 70 46 64 3b 20 70 70 46 64  *ppFd!=pFd; ppFd
6850: 3d 26 28 28 2a 70 70 46 64 29 2d 3e 70 4e 65 78  =&((*ppFd)->pNex
6860: 74 29 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28  t));.  assert( (
6870: 2a 70 70 46 64 29 3d 3d 70 46 64 20 29 3b 0a 20  *ppFd)==pFd );. 
6880: 20 2a 70 70 46 64 20 3d 20 70 46 64 2d 3e 70 4e   *ppFd = pFd->pN
6890: 65 78 74 3b 0a 20 20 70 46 64 2d 3e 70 4e 65 78  ext;.  pFd->pNex
68a0: 74 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 70 42  t = 0;..  if( pB
68b0: 75 66 66 65 72 2d 3e 70 46 69 6c 65 3d 3d 30 20  uffer->pFile==0 
68c0: 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  ){.    int i;.  
68d0: 20 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20    TestvfsBuffer 
68e0: 2a 2a 70 70 3b 0a 20 20 20 20 66 6f 72 28 70 70  **pp;.    for(pp
68f0: 3d 26 70 2d 3e 70 42 75 66 66 65 72 3b 20 2a 70  =&p->pBuffer; *p
6900: 70 21 3d 70 42 75 66 66 65 72 3b 20 70 70 3d 26  p!=pBuffer; pp=&
6910: 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 29 3b  ((*pp)->pNext));
6920: 0a 20 20 20 20 2a 70 70 20 3d 20 28 2a 70 70 29  .    *pp = (*pp)
6930: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 66 6f 72  ->pNext;.    for
6940: 28 69 3d 30 3b 20 70 42 75 66 66 65 72 2d 3e 61  (i=0; pBuffer->a
6950: 50 61 67 65 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  Page[i]; i++){. 
6960: 20 20 20 20 20 63 6b 66 72 65 65 28 28 63 68 61       ckfree((cha
6970: 72 20 2a 29 70 42 75 66 66 65 72 2d 3e 61 50 61  r *)pBuffer->aPa
6980: 67 65 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20  ge[i]);.    }.  
6990: 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a    ckfree((char *
69a0: 29 70 42 75 66 66 65 72 29 3b 0a 20 20 7d 0a 20  )pBuffer);.  }. 
69b0: 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30 3b 0a   pFd->pShm = 0;.
69c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
69d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
69e0: 76 66 73 5f 6f 62 6a 5f 63 6d 64 28 0a 20 20 43  vfs_obj_cmd(.  C
69f0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a 20 20  lientData cd,.  
6a00: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6a10: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
6a20: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
6a30: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 54 65 73   objv[].){.  Tes
6a40: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
6a50: 66 73 20 2a 29 63 64 3b 0a 0a 20 20 65 6e 75 6d  fs *)cd;..  enum
6a60: 20 44 42 5f 65 6e 75 6d 20 7b 20 0a 20 20 20 20   DB_enum { .    
6a70: 43 4d 44 5f 53 48 4d 2c 20 43 4d 44 5f 44 45 4c  CMD_SHM, CMD_DEL
6a80: 45 54 45 2c 20 43 4d 44 5f 46 49 4c 54 45 52 2c  ETE, CMD_FILTER,
6a90: 20 43 4d 44 5f 49 4f 45 52 52 2c 20 43 4d 44 5f   CMD_IOERR, CMD_
6aa0: 53 43 52 49 50 54 2c 20 0a 20 20 20 20 43 4d 44  SCRIPT, .    CMD
6ab0: 5f 44 45 56 43 48 41 52 2c 20 43 4d 44 5f 53 45  _DEVCHAR, CMD_SE
6ac0: 43 54 4f 52 53 49 5a 45 2c 20 43 4d 44 5f 46 55  CTORSIZE, CMD_FU
6ad0: 4c 4c 45 52 52 2c 20 43 4d 44 5f 43 41 4e 54 4f  LLERR, CMD_CANTO
6ae0: 50 45 4e 45 52 52 0a 20 20 7d 3b 0a 20 20 73 74  PENERR.  };.  st
6af0: 72 75 63 74 20 54 65 73 74 76 66 73 53 75 62 63  ruct TestvfsSubc
6b00: 6d 64 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  md {.    char *z
6b10: 4e 61 6d 65 3b 0a 20 20 20 20 65 6e 75 6d 20 44  Name;.    enum D
6b20: 42 5f 65 6e 75 6d 20 65 43 6d 64 3b 0a 20 20 7d  B_enum eCmd;.  }
6b30: 20 61 53 75 62 63 6d 64 5b 5d 20 3d 20 7b 0a 20   aSubcmd[] = {. 
6b40: 20 20 20 7b 20 22 73 68 6d 22 2c 20 20 20 20 20     { "shm",     
6b50: 20 20 20 20 43 4d 44 5f 53 48 4d 20 20 20 20 20      CMD_SHM     
6b60: 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 64 65      },.    { "de
6b70: 6c 65 74 65 22 2c 20 20 20 20 20 20 43 4d 44 5f  lete",      CMD_
6b80: 44 45 4c 45 54 45 20 20 20 20 20 20 7d 2c 0a 20  DELETE      },. 
6b90: 20 20 20 7b 20 22 66 69 6c 74 65 72 22 2c 20 20     { "filter",  
6ba0: 20 20 20 20 43 4d 44 5f 46 49 4c 54 45 52 20 20      CMD_FILTER  
6bb0: 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 69 6f      },.    { "io
6bc0: 65 72 72 22 2c 20 20 20 20 20 20 20 43 4d 44 5f  err",       CMD_
6bd0: 49 4f 45 52 52 20 20 20 20 20 20 20 7d 2c 0a 20  IOERR       },. 
6be0: 20 20 20 7b 20 22 66 75 6c 6c 65 72 72 22 2c 20     { "fullerr", 
6bf0: 20 20 20 20 43 4d 44 5f 46 55 4c 4c 45 52 52 20      CMD_FULLERR 
6c00: 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 63 61      },.    { "ca
6c10: 6e 74 6f 70 65 6e 65 72 72 22 2c 20 43 4d 44 5f  ntopenerr", CMD_
6c20: 43 41 4e 54 4f 50 45 4e 45 52 52 20 7d 2c 0a 20  CANTOPENERR },. 
6c30: 20 20 20 7b 20 22 73 63 72 69 70 74 22 2c 20 20     { "script",  
6c40: 20 20 20 20 43 4d 44 5f 53 43 52 49 50 54 20 20      CMD_SCRIPT  
6c50: 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 64 65      },.    { "de
6c60: 76 63 68 61 72 22 2c 20 20 20 20 20 43 4d 44 5f  vchar",     CMD_
6c70: 44 45 56 43 48 41 52 20 20 20 20 20 7d 2c 0a 20  DEVCHAR     },. 
6c80: 20 20 20 7b 20 22 73 65 63 74 6f 72 73 69 7a 65     { "sectorsize
6c90: 22 2c 20 20 43 4d 44 5f 53 45 43 54 4f 52 53 49  ",  CMD_SECTORSI
6ca0: 5a 45 20 20 7d 2c 0a 20 20 20 20 7b 20 30 2c 20  ZE  },.    { 0, 
6cb0: 30 20 7d 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69  0 }.  };.  int i
6cc0: 3b 0a 20 20 0a 20 20 69 66 28 20 6f 62 6a 63 3c  ;.  .  if( objc<
6cd0: 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  2 ){.    Tcl_Wro
6ce0: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
6cf0: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 53 55 42 43  , 1, objv, "SUBC
6d00: 4f 4d 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20  OMMAND ...");.  
6d10: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
6d20: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 54 63  OR;.  }.  if( Tc
6d30: 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62  l_GetIndexFromOb
6d40: 6a 53 74 72 75 63 74 28 0a 20 20 20 20 20 20 20  jStruct(.       
6d50: 20 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d   interp, objv[1]
6d60: 2c 20 61 53 75 62 63 6d 64 2c 20 73 69 7a 65 6f  , aSubcmd, sizeo
6d70: 66 28 61 53 75 62 63 6d 64 5b 30 5d 29 2c 20 22  f(aSubcmd[0]), "
6d80: 73 75 62 63 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20  subcommand", 0, 
6d90: 26 69 29 20 0a 20 20 29 7b 0a 20 20 20 20 72 65  &i) .  ){.    re
6da0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
6db0: 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65 74 52    }.  Tcl_ResetR
6dc0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a  esult(interp);..
6dd0: 20 20 73 77 69 74 63 68 28 20 61 53 75 62 63 6d    switch( aSubcm
6de0: 64 5b 69 5d 2e 65 43 6d 64 20 29 7b 0a 20 20 20  d[i].eCmd ){.   
6df0: 20 63 61 73 65 20 43 4d 44 5f 53 48 4d 3a 20 7b   case CMD_SHM: {
6e00: 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a  .      Tcl_Obj *
6e10: 70 4f 62 6a 3b 0a 20 20 20 20 20 20 69 6e 74 20  pObj;.      int 
6e20: 69 3b 0a 20 20 20 20 20 20 54 65 73 74 76 66 73  i;.      Testvfs
6e30: 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72 3b  Buffer *pBuffer;
6e40: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61  .      char *zNa
6e50: 6d 65 3b 0a 20 20 20 20 20 20 69 66 28 20 6f 62  me;.      if( ob
6e60: 6a 63 21 3d 33 20 26 26 20 6f 62 6a 63 21 3d 34  jc!=3 && objc!=4
6e70: 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f   ){.        Tcl_
6e80: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
6e90: 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 46  erp, 2, objv, "F
6ea0: 49 4c 45 20 3f 56 41 4c 55 45 3f 22 29 3b 0a 20  ILE ?VALUE?");. 
6eb0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
6ec0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
6ed0: 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 63  .      zName = c
6ee0: 6b 61 6c 6c 6f 63 28 70 2d 3e 70 50 61 72 65 6e  kalloc(p->pParen
6ef0: 74 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 29 3b 0a  t->mxPathname);.
6f00: 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74        p->pParent
6f10: 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  ->xFullPathname(
6f20: 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70 50  .          p->pP
6f30: 61 72 65 6e 74 2c 20 54 63 6c 5f 47 65 74 53 74  arent, Tcl_GetSt
6f40: 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 0a  ring(objv[2]), .
6f50: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70 50 61            p->pPa
6f60: 72 65 6e 74 2d 3e 6d 78 50 61 74 68 6e 61 6d 65  rent->mxPathname
6f70: 2c 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b  , zName.      );
6f80: 0a 20 20 20 20 20 20 66 6f 72 28 70 42 75 66 66  .      for(pBuff
6f90: 65 72 3d 70 2d 3e 70 42 75 66 66 65 72 3b 20 70  er=p->pBuffer; p
6fa0: 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72 3d  Buffer; pBuffer=
6fb0: 70 42 75 66 66 65 72 2d 3e 70 4e 65 78 74 29 7b  pBuffer->pNext){
6fc0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 30 3d 3d  .        if( 0==
6fd0: 73 74 72 63 6d 70 28 70 42 75 66 66 65 72 2d 3e  strcmp(pBuffer->
6fe0: 7a 46 69 6c 65 2c 20 7a 4e 61 6d 65 29 20 29 20  zFile, zName) ) 
6ff0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
7000: 20 20 20 20 20 63 6b 66 72 65 65 28 7a 4e 61 6d       ckfree(zNam
7010: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70  e);.      if( !p
7020: 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20 20 20  Buffer ){.      
7030: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
7040: 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73  lt(interp, "no s
7050: 75 63 68 20 66 69 6c 65 3a 20 22 2c 20 54 63 6c  uch file: ", Tcl
7060: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
7070: 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  2]), 0);.       
7080: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7090: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
70a0: 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a   if( objc==4 ){.
70b0: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 20          int n;. 
70c0: 20 20 20 20 20 20 20 75 38 20 2a 61 20 3d 20 54         u8 *a = T
70d0: 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61 79 46  cl_GetByteArrayF
70e0: 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 33 5d 2c 20  romObj(objv[3], 
70f0: 26 6e 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  &n);.        int
7100: 20 70 67 73 7a 20 3d 20 70 42 75 66 66 65 72 2d   pgsz = pBuffer-
7110: 3e 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 69  >pgsz;.        i
7120: 66 28 20 70 67 73 7a 3d 3d 30 20 29 20 70 67 73  f( pgsz==0 ) pgs
7130: 7a 20 3d 20 36 35 35 33 36 3b 0a 20 20 20 20 20  z = 65536;.     
7140: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 2a 70 67     for(i=0; i*pg
7150: 73 7a 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  sz<n; i++){.    
7160: 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
7170: 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20  = pgsz;.        
7180: 20 20 74 76 66 73 41 6c 6c 6f 63 50 61 67 65 28    tvfsAllocPage(
7190: 70 42 75 66 66 65 72 2c 20 69 2c 20 70 67 73 7a  pBuffer, i, pgsz
71a0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  );.          if(
71b0: 20 6e 2d 69 2a 70 67 73 7a 3c 70 67 73 7a 20 29   n-i*pgsz<pgsz )
71c0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 42  {.            nB
71d0: 79 74 65 20 3d 20 6e 3b 0a 20 20 20 20 20 20 20  yte = n;.       
71e0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 6d     }.          m
71f0: 65 6d 63 70 79 28 70 42 75 66 66 65 72 2d 3e 61  emcpy(pBuffer->a
7200: 50 61 67 65 5b 69 5d 2c 20 26 61 5b 69 2a 70 67  Page[i], &a[i*pg
7210: 73 7a 5d 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  sz], nByte);.   
7220: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
7230: 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54 63 6c        pObj = Tcl
7240: 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 20  _NewObj();.     
7250: 20 66 6f 72 28 69 3d 30 3b 20 70 42 75 66 66 65   for(i=0; pBuffe
7260: 72 2d 3e 61 50 61 67 65 5b 69 5d 3b 20 69 2b 2b  r->aPage[i]; i++
7270: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 70  ){.        int p
7280: 67 73 7a 20 3d 20 70 42 75 66 66 65 72 2d 3e 70  gsz = pBuffer->p
7290: 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 69 66 28  gsz;.        if(
72a0: 20 70 67 73 7a 3d 3d 30 20 29 20 70 67 73 7a 20   pgsz==0 ) pgsz 
72b0: 3d 20 36 35 35 33 36 3b 0a 20 20 20 20 20 20 20  = 65536;.       
72c0: 20 54 63 6c 5f 41 70 70 65 6e 64 4f 62 6a 54 6f   Tcl_AppendObjTo
72d0: 4f 62 6a 28 70 4f 62 6a 2c 20 54 63 6c 5f 4e 65  Obj(pObj, Tcl_Ne
72e0: 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28 70 42  wByteArrayObj(pB
72f0: 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 2c  uffer->aPage[i],
7300: 20 70 67 73 7a 29 29 3b 0a 20 20 20 20 20 20 7d   pgsz));.      }
7310: 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62  .      Tcl_SetOb
7320: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
7330: 70 4f 62 6a 29 3b 0a 20 20 20 20 20 20 62 72 65  pObj);.      bre
7340: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
7350: 61 73 65 20 43 4d 44 5f 46 49 4c 54 45 52 3a 20  ase CMD_FILTER: 
7360: 7b 0a 20 20 20 20 20 20 73 74 61 74 69 63 20 73  {.      static s
7370: 74 72 75 63 74 20 56 66 73 4d 65 74 68 6f 64 20  truct VfsMethod 
7380: 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a  {.        char *
7390: 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 69  zName;.        i
73a0: 6e 74 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 7d  nt mask;.      }
73b0: 20 76 66 73 6d 65 74 68 6f 64 20 5b 5d 20 3d 20   vfsmethod [] = 
73c0: 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68  {.        { "xSh
73d0: 6d 4f 70 65 6e 22 2c 20 20 20 20 20 20 54 45 53  mOpen",      TES
73e0: 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53  TVFS_SHMOPEN_MAS
73f0: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
7400: 78 53 68 6d 4c 6f 63 6b 22 2c 20 20 20 20 20 20  xShmLock",      
7410: 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f  TESTVFS_SHMLOCK_
7420: 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20  MASK },.        
7430: 7b 20 22 78 53 68 6d 42 61 72 72 69 65 72 22 2c  { "xShmBarrier",
7440: 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d 42 41     TESTVFS_SHMBA
7450: 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a 20 20  RRIER_MASK },.  
7460: 20 20 20 20 20 20 7b 20 22 78 53 68 6d 55 6e 6d        { "xShmUnm
7470: 61 70 22 2c 20 20 20 20 20 54 45 53 54 56 46 53  ap",     TESTVFS
7480: 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d  _SHMCLOSE_MASK }
7490: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68  ,.        { "xSh
74a0: 6d 4d 61 70 22 2c 20 20 20 20 20 20 20 54 45 53  mMap",       TES
74b0: 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b  TVFS_SHMMAP_MASK
74c0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
74d0: 53 79 6e 63 22 2c 20 20 20 20 20 20 20 20 20 54  Sync",         T
74e0: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
74f0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
7500: 44 65 6c 65 74 65 22 2c 20 20 20 20 20 20 20 54  Delete",       T
7510: 45 53 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d 41  ESTVFS_DELETE_MA
7520: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
7530: 22 78 57 72 69 74 65 22 2c 20 20 20 20 20 20 20  "xWrite",       
7540: 20 54 45 53 54 56 46 53 5f 57 52 49 54 45 5f 4d   TESTVFS_WRITE_M
7550: 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  ASK },.        {
7560: 20 22 78 54 72 75 6e 63 61 74 65 22 2c 20 20 20   "xTruncate",   
7570: 20 20 54 45 53 54 56 46 53 5f 54 52 55 4e 43 41    TESTVFS_TRUNCA
7580: 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  TE_MASK },.     
7590: 20 20 20 7b 20 22 78 4f 70 65 6e 22 2c 20 20 20     { "xOpen",   
75a0: 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 4f 50        TESTVFS_OP
75b0: 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  EN_MASK },.     
75c0: 20 20 20 7b 20 22 78 43 6c 6f 73 65 22 2c 20 20     { "xClose",  
75d0: 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 43 4c        TESTVFS_CL
75e0: 4f 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20  OSE_MASK },.    
75f0: 20 20 20 20 7b 20 22 78 41 63 63 65 73 73 22 2c      { "xAccess",
7600: 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 41         TESTVFS_A
7610: 43 43 45 53 53 5f 4d 41 53 4b 20 7d 2c 0a 20 20  CCESS_MASK },.  
7620: 20 20 20 20 20 20 7b 20 22 78 46 75 6c 6c 50 61        { "xFullPa
7630: 74 68 6e 61 6d 65 22 2c 20 54 45 53 54 56 46 53  thname", TESTVFS
7640: 5f 46 55 4c 4c 50 41 54 48 4e 41 4d 45 5f 4d 41  _FULLPATHNAME_MA
7650: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 7d 3b 0a 20  SK },.      };. 
7660: 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61       Tcl_Obj **a
7670: 70 45 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20 20  pElem = 0;.     
7680: 20 69 6e 74 20 6e 45 6c 65 6d 20 3d 20 30 3b 0a   int nElem = 0;.
7690: 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20        int i;.   
76a0: 20 20 20 69 6e 74 20 6d 61 73 6b 20 3d 20 30 3b     int mask = 0;
76b0: 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21  .      if( objc!
76c0: 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63  =3 ){.        Tc
76d0: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
76e0: 6e 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20  nterp, 2, objv, 
76f0: 22 4c 49 53 54 22 29 3b 0a 20 20 20 20 20 20 20  "LIST");.       
7700: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7710: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
7720: 20 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f 62 6a   if( Tcl_ListObj
7730: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65  GetElements(inte
7740: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45  rp, objv[2], &nE
7750: 6c 65 6d 2c 20 26 61 70 45 6c 65 6d 29 20 29 7b  lem, &apElem) ){
7760: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
7770: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
7780: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 52 65 73   }.      Tcl_Res
7790: 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  etResult(interp)
77a0: 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b  ;.      for(i=0;
77b0: 20 69 3c 6e 45 6c 65 6d 3b 20 69 2b 2b 29 7b 0a   i<nElem; i++){.
77c0: 20 20 20 20 20 20 20 20 69 6e 74 20 69 4d 65 74          int iMet
77d0: 68 6f 64 3b 0a 20 20 20 20 20 20 20 20 63 68 61  hod;.        cha
77e0: 72 20 2a 7a 45 6c 65 6d 20 3d 20 54 63 6c 5f 47  r *zElem = Tcl_G
77f0: 65 74 53 74 72 69 6e 67 28 61 70 45 6c 65 6d 5b  etString(apElem[
7800: 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72  i]);.        for
7810: 28 69 4d 65 74 68 6f 64 3d 30 3b 20 69 4d 65 74  (iMethod=0; iMet
7820: 68 6f 64 3c 41 72 72 61 79 53 69 7a 65 28 76 66  hod<ArraySize(vf
7830: 73 6d 65 74 68 6f 64 29 3b 20 69 4d 65 74 68 6f  smethod); iMetho
7840: 64 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  d++){.          
7850: 69 66 28 20 73 74 72 63 6d 70 28 7a 45 6c 65 6d  if( strcmp(zElem
7860: 2c 20 76 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74  , vfsmethod[iMet
7870: 68 6f 64 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29  hod].zName)==0 )
7880: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 61  {.            ma
7890: 73 6b 20 7c 3d 20 76 66 73 6d 65 74 68 6f 64 5b  sk |= vfsmethod[
78a0: 69 4d 65 74 68 6f 64 5d 2e 6d 61 73 6b 3b 0a 20  iMethod].mask;. 
78b0: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b             break
78c0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
78d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
78e0: 69 66 28 20 69 4d 65 74 68 6f 64 3d 3d 41 72 72  if( iMethod==Arr
78f0: 61 79 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64  aySize(vfsmethod
7900: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54  ) ){.          T
7910: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
7920: 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e  interp, "unknown
7930: 20 6d 65 74 68 6f 64 3a 20 22 2c 20 7a 45 6c 65   method: ", zEle
7940: 6d 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 20  m, 0);.         
7950: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7960: 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  R;.        }.   
7970: 20 20 20 7d 0a 20 20 20 20 20 20 70 2d 3e 6d 61     }.      p->ma
7980: 73 6b 20 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20  sk = mask;.     
7990: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
79a0: 20 20 20 63 61 73 65 20 43 4d 44 5f 53 43 52 49     case CMD_SCRI
79b0: 50 54 3a 20 7b 0a 20 20 20 20 20 20 69 66 28 20  PT: {.      if( 
79c0: 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20  objc==3 ){.     
79d0: 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20     int nByte;.  
79e0: 20 20 20 20 20 20 69 66 28 20 70 2d 3e 70 53 63        if( p->pSc
79f0: 72 69 70 74 20 29 7b 0a 20 20 20 20 20 20 20 20  ript ){.        
7a00: 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75    Tcl_DecrRefCou
7a10: 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a  nt(p->pScript);.
7a20: 20 20 20 20 20 20 20 20 20 20 63 6b 66 72 65 65            ckfree
7a30: 28 28 63 68 61 72 20 2a 29 70 2d 3e 61 70 53 63  ((char *)p->apSc
7a40: 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 20  ript);.         
7a50: 20 70 2d 3e 61 70 53 63 72 69 70 74 20 3d 20 30   p->apScript = 0
7a60: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 6e  ;.          p->n
7a70: 53 63 72 69 70 74 20 3d 20 30 3b 0a 20 20 20 20  Script = 0;.    
7a80: 20 20 20 20 20 20 70 2d 3e 70 53 63 72 69 70 74        p->pScript
7a90: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 0;.        }.
7aa0: 20 20 20 20 20 20 20 20 54 63 6c 5f 47 65 74 53          Tcl_GetS
7ab0: 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a  tringFromObj(obj
7ac0: 76 5b 32 5d 2c 20 26 6e 42 79 74 65 29 3b 0a 20  v[2], &nByte);. 
7ad0: 20 20 20 20 20 20 20 69 66 28 20 6e 42 79 74 65         if( nByte
7ae0: 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  >0 ){.          
7af0: 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 54 63 6c  p->pScript = Tcl
7b00: 5f 44 75 70 6c 69 63 61 74 65 4f 62 6a 28 6f 62  _DuplicateObj(ob
7b10: 6a 76 5b 32 5d 29 3b 0a 20 20 20 20 20 20 20 20  jv[2]);.        
7b20: 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75    Tcl_IncrRefCou
7b30: 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a  nt(p->pScript);.
7b40: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7b50: 7d 65 6c 73 65 20 69 66 28 20 6f 62 6a 63 21 3d  }else if( objc!=
7b60: 32 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c  2 ){.        Tcl
7b70: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
7b80: 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22  terp, 2, objv, "
7b90: 3f 53 43 52 49 50 54 3f 22 29 3b 0a 20 20 20 20  ?SCRIPT?");.    
7ba0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
7bb0: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  RROR;.      }.. 
7bc0: 20 20 20 20 20 54 63 6c 5f 52 65 73 65 74 52 65       Tcl_ResetRe
7bd0: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20 20  sult(interp);.  
7be0: 20 20 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69      if( p->pScri
7bf0: 70 74 20 29 20 54 63 6c 5f 53 65 74 4f 62 6a 52  pt ) Tcl_SetObjR
7c00: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 2d  esult(interp, p-
7c10: 3e 70 53 63 72 69 70 74 29 3b 0a 0a 20 20 20 20  >pScript);..    
7c20: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
7c30: 20 20 20 20 2f 2a 0a 20 20 20 20 2a 2a 20 54 45      /*.    ** TE
7c40: 53 54 56 46 53 20 69 6f 65 72 72 20 3f 49 46 41  STVFS ioerr ?IFA
7c50: 49 4c 20 50 45 52 53 49 53 54 3f 0a 20 20 20 20  IL PERSIST?.    
7c60: 2a 2a 0a 20 20 20 20 2a 2a 20 20 20 57 68 65 72  **.    **   Wher
7c70: 65 20 49 46 41 49 4c 20 69 73 20 61 6e 20 69 6e  e IFAIL is an in
7c80: 74 65 67 65 72 20 61 6e 64 20 50 45 52 53 49 53  teger and PERSIS
7c90: 54 20 69 73 20 62 6f 6f 6c 65 61 6e 2e 0a 20 20  T is boolean..  
7ca0: 20 20 2a 2f 0a 20 20 20 20 63 61 73 65 20 43 4d    */.    case CM
7cb0: 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 3a 0a 20  D_CANTOPENERR:. 
7cc0: 20 20 20 63 61 73 65 20 43 4d 44 5f 49 4f 45 52     case CMD_IOER
7cd0: 52 3a 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f  R:.    case CMD_
7ce0: 46 55 4c 4c 45 52 52 3a 20 7b 0a 20 20 20 20 20  FULLERR: {.     
7cf0: 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74   TestFaultInject
7d00: 20 2a 70 54 65 73 74 3b 0a 20 20 20 20 20 20 69   *pTest;.      i
7d10: 6e 74 20 69 52 65 74 3b 0a 0a 20 20 20 20 20 20  nt iRet;..      
7d20: 73 77 69 74 63 68 28 20 61 53 75 62 63 6d 64 5b  switch( aSubcmd[
7d30: 69 5d 2e 65 43 6d 64 20 29 7b 0a 20 20 20 20 20  i].eCmd ){.     
7d40: 20 20 20 63 61 73 65 20 43 4d 44 5f 49 4f 45 52     case CMD_IOER
7d50: 52 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 69  R: pTest = &p->i
7d60: 6f 65 72 72 5f 65 72 72 3b 20 62 72 65 61 6b 3b  oerr_err; break;
7d70: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 43 4d  .        case CM
7d80: 44 5f 46 55 4c 4c 45 52 52 3a 20 70 54 65 73 74  D_FULLERR: pTest
7d90: 20 3d 20 26 70 2d 3e 66 75 6c 6c 5f 65 72 72 3b   = &p->full_err;
7da0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
7db0: 63 61 73 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45  case CMD_CANTOPE
7dc0: 4e 45 52 52 3a 20 70 54 65 73 74 20 3d 20 26 70  NERR: pTest = &p
7dd0: 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 20  ->cantopen_err; 
7de0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 64  break;.        d
7df0: 65 66 61 75 6c 74 3a 20 61 73 73 65 72 74 28 30  efault: assert(0
7e00: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
7e10: 20 69 52 65 74 20 3d 20 70 54 65 73 74 2d 3e 6e   iRet = pTest->n
7e20: 46 61 69 6c 3b 0a 20 20 20 20 20 20 70 54 65 73  Fail;.      pTes
7e30: 74 2d 3e 6e 46 61 69 6c 20 3d 20 30 3b 0a 20 20  t->nFail = 0;.  
7e40: 20 20 20 20 70 54 65 73 74 2d 3e 65 46 61 75 6c      pTest->eFaul
7e50: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 65  t = 0;.      pTe
7e60: 73 74 2d 3e 69 43 6e 74 20 3d 20 30 3b 0a 0a 20  st->iCnt = 0;.. 
7e70: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34       if( objc==4
7e80: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
7e90: 69 43 6e 74 2c 20 69 50 65 72 73 69 73 74 3b 0a  iCnt, iPersist;.
7ea0: 20 20 20 20 20 20 20 20 69 66 28 20 54 43 4c 5f          if( TCL_
7eb0: 4f 4b 21 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72  OK!=Tcl_GetIntFr
7ec0: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
7ed0: 6a 76 5b 32 5d 2c 20 26 69 43 6e 74 29 0a 20 20  jv[2], &iCnt).  
7ee0: 20 20 20 20 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b         || TCL_OK
7ef0: 21 3d 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e  !=Tcl_GetBoolean
7f00: 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20  FromObj(interp, 
7f10: 6f 62 6a 76 5b 33 5d 2c 20 26 69 50 65 72 73 69  objv[3], &iPersi
7f20: 73 74 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  st).        ){. 
7f30: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
7f40: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
7f50: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 54 65     }.        pTe
7f60: 73 74 2d 3e 65 46 61 75 6c 74 20 3d 20 69 50 65  st->eFault = iPe
7f70: 72 73 69 73 74 3f 46 41 55 4c 54 5f 49 4e 4a 45  rsist?FAULT_INJE
7f80: 43 54 5f 50 45 52 53 49 53 54 45 4e 54 3a 46 41  CT_PERSISTENT:FA
7f90: 55 4c 54 5f 49 4e 4a 45 43 54 5f 54 52 41 4e 53  ULT_INJECT_TRANS
7fa0: 49 45 4e 54 3b 0a 20 20 20 20 20 20 20 20 70 54  IENT;.        pT
7fb0: 65 73 74 2d 3e 69 43 6e 74 20 3d 20 69 43 6e 74  est->iCnt = iCnt
7fc0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
7fd0: 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20  ( objc!=2 ){.   
7fe0: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
7ff0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
8000: 20 6f 62 6a 76 2c 20 22 3f 43 4e 54 20 50 45 52   objv, "?CNT PER
8010: 53 49 53 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  SIST?");.       
8020: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8030: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
8040: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
8050: 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65  t(interp, Tcl_Ne
8060: 77 49 6e 74 4f 62 6a 28 69 52 65 74 29 29 3b 0a  wIntObj(iRet));.
8070: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
8080: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44   }..    case CMD
8090: 5f 44 45 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20  _DELETE: {.     
80a0: 20 54 63 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61   Tcl_DeleteComma
80b0: 6e 64 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  nd(interp, Tcl_G
80c0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d  etString(objv[0]
80d0: 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  ));.      break;
80e0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
80f0: 20 43 4d 44 5f 44 45 56 43 48 41 52 3a 20 7b 0a   CMD_DEVCHAR: {.
8100: 20 20 20 20 20 20 73 74 72 75 63 74 20 44 65 76        struct Dev
8110: 69 63 65 46 6c 61 67 20 7b 0a 20 20 20 20 20 20  iceFlag {.      
8120: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
8130: 20 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c 75         int iValu
8140: 65 3b 0a 20 20 20 20 20 20 7d 20 61 46 6c 61 67  e;.      } aFlag
8150: 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b  [] = {.        {
8160: 20 22 64 65 66 61 75 6c 74 22 2c 20 20 20 20 20   "default",     
8170: 20 20 20 20 20 20 20 20 20 20 2d 31 20 7d 2c 0a            -1 },.
8180: 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69          { "atomi
8190: 63 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  c",             
81a0: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
81b0: 41 54 4f 4d 49 43 20 20 20 20 20 20 7d 2c 0a 20  ATOMIC      },. 
81c0: 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63         { "atomic
81d0: 35 31 32 22 2c 20 20 20 20 20 20 20 20 20 20 20  512",           
81e0: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41    SQLITE_IOCAP_A
81f0: 54 4f 4d 49 43 35 31 32 20 20 20 7d 2c 0a 20 20  TOMIC512   },.  
8200: 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 31        { "atomic1
8210: 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  k",             
8220: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54   SQLITE_IOCAP_AT
8230: 4f 4d 49 43 31 4b 20 20 20 20 7d 2c 0a 20 20 20  OMIC1K    },.   
8240: 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 32 6b       { "atomic2k
8250: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ",              
8260: 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f  SQLITE_IOCAP_ATO
8270: 4d 49 43 32 4b 20 20 20 20 7d 2c 0a 20 20 20 20  MIC2K    },.    
8280: 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 34 6b 22      { "atomic4k"
8290: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53  ,              S
82a0: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d  QLITE_IOCAP_ATOM
82b0: 49 43 34 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20  IC4K    },.     
82c0: 20 20 20 7b 20 22 61 74 6f 6d 69 63 38 6b 22 2c     { "atomic8k",
82d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
82e0: 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49  LITE_IOCAP_ATOMI
82f0: 43 38 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20  C8K    },.      
8300: 20 20 7b 20 22 61 74 6f 6d 69 63 31 36 6b 22 2c    { "atomic16k",
8310: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
8320: 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43  ITE_IOCAP_ATOMIC
8330: 31 36 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20  16K   },.       
8340: 20 7b 20 22 61 74 6f 6d 69 63 33 32 6b 22 2c 20   { "atomic32k", 
8350: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
8360: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 33  TE_IOCAP_ATOMIC3
8370: 32 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20  2K   },.        
8380: 7b 20 22 61 74 6f 6d 69 63 36 34 6b 22 2c 20 20  { "atomic64k",  
8390: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
83a0: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 36 34  E_IOCAP_ATOMIC64
83b0: 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  K   },.        {
83c0: 20 22 73 65 71 75 65 6e 74 69 61 6c 22 2c 20 20   "sequential",  
83d0: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
83e0: 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41  _IOCAP_SEQUENTIA
83f0: 4c 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  L  },.        { 
8400: 22 73 61 66 65 5f 61 70 70 65 6e 64 22 2c 20 20  "safe_append",  
8410: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
8420: 49 4f 43 41 50 5f 53 41 46 45 5f 41 50 50 45 4e  IOCAP_SAFE_APPEN
8430: 44 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  D },.        { "
8440: 75 6e 64 65 6c 65 74 61 62 6c 65 5f 77 68 65 6e  undeletable_when
8450: 5f 6f 70 65 6e 22 2c 20 53 51 4c 49 54 45 5f 49  _open", SQLITE_I
8460: 4f 43 41 50 5f 55 4e 44 45 4c 45 54 41 42 4c 45  OCAP_UNDELETABLE
8470: 5f 57 48 45 4e 5f 4f 50 45 4e 20 7d 2c 0a 20 20  _WHEN_OPEN },.  
8480: 20 20 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20        { 0, 0 }. 
8490: 20 20 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63       };.      Tc
84a0: 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 20 20 20  l_Obj *pRet;.   
84b0: 20 20 20 69 6e 74 20 69 46 6c 61 67 3b 0a 0a 20     int iFlag;.. 
84c0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3e 33 20       if( objc>3 
84d0: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57  ){.        Tcl_W
84e0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
84f0: 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 41  rp, 2, objv, "?A
8500: 54 54 52 2d 4c 49 53 54 3f 22 29 3b 0a 20 20 20  TTR-LIST?");.   
8510: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
8520: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
8530: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33       if( objc==3
8540: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
8550: 6a 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  j;.        int i
8560: 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  New = 0;.       
8570: 20 54 63 6c 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73   Tcl_Obj **flags
8580: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69 6e   = 0;.        in
8590: 74 20 6e 46 6c 61 67 73 20 3d 20 30 3b 0a 0a 20  t nFlags = 0;.. 
85a0: 20 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 4c         if( Tcl_L
85b0: 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74  istObjGetElement
85c0: 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32  s(interp, objv[2
85d0: 5d 2c 20 26 6e 46 6c 61 67 73 2c 20 26 66 6c 61  ], &nFlags, &fla
85e0: 67 73 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  gs) ){.         
85f0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8600: 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  R;.        }..  
8610: 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a        for(j=0; j
8620: 3c 6e 46 6c 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20  <nFlags; j++){. 
8630: 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 64 78           int idx
8640: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
8650: 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 64 65 78  if( Tcl_GetIndex
8660: 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 69 6e  FromObjStruct(in
8670: 74 65 72 70 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20  terp, flags[j], 
8680: 61 46 6c 61 67 2c 20 0a 20 20 20 20 20 20 20 20  aFlag, .        
8690: 20 20 20 20 20 20 20 20 73 69 7a 65 6f 66 28 61          sizeof(a
86a0: 46 6c 61 67 5b 30 5d 29 2c 20 22 66 6c 61 67 22  Flag[0]), "flag"
86b0: 2c 20 30 2c 20 26 69 64 78 29 20 0a 20 20 20 20  , 0, &idx) .    
86c0: 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
86d0: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
86e0: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 20  ERROR;.         
86f0: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66 28   }.          if(
8700: 20 61 46 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c   aFlag[idx].iVal
8710: 75 65 3c 30 20 26 26 20 6e 46 6c 61 67 73 3e 31  ue<0 && nFlags>1
8720: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
8730: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
8740: 28 69 6e 74 65 72 70 2c 20 22 62 61 64 20 66 6c  (interp, "bad fl
8750: 61 67 73 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53  ags: ", Tcl_GetS
8760: 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20  tring(objv[2]), 
8770: 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  0);.            
8780: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
8790: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
87a0: 20 20 20 20 20 20 20 20 69 4e 65 77 20 7c 3d 20          iNew |= 
87b0: 61 46 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75  aFlag[idx].iValu
87c0: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  e;.        }..  
87d0: 20 20 20 20 20 20 70 2d 3e 69 44 65 76 63 68 61        p->iDevcha
87e0: 72 20 3d 20 69 4e 65 77 3b 0a 20 20 20 20 20 20  r = iNew;.      
87f0: 7d 0a 0a 20 20 20 20 20 20 70 52 65 74 20 3d 20  }..      pRet = 
8800: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
8810: 20 20 20 20 66 6f 72 28 69 46 6c 61 67 3d 30 3b      for(iFlag=0;
8820: 20 69 46 6c 61 67 3c 73 69 7a 65 6f 66 28 61 46   iFlag<sizeof(aF
8830: 6c 61 67 29 2f 73 69 7a 65 6f 66 28 61 46 6c 61  lag)/sizeof(aFla
8840: 67 5b 30 5d 29 3b 20 69 46 6c 61 67 2b 2b 29 7b  g[0]); iFlag++){
8850: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e  .        if( p->
8860: 69 44 65 76 63 68 61 72 20 26 20 61 46 6c 61 67  iDevchar & aFlag
8870: 5b 69 46 6c 61 67 5d 2e 69 56 61 6c 75 65 20 29  [iFlag].iValue )
8880: 7b 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f  {.          Tcl_
8890: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
88a0: 6d 65 6e 74 28 0a 20 20 20 20 20 20 20 20 20 20  ment(.          
88b0: 20 20 20 20 69 6e 74 65 72 70 2c 20 70 52 65 74      interp, pRet
88c0: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
88d0: 62 6a 28 61 46 6c 61 67 5b 69 46 6c 61 67 5d 2e  bj(aFlag[iFlag].
88e0: 7a 4e 61 6d 65 2c 20 2d 31 29 0a 20 20 20 20 20  zName, -1).     
88f0: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20       );.        
8900: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
8910: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
8920: 28 69 6e 74 65 72 70 2c 20 70 52 65 74 29 3b 0a  (interp, pRet);.
8930: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
8940: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d    }..    case CM
8950: 44 5f 53 45 43 54 4f 52 53 49 5a 45 3a 20 7b 0a  D_SECTORSIZE: {.
8960: 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3e 33        if( objc>3
8970: 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f   ){.        Tcl_
8980: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
8990: 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f  erp, 2, objv, "?
89a0: 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20 20  VALUE?");.      
89b0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
89c0: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
89d0: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
89e0: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65  .        int iNe
89f0: 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  w = 0;.        i
8a00: 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  f( Tcl_GetIntFro
8a10: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
8a20: 76 5b 32 5d 2c 20 26 69 4e 65 77 29 20 29 7b 0a  v[2], &iNew) ){.
8a30: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
8a40: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
8a50: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 2d      }.        p-
8a60: 3e 69 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 69  >iSectorsize = i
8a70: 4e 65 77 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  New;.      }.   
8a80: 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73     Tcl_SetObjRes
8a90: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
8aa0: 4e 65 77 49 6e 74 4f 62 6a 28 70 2d 3e 69 53 65  NewIntObj(p->iSe
8ab0: 63 74 6f 72 73 69 7a 65 29 29 3b 0a 20 20 20 20  ctorsize));.    
8ac0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
8ad0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c   }..  return TCL
8ae0: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  _OK;.}..static v
8af0: 6f 69 64 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f  oid testvfs_obj_
8b00: 64 65 6c 28 43 6c 69 65 6e 74 44 61 74 61 20 63  del(ClientData c
8b10: 64 29 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  d){.  Testvfs *p
8b20: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63 64   = (Testvfs *)cd
8b30: 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ;.  if( p->pScri
8b40: 70 74 20 29 20 54 63 6c 5f 44 65 63 72 52 65 66  pt ) Tcl_DecrRef
8b50: 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74  Count(p->pScript
8b60: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  );.  sqlite3_vfs
8b70: 5f 75 6e 72 65 67 69 73 74 65 72 28 70 2d 3e 70  _unregister(p->p
8b80: 56 66 73 29 3b 0a 20 20 63 6b 66 72 65 65 28 28  Vfs);.  ckfree((
8b90: 63 68 61 72 20 2a 29 70 2d 3e 61 70 53 63 72 69  char *)p->apScri
8ba0: 70 74 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63  pt);.  ckfree((c
8bb0: 68 61 72 20 2a 29 70 2d 3e 70 56 66 73 29 3b 0a  har *)p->pVfs);.
8bc0: 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a    ckfree((char *
8bd0: 29 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73  )p);.}../*.** Us
8be0: 61 67 65 3a 20 20 74 65 73 74 76 66 73 20 56 46  age:  testvfs VF
8bf0: 53 4e 41 4d 45 20 3f 53 57 49 54 43 48 45 53 3f  SNAME ?SWITCHES?
8c00: 0a 2a 2a 0a 2a 2a 20 53 77 69 74 63 68 65 73 20  .**.** Switches 
8c10: 61 72 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e 6f  are:.**.**   -no
8c20: 73 68 6d 20 20 20 42 4f 4f 4c 45 41 4e 20 20 20  shm   BOOLEAN   
8c30: 20 20 20 20 20 20 20 20 20 20 28 54 72 75 65 20            (True 
8c40: 74 6f 20 6f 6d 69 74 20 73 68 6d 20 6d 65 74 68  to omit shm meth
8c50: 6f 64 73 2e 20 44 65 66 61 75 6c 74 20 66 61 6c  ods. Default fal
8c60: 73 65 29 0a 2a 2a 20 20 20 2d 64 65 66 61 75 6c  se).**   -defaul
8c70: 74 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20  t BOOLEAN       
8c80: 20 20 20 20 20 20 28 54 72 75 65 20 74 6f 20 6d        (True to m
8c90: 61 6b 65 20 74 68 65 20 76 66 73 20 64 65 66 61  ake the vfs defa
8ca0: 75 6c 74 2e 20 44 65 66 61 75 6c 74 20 66 61 6c  ult. Default fal
8cb0: 73 65 29 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63  se).**.** This c
8cc0: 6f 6d 6d 61 6e 64 20 63 72 65 61 74 65 73 20 74  ommand creates t
8cd0: 77 6f 20 74 68 69 6e 67 73 20 77 68 65 6e 20 69  wo things when i
8ce0: 74 20 69 73 20 69 6e 76 6f 6b 65 64 3a 20 61 6e  t is invoked: an
8cf0: 20 53 51 4c 69 74 65 20 56 46 53 2c 20 61 6e 64   SQLite VFS, and
8d00: 0a 2a 2a 20 61 20 54 63 6c 20 63 6f 6d 6d 61 6e  .** a Tcl comman
8d10: 64 2e 20 42 6f 74 68 20 61 72 65 20 6e 61 6d 65  d. Both are name
8d20: 64 20 56 46 53 4e 41 4d 45 2e 20 54 68 65 20 56  d VFSNAME. The V
8d30: 46 53 20 69 73 20 69 6e 73 74 61 6c 6c 65 64 2e  FS is installed.
8d40: 20 49 74 20 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e   It is not.** in
8d50: 73 74 61 6c 6c 65 64 20 61 73 20 74 68 65 20 64  stalled as the d
8d60: 65 66 61 75 6c 74 20 56 46 53 2e 0a 2a 2a 0a 2a  efault VFS..**.*
8d70: 2a 20 54 68 65 20 56 46 53 20 70 61 73 73 65 73  * The VFS passes
8d80: 20 61 6c 6c 20 66 69 6c 65 20 49 2f 4f 20 63 61   all file I/O ca
8d90: 6c 6c 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  lls through to t
8da0: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 56 46  he underlying VF
8db0: 53 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 65 76 65  S..**.** Wheneve
8dc0: 72 20 74 68 65 20 78 53 68 6d 4d 61 70 20 6d 65  r the xShmMap me
8dd0: 74 68 6f 64 20 6f 66 20 74 68 65 20 56 46 53 0a  thod of the VFS.
8de0: 2a 2a 20 69 73 20 69 6e 76 6f 6b 65 64 2c 20 74  ** is invoked, t
8df0: 68 65 20 53 43 52 49 50 54 20 69 73 20 65 78 65  he SCRIPT is exe
8e00: 63 75 74 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73  cuted as follows
8e10: 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50 54  :.**.**   SCRIPT
8e20: 20 78 53 68 6d 4d 61 70 20 20 20 20 46 49 4c 45   xShmMap    FILE
8e30: 4e 41 4d 45 20 49 44 0a 2a 2a 0a 2a 2a 20 54 68  NAME ID.**.** Th
8e40: 65 20 76 61 6c 75 65 20 72 65 74 75 72 6e 65 64  e value returned
8e50: 20 62 79 20 74 68 65 20 69 6e 76 6f 63 61 74 69   by the invocati
8e60: 6f 6e 20 6f 66 20 53 43 52 49 50 54 20 61 62 6f  on of SCRIPT abo
8e70: 76 65 20 69 73 20 69 6e 74 65 72 70 72 65 74 65  ve is interprete
8e80: 64 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 69 74  d as.** an SQLit
8e90: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 61 6e 64  e error code and
8ea0: 20 72 65 74 75 72 6e 65 64 20 74 6f 20 53 51 4c   returned to SQL
8eb0: 69 74 65 2e 20 45 69 74 68 65 72 20 61 20 73 79  ite. Either a sy
8ec0: 6d 62 6f 6c 69 63 20 0a 2a 2a 20 22 53 51 4c 49  mbolic .** "SQLI
8ed0: 54 45 5f 4f 4b 22 20 6f 72 20 6e 75 6d 65 72 69  TE_OK" or numeri
8ee0: 63 20 22 30 22 20 76 61 6c 75 65 20 6d 61 79 20  c "0" value may 
8ef0: 62 65 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  be returned..**.
8f00: 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20  ** The contents 
8f10: 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65  of the shared-me
8f20: 6d 6f 72 79 20 62 75 66 66 65 72 20 61 73 73 6f  mory buffer asso
8f30: 63 69 61 74 65 64 20 77 69 74 68 20 61 20 67 69  ciated with a gi
8f40: 76 65 6e 20 66 69 6c 65 0a 2a 2a 20 6d 61 79 20  ven file.** may 
8f50: 62 65 20 72 65 61 64 20 61 6e 64 20 73 65 74 20  be read and set 
8f60: 75 73 69 6e 67 20 74 68 65 20 66 6f 6c 6c 6f 77  using the follow
8f70: 69 6e 67 20 63 6f 6d 6d 61 6e 64 3a 0a 2a 2a 0a  ing command:.**.
8f80: 2a 2a 20 20 20 56 46 53 4e 41 4d 45 20 73 68 6d  **   VFSNAME shm
8f90: 20 46 49 4c 45 4e 41 4d 45 20 3f 4e 45 57 56 41   FILENAME ?NEWVA
8fa0: 4c 55 45 3f 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20  LUE?.**.** When 
8fb0: 74 68 65 20 78 53 68 6d 4c 6f 63 6b 20 6d 65 74  the xShmLock met
8fc0: 68 6f 64 20 69 73 20 69 6e 76 6f 6b 65 64 20 62  hod is invoked b
8fd0: 79 20 53 51 4c 69 74 65 2c 20 74 68 65 20 66 6f  y SQLite, the fo
8fe0: 6c 6c 6f 77 69 6e 67 20 73 63 72 69 70 74 20 69  llowing script i
8ff0: 73 0a 2a 2a 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20  s.** run:.**.** 
9000: 20 20 53 43 52 49 50 54 20 78 53 68 6d 4c 6f 63    SCRIPT xShmLoc
9010: 6b 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49 44  k    FILENAME ID
9020: 20 4c 4f 43 4b 0a 2a 2a 0a 2a 2a 20 77 68 65 72   LOCK.**.** wher
9030: 65 20 4c 4f 43 4b 20 69 73 20 6f 66 20 74 68 65  e LOCK is of the
9040: 20 66 6f 72 6d 20 22 4f 46 46 53 45 54 20 4e 42   form "OFFSET NB
9050: 59 54 45 20 6c 6f 63 6b 2f 75 6e 6c 6f 63 6b 20  YTE lock/unlock 
9060: 73 68 61 72 65 64 2f 65 78 63 6c 75 73 69 76 65  shared/exclusive
9070: 22 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ".*/.static int 
9080: 74 65 73 74 76 66 73 5f 63 6d 64 28 0a 20 20 43  testvfs_cmd(.  C
9090: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a 20 20  lientData cd,.  
90a0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
90b0: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
90c0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
90d0: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 73 74 61   objv[].){.  sta
90e0: 74 69 63 20 73 71 6c 69 74 65 33 5f 76 66 73 20  tic sqlite3_vfs 
90f0: 74 76 66 73 5f 76 66 73 20 3d 20 7b 0a 20 20 20  tvfs_vfs = {.   
9100: 20 32 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   2,             
9110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9120: 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20  * iVersion */.  
9130: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
9140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9150: 2f 2a 20 73 7a 4f 73 46 69 6c 65 20 2a 2f 0a 20  /* szOsFile */. 
9160: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
9170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9180: 20 2f 2a 20 6d 78 50 61 74 68 6e 61 6d 65 20 2a   /* mxPathname *
9190: 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  /.    0,        
91a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91b0: 20 20 20 20 2f 2a 20 70 4e 65 78 74 20 2a 2f 0a      /* pNext */.
91c0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
91d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91e0: 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20    /* zName */.  
91f0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
9200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9210: 2f 2a 20 70 41 70 70 44 61 74 61 20 2a 2f 0a 20  /* pAppData */. 
9220: 20 20 20 74 76 66 73 4f 70 65 6e 2c 20 20 20 20     tvfsOpen,    
9230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9240: 20 2f 2a 20 78 4f 70 65 6e 20 2a 2f 0a 20 20 20   /* xOpen */.   
9250: 20 74 76 66 73 44 65 6c 65 74 65 2c 20 20 20 20   tvfsDelete,    
9260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9270: 2a 20 78 44 65 6c 65 74 65 20 2a 2f 0a 20 20 20  * xDelete */.   
9280: 20 74 76 66 73 41 63 63 65 73 73 2c 20 20 20 20   tvfsAccess,    
9290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
92a0: 2a 20 78 41 63 63 65 73 73 20 2a 2f 0a 20 20 20  * xAccess */.   
92b0: 20 74 76 66 73 46 75 6c 6c 50 61 74 68 6e 61 6d   tvfsFullPathnam
92c0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  e,             /
92d0: 2a 20 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 20  * xFullPathname 
92e0: 2a 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  */.#ifndef SQLIT
92f0: 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45  E_OMIT_LOAD_EXTE
9300: 4e 53 49 4f 4e 0a 20 20 20 20 74 76 66 73 44 6c  NSION.    tvfsDl
9310: 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20  Open,           
9320: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 4f 70          /* xDlOp
9330: 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c  en */.    tvfsDl
9340: 45 72 72 6f 72 2c 20 20 20 20 20 20 20 20 20 20  Error,          
9350: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 45 72          /* xDlEr
9360: 72 6f 72 20 2a 2f 0a 20 20 20 20 74 76 66 73 44  ror */.    tvfsD
9370: 6c 53 79 6d 2c 20 20 20 20 20 20 20 20 20 20 20  lSym,           
9380: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 53           /* xDlS
9390: 79 6d 20 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c  ym */.    tvfsDl
93a0: 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20  Close,          
93b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c          /* xDlCl
93c0: 6f 73 65 20 2a 2f 0a 23 65 6c 73 65 0a 20 20 20  ose */.#else.   
93d0: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
93e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
93f0: 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20 20  * xDlOpen */.   
9400: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
9410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9420: 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f 0a 20 20  * xDlError */.  
9430: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
9440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9450: 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20 20 20  /* xDlSym */.   
9460: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
9470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9480: 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a 23 65  * xDlClose */.#e
9490: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4f  ndif /* SQLITE_O
94a0: 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49  MIT_LOAD_EXTENSI
94b0: 4f 4e 20 2a 2f 0a 20 20 20 20 74 76 66 73 52 61  ON */.    tvfsRa
94c0: 6e 64 6f 6d 6e 65 73 73 2c 20 20 20 20 20 20 20  ndomness,       
94d0: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 61 6e 64          /* xRand
94e0: 6f 6d 6e 65 73 73 20 2a 2f 0a 20 20 20 20 74 76  omness */.    tv
94f0: 66 73 53 6c 65 65 70 2c 20 20 20 20 20 20 20 20  fsSleep,        
9500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9510: 53 6c 65 65 70 20 2a 2f 0a 20 20 20 20 74 76 66  Sleep */.    tvf
9520: 73 43 75 72 72 65 6e 74 54 69 6d 65 2c 20 20 20  sCurrentTime,   
9530: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
9540: 75 72 72 65 6e 74 54 69 6d 65 20 2a 2f 0a 20 20  urrentTime */.  
9550: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
9560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9570: 2f 2a 20 78 47 65 74 4c 61 73 74 45 72 72 6f 72  /* xGetLastError
9580: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
9590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
95a0: 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e        /* xCurren
95b0: 74 54 69 6d 65 49 6e 74 36 34 20 2a 2f 0a 20 20  tTimeInt64 */.  
95c0: 7d 3b 0a 0a 20 20 54 65 73 74 76 66 73 20 2a 70  };..  Testvfs *p
95d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
95e0: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6f 62 6a        /* New obj
95f0: 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ect */.  sqlite3
9600: 5f 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20  _vfs *pVfs;     
9610: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20           /* New 
9620: 56 46 53 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  VFS */.  char *z
9630: 56 66 73 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65  Vfs;.  int nByte
9640: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9650: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
9660: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
9670: 63 61 74 65 20 61 74 20 70 20 2a 2f 0a 0a 20 20  cate at p */..  
9680: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 73 4e  int i;.  int isN
9690: 6f 73 68 6d 20 3d 20 30 3b 20 20 20 20 20 20 20  oshm = 0;       
96a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
96b0: 20 69 66 20 2d 6e 6f 73 68 6d 20 69 73 20 70 61   if -noshm is pa
96c0: 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69 73  ssed */.  int is
96d0: 44 65 66 61 75 6c 74 20 3d 20 30 3b 20 20 20 20  Default = 0;    
96e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
96f0: 65 20 69 66 20 2d 64 65 66 61 75 6c 74 20 69 73  e if -default is
9700: 20 70 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74   passed */.  int
9710: 20 73 7a 4f 73 46 69 6c 65 20 3d 20 30 3b 20 20   szOsFile = 0;  
9720: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9730: 56 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f 20  Value passed to 
9740: 2d 73 7a 6f 73 66 69 6c 65 20 2a 2f 0a 20 20 69  -szosfile */.  i
9750: 6e 74 20 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20  nt mxPathname = 
9760: 2d 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  -1;            /
9770: 2a 20 56 61 6c 75 65 20 70 61 73 73 65 64 20 74  * Value passed t
9780: 6f 20 2d 6d 78 70 61 74 68 6e 61 6d 65 20 2a 2f  o -mxpathname */
9790: 0a 20 20 69 6e 74 20 69 56 65 72 73 69 6f 6e 20  .  int iVersion 
97a0: 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 2;            
97b0: 20 20 20 2f 2a 20 56 61 6c 75 65 20 70 61 73 73     /* Value pass
97c0: 65 64 20 74 6f 20 2d 69 76 65 72 73 69 6f 6e 20  ed to -iversion 
97d0: 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32  */..  if( objc<2
97e0: 20 7c 7c 20 30 21 3d 28 6f 62 6a 63 25 32 29 20   || 0!=(objc%2) 
97f0: 29 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b  ) goto bad_args;
9800: 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6f 62  .  for(i=2; i<ob
9810: 6a 63 3b 20 69 20 2b 3d 20 32 29 7b 0a 20 20 20  jc; i += 2){.   
9820: 20 69 6e 74 20 6e 53 77 69 74 63 68 3b 0a 20 20   int nSwitch;.  
9830: 20 20 63 68 61 72 20 2a 7a 53 77 69 74 63 68 3b    char *zSwitch;
9840: 0a 20 20 20 20 7a 53 77 69 74 63 68 20 3d 20 54  .    zSwitch = T
9850: 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d  cl_GetStringFrom
9860: 4f 62 6a 28 6f 62 6a 76 5b 69 5d 2c 20 26 6e 53  Obj(objv[i], &nS
9870: 77 69 74 63 68 29 3b 20 0a 0a 20 20 20 20 69 66  witch); ..    if
9880: 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30  ( nSwitch>2 && 0
9890: 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 6e 6f 73 68  ==strncmp("-nosh
98a0: 6d 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77  m", zSwitch, nSw
98b0: 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69  itch) ){.      i
98c0: 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61  f( Tcl_GetBoolea
98d0: 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  nFromObj(interp,
98e0: 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 4e   objv[i+1], &isN
98f0: 6f 73 68 6d 29 20 29 7b 0a 20 20 20 20 20 20 20  oshm) ){.       
9900: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
9910: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  R;.      }.    }
9920: 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53  .    else if( nS
9930: 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74  witch>2 && 0==st
9940: 72 6e 63 6d 70 28 22 2d 64 65 66 61 75 6c 74 22  rncmp("-default"
9950: 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74  , zSwitch, nSwit
9960: 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ch) ){.      if(
9970: 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46   Tcl_GetBooleanF
9980: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
9990: 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 44 65 66  bjv[i+1], &isDef
99a0: 61 75 6c 74 29 20 29 7b 0a 20 20 20 20 20 20 20  ault) ){.       
99b0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
99c0: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  R;.      }.    }
99d0: 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53  .    else if( nS
99e0: 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74  witch>2 && 0==st
99f0: 72 6e 63 6d 70 28 22 2d 73 7a 6f 73 66 69 6c 65  rncmp("-szosfile
9a00: 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69  ", zSwitch, nSwi
9a10: 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66  tch) ){.      if
9a20: 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d  ( Tcl_GetIntFrom
9a30: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
9a40: 5b 69 2b 31 5d 2c 20 26 73 7a 4f 73 46 69 6c 65  [i+1], &szOsFile
9a50: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  ) ){.        ret
9a60: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
9a70: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
9a80: 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63   else if( nSwitc
9a90: 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d  h>2 && 0==strncm
9aa0: 70 28 22 2d 6d 78 70 61 74 68 6e 61 6d 65 22 2c  p("-mxpathname",
9ab0: 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63   zSwitch, nSwitc
9ac0: 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  h) ){.      if( 
9ad0: 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62  Tcl_GetIntFromOb
9ae0: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69  j(interp, objv[i
9af0: 2b 31 5d 2c 20 26 6d 78 50 61 74 68 6e 61 6d 65  +1], &mxPathname
9b00: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  ) ){.        ret
9b10: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
9b20: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
9b30: 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63   else if( nSwitc
9b40: 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d  h>2 && 0==strncm
9b50: 70 28 22 2d 69 76 65 72 73 69 6f 6e 22 2c 20 7a  p("-iversion", z
9b60: 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29  Switch, nSwitch)
9b70: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63   ){.      if( Tc
9b80: 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28  l_GetIntFromObj(
9b90: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31  interp, objv[i+1
9ba0: 5d 2c 20 26 69 56 65 72 73 69 6f 6e 29 20 29 7b  ], &iVersion) ){
9bb0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
9bc0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
9bd0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73   }.    }.    els
9be0: 65 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 62 61  e{.      goto ba
9bf0: 64 5f 61 72 67 73 3b 0a 20 20 20 20 7d 0a 20 20  d_args;.    }.  
9c00: 7d 0a 0a 20 20 69 66 28 20 73 7a 4f 73 46 69 6c  }..  if( szOsFil
9c10: 65 3c 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  e<sizeof(Testvfs
9c20: 46 69 6c 65 29 20 29 7b 0a 20 20 20 20 73 7a 4f  File) ){.    szO
9c30: 73 46 69 6c 65 20 3d 20 73 69 7a 65 6f 66 28 54  sFile = sizeof(T
9c40: 65 73 74 76 66 73 46 69 6c 65 29 3b 0a 20 20 7d  estvfsFile);.  }
9c50: 0a 0a 20 20 7a 56 66 73 20 3d 20 54 63 6c 5f 47  ..  zVfs = Tcl_G
9c60: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
9c70: 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a  );.  nByte = siz
9c80: 65 6f 66 28 54 65 73 74 76 66 73 29 20 2b 20 73  eof(Testvfs) + s
9c90: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 3b 0a 20  trlen(zVfs)+1;. 
9ca0: 20 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29   p = (Testvfs *)
9cb0: 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  ckalloc(nByte);.
9cc0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e    memset(p, 0, n
9cd0: 42 79 74 65 29 3b 0a 20 20 70 2d 3e 69 44 65 76  Byte);.  p->iDev
9ce0: 63 68 61 72 20 3d 20 2d 31 3b 0a 20 20 70 2d 3e  char = -1;.  p->
9cf0: 69 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 2d 31  iSectorsize = -1
9d00: 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20 74  ;..  /* Create t
9d10: 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 63 6f  he new object co
9d20: 6d 6d 61 6e 64 20 62 65 66 6f 72 65 20 71 75 65  mmand before que
9d30: 72 79 69 6e 67 20 53 51 4c 69 74 65 20 66 6f 72  rying SQLite for
9d40: 20 61 20 64 65 66 61 75 6c 74 20 56 46 53 0a 20   a default VFS. 
9d50: 20 2a 2a 20 74 6f 20 75 73 65 20 66 6f 72 20 27   ** to use for '
9d60: 72 65 61 6c 27 20 49 4f 20 6f 70 65 72 61 74 69  real' IO operati
9d70: 6f 6e 73 2e 20 54 68 69 73 20 69 73 20 62 65 63  ons. This is bec
9d80: 61 75 73 65 20 63 72 65 61 74 69 6e 67 20 74 68  ause creating th
9d90: 65 20 6e 65 77 20 56 46 53 0a 20 20 2a 2a 20 6d  e new VFS.  ** m
9da0: 61 79 20 64 65 6c 65 74 65 20 61 6e 20 65 78 69  ay delete an exi
9db0: 73 74 69 6e 67 20 5b 74 65 73 74 76 66 73 5d 20  sting [testvfs] 
9dc0: 56 46 53 20 6f 66 20 74 68 65 20 73 61 6d 65 20  VFS of the same 
9dd0: 6e 61 6d 65 2e 20 49 66 20 73 75 63 68 20 61 20  name. If such a 
9de0: 56 46 53 0a 20 20 2a 2a 20 69 73 20 63 75 72 72  VFS.  ** is curr
9df0: 65 6e 74 6c 79 20 74 68 65 20 64 65 66 61 75 6c  ently the defaul
9e00: 74 2c 20 74 68 65 20 6e 65 77 20 5b 74 65 73 74  t, the new [test
9e10: 76 66 73 5d 20 6d 61 79 20 65 6e 64 20 75 70 20  vfs] may end up 
9e20: 63 61 6c 6c 69 6e 67 20 74 68 65 20 0a 20 20 2a  calling the .  *
9e30: 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 61 20 64  * methods of a d
9e40: 65 6c 65 74 65 64 20 6f 62 6a 65 63 74 2e 0a 20  eleted object.. 
9e50: 20 2a 2f 0a 20 20 54 63 6c 5f 43 72 65 61 74 65   */.  Tcl_Create
9e60: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
9e70: 70 2c 20 7a 56 66 73 2c 20 74 65 73 74 76 66 73  p, zVfs, testvfs
9e80: 5f 6f 62 6a 5f 63 6d 64 2c 20 70 2c 20 74 65 73  _obj_cmd, p, tes
9e90: 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 29 3b 0a 20  tvfs_obj_del);. 
9ea0: 20 70 2d 3e 70 50 61 72 65 6e 74 20 3d 20 73 71   p->pParent = sq
9eb0: 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30  lite3_vfs_find(0
9ec0: 29 3b 0a 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d  );.  p->interp =
9ed0: 20 69 6e 74 65 72 70 3b 0a 0a 20 20 70 2d 3e 7a   interp;..  p->z
9ee0: 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29 26  Name = (char *)&
9ef0: 70 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70  p[1];.  memcpy(p
9f00: 2d 3e 7a 4e 61 6d 65 2c 20 7a 56 66 73 2c 20 73  ->zName, zVfs, s
9f10: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 29 3b 0a  trlen(zVfs)+1);.
9f20: 0a 20 20 70 56 66 73 20 3d 20 28 73 71 6c 69 74  .  pVfs = (sqlit
9f30: 65 33 5f 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63  e3_vfs *)ckalloc
9f40: 28 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f  (sizeof(sqlite3_
9f50: 76 66 73 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28  vfs));.  memcpy(
9f60: 70 56 66 73 2c 20 26 74 76 66 73 5f 76 66 73 2c  pVfs, &tvfs_vfs,
9f70: 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f   sizeof(sqlite3_
9f80: 76 66 73 29 29 3b 0a 20 20 70 56 66 73 2d 3e 70  vfs));.  pVfs->p
9f90: 41 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20  AppData = (void 
9fa0: 2a 29 70 3b 0a 20 20 70 56 66 73 2d 3e 69 56 65  *)p;.  pVfs->iVe
9fb0: 72 73 69 6f 6e 20 3d 20 69 56 65 72 73 69 6f 6e  rsion = iVersion
9fc0: 3b 0a 20 20 70 56 66 73 2d 3e 7a 4e 61 6d 65 20  ;.  pVfs->zName 
9fd0: 3d 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 70 56  = p->zName;.  pV
9fe0: 66 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d  fs->mxPathname =
9ff0: 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50   p->pParent->mxP
a000: 61 74 68 6e 61 6d 65 3b 0a 20 20 69 66 28 20 6d  athname;.  if( m
a010: 78 50 61 74 68 6e 61 6d 65 3e 3d 30 20 26 26 20  xPathname>=0 && 
a020: 6d 78 50 61 74 68 6e 61 6d 65 3c 70 56 66 73 2d  mxPathname<pVfs-
a030: 3e 6d 78 50 61 74 68 6e 61 6d 65 20 29 7b 0a 20  >mxPathname ){. 
a040: 20 20 20 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e     pVfs->mxPathn
a050: 61 6d 65 20 3d 20 6d 78 50 61 74 68 6e 61 6d 65  ame = mxPathname
a060: 3b 0a 20 20 7d 0a 20 20 70 56 66 73 2d 3e 73 7a  ;.  }.  pVfs->sz
a070: 4f 73 46 69 6c 65 20 3d 20 73 7a 4f 73 46 69 6c  OsFile = szOsFil
a080: 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20 3d 20 70  e;.  p->pVfs = p
a090: 56 66 73 3b 0a 20 20 70 2d 3e 69 73 4e 6f 73 68  Vfs;.  p->isNosh
a0a0: 6d 20 3d 20 69 73 4e 6f 73 68 6d 3b 0a 20 20 70  m = isNoshm;.  p
a0b0: 2d 3e 6d 61 73 6b 20 3d 20 54 45 53 54 56 46 53  ->mask = TESTVFS
a0c0: 5f 41 4c 4c 5f 4d 41 53 4b 3b 0a 0a 20 20 73 71  _ALL_MASK;..  sq
a0d0: 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74  lite3_vfs_regist
a0e0: 65 72 28 70 56 66 73 2c 20 69 73 44 65 66 61 75  er(pVfs, isDefau
a0f0: 6c 74 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 54  lt);..  return T
a100: 43 4c 5f 4f 4b 3b 0a 0a 20 62 61 64 5f 61 72 67  CL_OK;.. bad_arg
a110: 73 3a 0a 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  s:.  Tcl_WrongNu
a120: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
a130: 20 6f 62 6a 76 2c 20 22 56 46 53 4e 41 4d 45 20   objv, "VFSNAME 
a140: 3f 2d 6e 6f 73 68 6d 20 42 4f 4f 4c 3f 20 3f 2d  ?-noshm BOOL? ?-
a150: 64 65 66 61 75 6c 74 20 42 4f 4f 4c 3f 20 3f 2d  default BOOL? ?-
a160: 6d 78 70 61 74 68 6e 61 6d 65 20 49 4e 54 3f 20  mxpathname INT? 
a170: 3f 2d 73 7a 6f 73 66 69 6c 65 20 49 4e 54 3f 20  ?-szosfile INT? 
a180: 3f 2d 69 76 65 72 73 69 6f 6e 20 49 4e 54 3f 22  ?-iversion INT?"
a190: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
a1a0: 45 52 52 4f 52 3b 0a 7d 0a 0a 69 6e 74 20 53 71  ERROR;.}..int Sq
a1b0: 6c 69 74 65 74 65 73 74 76 66 73 5f 49 6e 69 74  litetestvfs_Init
a1c0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
a1d0: 65 72 70 29 7b 0a 20 20 54 63 6c 5f 43 72 65 61  erp){.  Tcl_Crea
a1e0: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
a1f0: 65 72 70 2c 20 22 74 65 73 74 76 66 73 22 2c 20  erp, "testvfs", 
a200: 74 65 73 74 76 66 73 5f 63 6d 64 2c 20 30 2c 20  testvfs_cmd, 0, 
a210: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  0);.  return TCL
a220: 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a     _OK;.}..#endif.