/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 01d5732a8dbdc3f6b75d4ec79aeb9455942243a0:


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 54 65 73 74 76 66 73 42 75  e */.  TestvfsBu
0bb0: 66 66 65 72 20 2a 70 42 75 66 66 65 72 3b 20 20  ffer *pBuffer;  
0bc0: 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f         /* List o
0bd0: 66 20 73 68 61 72 65 64 20 62 75 66 66 65 72 73  f shared buffers
0be0: 20 2a 2f 0a 20 20 69 6e 74 20 69 73 4e 6f 73 68   */.  int isNosh
0bf0: 6d 3b 0a 0a 20 20 69 6e 74 20 6d 61 73 6b 3b 20  m;..  int mask; 
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c10: 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b 20 63 6f        /* Mask co
0c20: 6e 74 72 6f 6c 6c 69 6e 67 20 5b 73 63 72 69 70  ntrolling [scrip
0c30: 74 5d 20 61 6e 64 20 5b 69 6f 65 72 72 5d 20 2a  t] and [ioerr] *
0c40: 2f 0a 0a 20 20 54 65 73 74 46 61 75 6c 74 49 6e  /..  TestFaultIn
0c50: 6a 65 63 74 20 69 6f 65 72 72 5f 65 72 72 3b 0a  ject ioerr_err;.
0c60: 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63    TestFaultInjec
0c70: 74 20 66 75 6c 6c 5f 65 72 72 3b 0a 20 20 54 65  t full_err;.  Te
0c80: 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 63 61  stFaultInject ca
0c90: 6e 74 6f 70 65 6e 5f 65 72 72 3b 0a 0a 23 69 66  ntopen_err;..#if
0ca0: 20 30 0a 20 20 69 6e 74 20 69 49 6f 65 72 72 43   0.  int iIoerrC
0cb0: 6e 74 3b 0a 20 20 69 6e 74 20 69 6f 65 72 72 3b  nt;.  int ioerr;
0cc0: 0a 20 20 69 6e 74 20 6e 49 6f 65 72 72 46 61 69  .  int nIoerrFai
0cd0: 6c 3b 0a 20 20 69 6e 74 20 69 46 75 6c 6c 43 6e  l;.  int iFullCn
0ce0: 74 3b 0a 20 20 69 6e 74 20 66 75 6c 6c 65 72 72  t;.  int fullerr
0cf0: 3b 0a 20 20 69 6e 74 20 6e 46 75 6c 6c 46 61 69  ;.  int nFullFai
0d00: 6c 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 69 6e 74  l;.#endif..  int
0d10: 20 69 44 65 76 63 68 61 72 3b 0a 20 20 69 6e 74   iDevchar;.  int
0d20: 20 69 53 65 63 74 6f 72 73 69 7a 65 3b 0a 7d 3b   iSectorsize;.};
0d30: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 54 65 73 74  ../*.** The Test
0d40: 76 66 73 2e 6d 61 73 6b 20 76 61 72 69 61 62 6c  vfs.mask variabl
0d50: 65 20 69 73 20 73 65 74 20 74 6f 20 61 20 63 6f  e is set to a co
0d60: 6d 62 69 6e 61 74 69 6f 6e 20 6f 66 20 74 68 65  mbination of the
0d70: 20 66 6f 6c 6c 6f 77 69 6e 67 2e 0a 2a 2a 20 49   following..** I
0d80: 66 20 61 20 62 69 74 20 69 73 20 63 6c 65 61 72  f a bit is clear
0d90: 20 69 6e 20 54 65 73 74 76 66 73 2e 6d 61 73 6b   in Testvfs.mask
0da0: 2c 20 74 68 65 6e 20 63 61 6c 6c 73 20 6d 61 64  , then calls mad
0db0: 65 20 62 79 20 53 51 4c 69 74 65 20 74 6f 20 74  e by SQLite to t
0dc0: 68 65 20 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e  he .** correspon
0dd0: 64 69 6e 67 20 56 46 53 20 6d 65 74 68 6f 64 20  ding VFS method 
0de0: 69 73 20 69 67 6e 6f 72 65 64 20 66 6f 72 20 70  is ignored for p
0df0: 75 72 70 6f 73 65 73 20 6f 66 3a 0a 2a 2a 0a 2a  urposes of:.**.*
0e00: 2a 20 20 20 2b 20 53 69 6d 75 6c 61 74 69 6e 67  *   + Simulating
0e10: 20 49 4f 20 65 72 72 6f 72 73 2c 20 61 6e 64 0a   IO errors, and.
0e20: 2a 2a 20 20 20 2b 20 49 6e 76 6f 6b 69 6e 67 20  **   + Invoking 
0e30: 74 68 65 20 54 63 6c 20 63 61 6c 6c 62 61 63 6b  the Tcl callback
0e40: 20 73 63 72 69 70 74 2e 0a 2a 2f 0a 23 64 65 66   script..*/.#def
0e50: 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d 4f  ine TESTVFS_SHMO
0e60: 50 45 4e 5f 4d 41 53 4b 20 20 20 20 20 20 30 78  PEN_MASK      0x
0e70: 30 30 30 30 30 30 30 31 0a 23 64 65 66 69 6e 65  00000001.#define
0e80: 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b   TESTVFS_SHMLOCK
0e90: 5f 4d 41 53 4b 20 20 20 20 20 20 30 78 30 30 30  _MASK      0x000
0ea0: 30 30 30 31 30 0a 23 64 65 66 69 6e 65 20 54 45  00010.#define TE
0eb0: 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53  STVFS_SHMMAP_MAS
0ec0: 4b 20 20 20 20 20 20 20 30 78 30 30 30 30 30 30  K       0x000000
0ed0: 32 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  20.#define TESTV
0ee0: 46 53 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41  FS_SHMBARRIER_MA
0ef0: 53 4b 20 20 20 30 78 30 30 30 30 30 30 34 30 0a  SK   0x00000040.
0f00: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
0f10: 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 20 20  SHMCLOSE_MASK   
0f20: 20 20 30 78 30 30 30 30 30 30 38 30 0a 0a 23 64    0x00000080..#d
0f30: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 4f 50  efine TESTVFS_OP
0f40: 45 4e 5f 4d 41 53 4b 20 20 20 20 20 20 20 20 20  EN_MASK         
0f50: 30 78 30 30 30 30 30 31 30 30 0a 23 64 65 66 69  0x00000100.#defi
0f60: 6e 65 20 54 45 53 54 56 46 53 5f 53 59 4e 43 5f  ne TESTVFS_SYNC_
0f70: 4d 41 53 4b 20 20 20 20 20 20 20 20 20 30 78 30  MASK         0x0
0f80: 30 30 30 30 32 30 30 0a 23 64 65 66 69 6e 65 20  0000200.#define 
0f90: 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d  TESTVFS_DELETE_M
0fa0: 41 53 4b 20 20 20 20 20 20 20 30 78 30 30 30 30  ASK       0x0000
0fb0: 30 34 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53  0400.#define TES
0fc0: 54 56 46 53 5f 43 4c 4f 53 45 5f 4d 41 53 4b 20  TVFS_CLOSE_MASK 
0fd0: 20 20 20 20 20 20 20 30 78 30 30 30 30 30 38 30         0x0000080
0fe0: 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  0.#define TESTVF
0ff0: 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 20 20 20  S_WRITE_MASK    
1000: 20 20 20 20 30 78 30 30 30 30 31 30 30 30 0a 23      0x00001000.#
1010: 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 54  define TESTVFS_T
1020: 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 20 20 20  RUNCATE_MASK    
1030: 20 30 78 30 30 30 30 32 30 30 30 0a 23 64 65 66   0x00002000.#def
1040: 69 6e 65 20 54 45 53 54 56 46 53 5f 41 43 43 45  ine TESTVFS_ACCE
1050: 53 53 5f 4d 41 53 4b 20 20 20 20 20 20 20 30 78  SS_MASK       0x
1060: 30 30 30 30 34 30 30 30 0a 23 64 65 66 69 6e 65  00004000.#define
1070: 20 54 45 53 54 56 46 53 5f 46 55 4c 4c 50 41 54   TESTVFS_FULLPAT
1080: 48 4e 41 4d 45 5f 4d 41 53 4b 20 30 78 30 30 30  HNAME_MASK 0x000
1090: 30 38 30 30 30 0a 23 64 65 66 69 6e 65 20 54 45  08000.#define TE
10a0: 53 54 56 46 53 5f 52 45 41 44 5f 4d 41 53 4b 20  STVFS_READ_MASK 
10b0: 20 20 20 20 20 20 20 20 30 78 30 30 30 31 30 30          0x000100
10c0: 30 30 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54  00..#define TEST
10d0: 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20 20 20 20  VFS_ALL_MASK    
10e0: 20 20 20 20 20 20 30 78 30 30 30 31 46 46 46 46        0x0001FFFF
10f0: 0a 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  ...#define TESTV
1100: 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 31 30 32  FS_MAX_PAGES 102
1110: 34 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72 65  4../*.** A share
1120: 64 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e  d-memory buffer.
1130: 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f 66   There is one of
1140: 20 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20 66   these objects f
1150: 6f 72 20 65 61 63 68 20 73 68 61 72 65 64 0a 2a  or each shared.*
1160: 2a 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20  * memory region 
1170: 6f 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74  opened by client
1180: 73 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e 74  s. If two client
1190: 73 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65 20  s open the same 
11a0: 66 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20 61  file,.** there a
11b0: 72 65 20 74 77 6f 20 54 65 73 74 76 66 73 46 69  re two TestvfsFi
11c0: 6c 65 20 73 74 72 75 63 74 75 72 65 73 20 62 75  le structures bu
11d0: 74 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74 76  t only one Testv
11e0: 66 73 42 75 66 66 65 72 20 73 74 72 75 63 74 75  fsBuffer structu
11f0: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65  re..*/.struct Te
1200: 73 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20 20  stvfsBuffer {.  
1210: 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20 20  char *zFile;    
1220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1230: 2f 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66 69  /* Associated fi
1240: 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74  le name */.  int
1250: 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20   pgsz;          
1260: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1270: 50 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 75  Page size */.  u
1280: 38 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46 53  8 *aPage[TESTVFS
1290: 5f 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20 2f  _MAX_PAGES];   /
12a0: 2a 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c 6c  * Array of ckall
12b0: 6f 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20 20  oc'd pages */.  
12c0: 54 65 73 74 76 66 73 46 64 20 2a 70 46 69 6c 65  TestvfsFd *pFile
12d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
12e0: 2f 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e 20  /* List of open 
12f0: 68 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65 73  handles */.  Tes
1300: 74 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65 78  tvfsBuffer *pNex
1310: 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t;           /* 
1320: 4e 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c  Next in linked l
1330: 69 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66 65  ist of all buffe
1340: 72 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69  rs */.};...#defi
1350: 6e 65 20 50 41 52 45 4e 54 56 46 53 28 78 29 20  ne PARENTVFS(x) 
1360: 28 28 28 54 65 73 74 76 66 73 20 2a 29 28 28 78  (((Testvfs *)((x
1370: 29 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e 70  )->pAppData))->p
1380: 50 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e 65  Parent)..#define
1390: 20 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52 47   TESTVFS_MAX_ARG
13a0: 53 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  S 12.../*.** Met
13b0: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
13c0: 20 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c 65   for TestvfsFile
13d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
13e0: 74 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65  tvfsClose(sqlite
13f0: 33 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63  3_file*);.static
1400: 20 69 6e 74 20 74 76 66 73 52 65 61 64 28 73 71   int tvfsRead(sq
1410: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f 69  lite3_file*, voi
1420: 64 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73 71  d*, int iAmt, sq
1430: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
1440: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
1450: 76 66 73 57 72 69 74 65 28 73 71 6c 69 74 65 33  vfsWrite(sqlite3
1460: 5f 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f 69  _file*,const voi
1470: 64 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c  d*,int iAmt, sql
1480: 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74  ite3_int64 iOfst
1490: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
14a0: 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74  fsTruncate(sqlit
14b0: 65 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74 65  e3_file*, sqlite
14c0: 33 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a 73  3_int64 size);.s
14d0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 79  tatic int tvfsSy
14e0: 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  nc(sqlite3_file*
14f0: 2c 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74  , int flags);.st
1500: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 69 6c  atic int tvfsFil
1510: 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69  eSize(sqlite3_fi
1520: 6c 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  le*, sqlite3_int
1530: 36 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61 74  64 *pSize);.stat
1540: 69 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28  ic int tvfsLock(
1550: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69  sqlite3_file*, i
1560: 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  nt);.static int 
1570: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
1580: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a  e3_file*, int);.
1590: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43  static int tvfsC
15a0: 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b  heckReservedLock
15b0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
15c0: 69 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69  int *);.static i
15d0: 6e 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72  nt tvfsFileContr
15e0: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  ol(sqlite3_file*
15f0: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
1600: 70 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69 6e  pArg);.static in
1610: 74 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65  t tvfsSectorSize
1620: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b  (sqlite3_file*);
1630: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
1640: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
1650: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
1660: 6c 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  le*);../*.** Met
1670: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
1680: 20 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a 2a   for tvfs_vfs..*
1690: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
16a0: 73 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66  sOpen(sqlite3_vf
16b0: 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  s*, const char *
16c0: 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  , sqlite3_file*,
16d0: 20 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73   int , int *);.s
16e0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65  tatic int tvfsDe
16f0: 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73  lete(sqlite3_vfs
1700: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  *, const char *z
1710: 4e 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69  Name, int syncDi
1720: 72 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  r);.static int t
1730: 76 66 73 41 63 63 65 73 73 28 73 71 6c 69 74 65  vfsAccess(sqlite
1740: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
1750: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66  ar *zName, int f
1760: 6c 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  lags, int *);.st
1770: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c  atic int tvfsFul
1780: 6c 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65  lPathname(sqlite
1790: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
17a0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20  ar *zName, int, 
17b0: 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69 66  char *zOut);.#if
17c0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
17d0: 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a  _LOAD_EXTENSION.
17e0: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66  static void *tvf
17f0: 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  sDlOpen(sqlite3_
1800: 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72  vfs*, const char
1810: 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73 74   *zFilename);.st
1820: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
1830: 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66  Error(sqlite3_vf
1840: 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  s*, int nByte, c
1850: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a 73  har *zErrMsg);.s
1860: 74 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66  tatic void (*tvf
1870: 73 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76  sDlSym(sqlite3_v
1880: 66 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73 74  fs*,void*, const
1890: 20 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29 29   char *zSymbol))
18a0: 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76  (void);.static v
18b0: 6f 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28  oid tvfsDlClose(
18c0: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f  sqlite3_vfs*, vo
18d0: 69 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20  id*);.#endif /* 
18e0: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
18f0: 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73 74  _EXTENSION */.st
1900: 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e  atic int tvfsRan
1910: 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f  domness(sqlite3_
1920: 76 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c  vfs*, int nByte,
1930: 20 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74   char *zOut);.st
1940: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65  atic int tvfsSle
1950: 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  ep(sqlite3_vfs*,
1960: 20 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e 64   int microsecond
1970: 73 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  s);.static int t
1980: 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73  vfsCurrentTime(s
1990: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f 75  qlite3_vfs*, dou
19a0: 62 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69  ble*);..static i
19b0: 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73  nt tvfsShmOpen(s
19c0: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73  qlite3_file*);.s
19d0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68  tatic int tvfsSh
19e0: 6d 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  mLock(sqlite3_fi
19f0: 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 2c 20  le*, int , int, 
1a00: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
1a10: 20 74 76 66 73 53 68 6d 4d 61 70 28 73 71 6c 69   tvfsShmMap(sqli
1a20: 74 65 33 5f 66 69 6c 65 2a 2c 69 6e 74 2c 69 6e  te3_file*,int,in
1a30: 74 2c 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c 61  t,int, void vola
1a40: 74 69 6c 65 20 2a 2a 29 3b 0a 73 74 61 74 69 63  tile **);.static
1a50: 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72   void tvfsShmBar
1a60: 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c  rier(sqlite3_fil
1a70: 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  e*);.static int 
1a80: 74 76 66 73 53 68 6d 55 6e 6d 61 70 28 73 71 6c  tvfsShmUnmap(sql
1a90: 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29  ite3_file*, int)
1aa0: 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  ;..static sqlite
1ab0: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 74 76 66  3_io_methods tvf
1ac0: 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 3d 20 7b  s_io_methods = {
1ad0: 0a 20 20 32 2c 20 20 20 20 20 20 20 20 20 20 20  .  2,           
1ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1af0: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
1b00: 2f 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20 20  /.  tvfsClose,  
1b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b20: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a 2f      /* xClose */
1b30: 0a 20 20 74 76 66 73 52 65 61 64 2c 20 20 20 20  .  tvfsRead,    
1b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b50: 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a 20     /* xRead */. 
1b60: 20 74 76 66 73 57 72 69 74 65 2c 20 20 20 20 20   tvfsWrite,     
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b80: 20 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20 20   /* xWrite */.  
1b90: 74 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20 20  tvfsTruncate,   
1ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb0: 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a  /* xTruncate */.
1bc0: 20 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20 20    tvfsSync,     
1bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1be0: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
1bf0: 74 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20 20  tvfsFileSize,   
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f 0a  /* xFileSize */.
1c20: 20 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20 20    tvfsLock,     
1c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c40: 20 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20    /* xLock */.  
1c50: 74 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20 20  tvfsUnlock,     
1c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c70: 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20  /* xUnlock */.  
1c80: 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76 65  tvfsCheckReserve
1c90: 64 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20  dLock,          
1ca0: 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  /* xCheckReserve
1cb0: 64 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73 46  dLock */.  tvfsF
1cc0: 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20 20  ileControl,     
1cd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
1ce0: 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20  ileControl */.  
1cf0: 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c 20  tvfsSectorSize, 
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d10: 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20 2a  /* xSectorSize *
1d20: 2f 0a 20 20 74 76 66 73 44 65 76 69 63 65 43 68  /.  tvfsDeviceCh
1d30: 61 72 61 63 74 65 72 69 73 74 69 63 73 2c 20 20  aracteristics,  
1d40: 20 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43 68      /* xDeviceCh
1d50: 61 72 61 63 74 65 72 69 73 74 69 63 73 20 2a 2f  aracteristics */
1d60: 0a 20 20 74 76 66 73 53 68 6d 4d 61 70 2c 20 20  .  tvfsShmMap,  
1d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d80: 20 20 20 2f 2a 20 78 53 68 6d 4d 61 70 20 2a 2f     /* xShmMap */
1d90: 0a 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c 20  .  tvfsShmLock, 
1da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1db0: 20 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a     /* xShmLock *
1dc0: 2f 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72 69  /.  tvfsShmBarri
1dd0: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
1de0: 20 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69      /* xShmBarri
1df0: 65 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 55  er */.  tvfsShmU
1e00: 6e 6d 61 70 20 20 20 20 20 20 20 20 20 20 20 20  nmap            
1e10: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55          /* xShmU
1e20: 6e 6d 61 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74  nmap */.};..stat
1e30: 69 63 20 69 6e 74 20 74 76 66 73 52 65 73 75 6c  ic int tvfsResul
1e40: 74 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a 70  tCode(Testvfs *p
1e50: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 73  , int *pRc){.  s
1e60: 74 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b 0a  truct errcode {.
1e70: 20 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a 20      int eCode;. 
1e80: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
1e90: 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65 5b  Code;.  } aCode[
1ea0: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c 49  ] = {.    { SQLI
1eb0: 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c 49  TE_OK,     "SQLI
1ec0: 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20 20  TE_OK"     },.  
1ed0: 20 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f 52    { SQLITE_ERROR
1ee0: 2c 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52  ,  "SQLITE_ERROR
1ef0: 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  "  },.    { SQLI
1f00: 54 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c 49  TE_IOERR,  "SQLI
1f10: 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20 20  TE_IOERR"  },.  
1f20: 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45    { SQLITE_LOCKE
1f30: 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b 45  D, "SQLITE_LOCKE
1f40: 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  D" },.    { SQLI
1f50: 54 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c 49  TE_BUSY,   "SQLI
1f60: 54 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20 20  TE_BUSY"   },.  
1f70: 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  };..  const char
1f80: 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20   *z;.  int i;.. 
1f90: 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69   z = Tcl_GetStri
1fa0: 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  ngResult(p->inte
1fb0: 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  rp);.  for(i=0; 
1fc0: 69 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f 64  i<ArraySize(aCod
1fd0: 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  e); i++){.    if
1fe0: 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 61  ( 0==strcmp(z, a
1ff0: 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20 29  Code[i].zCode) )
2000: 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 61  {.      *pRc = a
2010: 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a 20  Code[i].eCode;. 
2020: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
2030: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
2040: 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 0;.}..static 
2050: 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 61  int tvfsInjectFa
2060: 75 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e 6a  ult(TestFaultInj
2070: 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ect *p){.  int r
2080: 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d  et = 0;.  if( p-
2090: 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20 70  >eFault ){.    p
20a0: 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69 66  ->iCnt--;.    if
20b0: 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c 20  ( p->iCnt==0 || 
20c0: 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70 2d  (p->iCnt<0 && p-
20d0: 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f 49  >eFault==FAULT_I
20e0: 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e 54  NJECT_PERSISTENT
20f0: 20 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20   ) ){.      ret 
2100: 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46  = 1;.      p->nF
2110: 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  ail++;.    }.  }
2120: 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d  .  return ret;.}
2130: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  ...static int tv
2140: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54 65  fsInjectIoerr(Te
2150: 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74  stvfs *p){.  ret
2160: 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61  urn tvfsInjectFa
2170: 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65 72  ult(&p->ioerr_er
2180: 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  r);.}..static in
2190: 74 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c  t tvfsInjectFull
21a0: 65 72 72 28 54 65 73 74 76 66 73 20 2a 70 29 7b  err(Testvfs *p){
21b0: 0a 20 20 72 65 74 75 72 6e 20 74 76 66 73 49 6e  .  return tvfsIn
21c0: 6a 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66 75  jectFault(&p->fu
21d0: 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74 69  ll_err);.}.stati
21e0: 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74  c int tvfsInject
21f0: 43 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73 74  Cantopenerr(Test
2200: 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  vfs *p){.  retur
2210: 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75 6c  n tvfsInjectFaul
2220: 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65  t(&p->cantopen_e
2230: 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20  rr);.}...static 
2240: 76 6f 69 64 20 74 76 66 73 45 78 65 63 54 63 6c  void tvfsExecTcl
2250: 28 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c 20  (.  Testvfs *p, 
2260: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2270: 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f 62  Method,.  Tcl_Ob
2280: 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f 4f  j *arg1,.  Tcl_O
2290: 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c 5f  bj *arg2,.  Tcl_
22a0: 4f 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20 69  Obj *arg3.){.  i
22b0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22d0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72  * Return code fr
22e0: 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28 29  om Tcl_EvalObj()
22f0: 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70   */.  Tcl_Obj *p
2300: 45 76 61 6c 3b 0a 20 20 61 73 73 65 72 74 28 20  Eval;.  assert( 
2310: 70 2d 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a 20  p->pScript );.. 
2320: 20 61 73 73 65 72 74 28 20 7a 4d 65 74 68 6f 64   assert( zMethod
2330: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 20   );.  assert( p 
2340: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 72 67  );.  assert( arg
2350: 32 3d 3d 30 20 7c 7c 20 61 72 67 31 21 3d 30 20  2==0 || arg1!=0 
2360: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 72 67  );.  assert( arg
2370: 33 3d 3d 30 20 7c 7c 20 61 72 67 32 21 3d 30 20  3==0 || arg2!=0 
2380: 29 3b 0a 0a 20 20 70 45 76 61 6c 20 3d 20 54 63  );..  pEval = Tc
2390: 6c 5f 44 75 70 6c 69 63 61 74 65 4f 62 6a 28 70  l_DuplicateObj(p
23a0: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 54 63  ->pScript);.  Tc
23b0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70  l_IncrRefCount(p
23c0: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 54 63  ->pScript);.  Tc
23d0: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
23e0: 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70  lement(p->interp
23f0: 2c 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77  , pEval, Tcl_New
2400: 53 74 72 69 6e 67 4f 62 6a 28 7a 4d 65 74 68 6f  StringObj(zMetho
2410: 64 2c 20 2d 31 29 29 3b 0a 20 20 69 66 28 20 61  d, -1));.  if( a
2420: 72 67 31 20 29 20 54 63 6c 5f 4c 69 73 74 4f 62  rg1 ) Tcl_ListOb
2430: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70  jAppendElement(p
2440: 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  ->interp, pEval,
2450: 20 61 72 67 31 29 3b 0a 20 20 69 66 28 20 61 72   arg1);.  if( ar
2460: 67 32 20 29 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  g2 ) Tcl_ListObj
2470: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
2480: 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20  >interp, pEval, 
2490: 61 72 67 32 29 3b 0a 20 20 69 66 28 20 61 72 67  arg2);.  if( arg
24a0: 33 20 29 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41  3 ) Tcl_ListObjA
24b0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e  ppendElement(p->
24c0: 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 61  interp, pEval, a
24d0: 72 67 33 29 3b 0a 0a 20 20 72 63 20 3d 20 54 63  rg3);..  rc = Tc
24e0: 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 70 2d 3e 69  l_EvalObjEx(p->i
24f0: 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 54 43  nterp, pEval, TC
2500: 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 3b 0a  L_EVAL_GLOBAL);.
2510: 20 20 69 66 28 20 72 63 21 3d 54 43 4c 5f 4f 4b    if( rc!=TCL_OK
2520: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42 61 63 6b   ){.    Tcl_Back
2530: 67 72 6f 75 6e 64 45 72 72 6f 72 28 70 2d 3e 69  groundError(p->i
2540: 6e 74 65 72 70 29 3b 0a 20 20 20 20 54 63 6c 5f  nterp);.    Tcl_
2550: 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69  ResetResult(p->i
2560: 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 0a  nterp);.  }.}...
2570: 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 74  /*.** Close an t
2580: 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  vfs-file..*/.sta
2590: 74 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f 73  tic int tvfsClos
25a0: 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  e(sqlite3_file *
25b0: 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63  pFile){.  int rc
25c0: 3b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20  ;.  TestvfsFile 
25d0: 2a 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65  *pTestfile = (Te
25e0: 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c  stvfsFile *)pFil
25f0: 65 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  e;.  TestvfsFd *
2600: 70 46 64 20 3d 20 70 54 65 73 74 66 69 6c 65 2d  pFd = pTestfile-
2610: 3e 70 46 64 3b 0a 20 20 54 65 73 74 76 66 73 20  >pFd;.  Testvfs 
2620: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
2630: 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44  pFd->pVfs->pAppD
2640: 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70  ata;..  if( p->p
2650: 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73  Script && p->mas
2660: 6b 26 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f  k&TESTVFS_CLOSE_
2670: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73  MASK ){.    tvfs
2680: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 43 6c 6f  ExecTcl(p, "xClo
2690: 73 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  se", .        Tc
26a0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
26b0: 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d  Fd->zFilename, -
26c0: 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c  1), pFd->pShmId,
26d0: 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20   0.    );.  }.. 
26e0: 20 69 66 28 20 70 46 64 2d 3e 70 53 68 6d 49 64   if( pFd->pShmId
26f0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72   ){.    Tcl_Decr
2700: 52 65 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70 53  RefCount(pFd->pS
2710: 68 6d 49 64 29 3b 0a 20 20 20 20 70 46 64 2d 3e  hmId);.    pFd->
2720: 70 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d 0a  pShmId = 0;.  }.
2730: 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d 65    if( pFile->pMe
2740: 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b 66  thods ){.    ckf
2750: 72 65 65 28 28 63 68 61 72 20 2a 29 70 46 69 6c  ree((char *)pFil
2760: 65 2d 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20 20  e->pMethods);.  
2770: 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  }.  rc = sqlite3
2780: 4f 73 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52 65  OsClose(pFd->pRe
2790: 61 6c 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63  al);.  ckfree((c
27a0: 68 61 72 20 2a 29 70 46 64 29 3b 0a 20 20 70 54  har *)pFd);.  pT
27b0: 65 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 30  estfile->pFd = 0
27c0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
27d0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61 74  ../*.** Read dat
27e0: 61 20 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d 66  a from an tvfs-f
27f0: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
2800: 6e 74 20 74 76 66 73 52 65 61 64 28 0a 20 20 73  nt tvfsRead(.  s
2810: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2820: 6c 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42 75  le, .  void *zBu
2830: 66 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20  f, .  int iAmt, 
2840: 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
2850: 69 4f 66 73 74 0a 29 7b 0a 20 20 69 6e 74 20 72  iOfst.){.  int r
2860: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
2870: 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20   TestvfsFd *pFd 
2880: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
2890: 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  e);.  Testvfs *p
28a0: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46   = (Testvfs *)pF
28b0: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
28c0: 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  a;.  if( p->pScr
28d0: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
28e0: 45 53 54 56 46 53 5f 52 45 41 44 5f 4d 41 53 4b  ESTVFS_READ_MASK
28f0: 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63   ){.    tvfsExec
2900: 54 63 6c 28 70 2c 20 22 78 52 65 61 64 22 2c 20  Tcl(p, "xRead", 
2910: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77  .        Tcl_New
2920: 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a  StringObj(pFd->z
2930: 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 70  Filename, -1), p
2940: 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20  Fd->pShmId, 0.  
2950: 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73    );.    tvfsRes
2960: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b  ultCode(p, &rc);
2970: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
2980: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d  QLITE_OK && p->m
2990: 61 73 6b 26 54 45 53 54 56 46 53 5f 52 45 41 44  ask&TESTVFS_READ
29a0: 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a  _MASK && tvfsInj
29b0: 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20  ectIoerr(p) ){. 
29c0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49     rc = SQLITE_I
29d0: 4f 45 52 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  OERR;.  }.  if( 
29e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
29f0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
2a00: 33 4f 73 52 65 61 64 28 70 46 64 2d 3e 70 52 65  3OsRead(pFd->pRe
2a10: 61 6c 2c 20 7a 42 75 66 2c 20 69 41 6d 74 2c 20  al, zBuf, iAmt, 
2a20: 69 4f 66 73 74 29 3b 0a 20 20 7d 0a 20 20 72 65  iOfst);.  }.  re
2a30: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
2a40: 2a 20 57 72 69 74 65 20 64 61 74 61 20 74 6f 20  * Write data to 
2a50: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
2a60: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
2a70: 57 72 69 74 65 28 0a 20 20 73 71 6c 69 74 65 33  Write(.  sqlite3
2a80: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 0a 20  _file *pFile, . 
2a90: 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 7a 42 75   const void *zBu
2aa0: 66 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20  f, .  int iAmt, 
2ab0: 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  .  sqlite_int64 
2ac0: 69 4f 66 73 74 0a 29 7b 0a 20 20 69 6e 74 20 72  iOfst.){.  int r
2ad0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
2ae0: 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20   TestvfsFd *pFd 
2af0: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
2b00: 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  e);.  Testvfs *p
2b10: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46   = (Testvfs *)pF
2b20: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
2b30: 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  a;..  if( p->pSc
2b40: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
2b50: 54 45 53 54 56 46 53 5f 57 52 49 54 45 5f 4d 41  TESTVFS_WRITE_MA
2b60: 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78  SK ){.    tvfsEx
2b70: 65 63 54 63 6c 28 70 2c 20 22 78 57 72 69 74 65  ecTcl(p, "xWrite
2b80: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
2b90: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
2ba0: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29  ->zFilename, -1)
2bb0: 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30  , pFd->pShmId, 0
2bc0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
2bd0: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
2be0: 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  c);.  }..  if( r
2bf0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2c00: 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c 65 72  tvfsInjectFuller
2c10: 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d  r(p) ){.    rc =
2c20: 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3b 0a 20 20   SQLITE_FULL;.  
2c30: 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  }.  if( rc==SQLI
2c40: 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b  TE_OK && p->mask
2c50: 26 54 45 53 54 56 46 53 5f 57 52 49 54 45 5f 4d  &TESTVFS_WRITE_M
2c60: 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63  ASK && tvfsInjec
2c70: 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20  tIoerr(p) ){.   
2c80: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45   rc = SQLITE_IOE
2c90: 52 52 3b 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28  RR;.  }.  .  if(
2ca0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2cb0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
2cc0: 65 33 4f 73 57 72 69 74 65 28 70 46 64 2d 3e 70  e3OsWrite(pFd->p
2cd0: 52 65 61 6c 2c 20 7a 42 75 66 2c 20 69 41 6d 74  Real, zBuf, iAmt
2ce0: 2c 20 69 4f 66 73 74 29 3b 0a 20 20 7d 0a 20 20  , iOfst);.  }.  
2cf0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
2d00: 0a 2a 2a 20 54 72 75 6e 63 61 74 65 20 61 6e 20  .** Truncate an 
2d10: 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74  tvfs-file..*/.st
2d20: 61 74 69 63 20 69 6e 74 20 74 76 66 73 54 72 75  atic int tvfsTru
2d30: 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69  ncate(sqlite3_fi
2d40: 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71 6c 69 74  le *pFile, sqlit
2d50: 65 5f 69 6e 74 36 34 20 73 69 7a 65 29 7b 0a 20  e_int64 size){. 
2d60: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2d70: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
2d80: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
2d90: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
2da0: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
2db0: 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70  s *)pFd->pVfs->p
2dc0: 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20  AppData;..  if( 
2dd0: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
2de0: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 54 52  >mask&TESTVFS_TR
2df0: 55 4e 43 41 54 45 5f 4d 41 53 4b 20 29 7b 0a 20  UNCATE_MASK ){. 
2e00: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
2e10: 2c 20 22 78 54 72 75 6e 63 61 74 65 22 2c 20 0a  , "xTruncate", .
2e20: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
2e30: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46  tringObj(pFd->zF
2e40: 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 70 46  ilename, -1), pF
2e50: 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20 20  d->pShmId, 0.   
2e60: 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75   );.    tvfsResu
2e70: 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a  ltCode(p, &rc);.
2e80: 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 72 63 3d    }.  .  if( rc=
2e90: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
2ea0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
2eb0: 54 72 75 6e 63 61 74 65 28 70 46 64 2d 3e 70 52  Truncate(pFd->pR
2ec0: 65 61 6c 2c 20 73 69 7a 65 29 3b 0a 20 20 7d 0a  eal, size);.  }.
2ed0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2ee0: 2f 2a 0a 2a 2a 20 53 79 6e 63 20 61 6e 20 74 76  /*.** Sync an tv
2ef0: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
2f00: 69 63 20 69 6e 74 20 74 76 66 73 53 79 6e 63 28  ic int tvfsSync(
2f10: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2f20: 69 6c 65 2c 20 69 6e 74 20 66 6c 61 67 73 29 7b  ile, int flags){
2f30: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
2f40: 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73  TE_OK;.  Testvfs
2f50: 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65  Fd *pFd = tvfsGe
2f60: 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65  tFd(pFile);.  Te
2f70: 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74  stvfs *p = (Test
2f80: 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d  vfs *)pFd->pVfs-
2f90: 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66  >pAppData;..  if
2fa0: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
2fb0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
2fc0: 53 59 4e 43 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  SYNC_MASK ){.   
2fd0: 20 63 68 61 72 20 2a 7a 46 6c 61 67 73 3b 0a 0a   char *zFlags;..
2fe0: 20 20 20 20 73 77 69 74 63 68 28 20 66 6c 61 67      switch( flag
2ff0: 73 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20  s ){.      case 
3000: 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4e 4f 52 4d  SQLITE_SYNC_NORM
3010: 41 4c 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61  AL:.        zFla
3020: 67 73 20 3d 20 22 6e 6f 72 6d 61 6c 22 3b 0a 20  gs = "normal";. 
3030: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
3040: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
3050: 53 59 4e 43 5f 46 55 4c 4c 3a 0a 20 20 20 20 20  SYNC_FULL:.     
3060: 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 66 75 6c     zFlags = "ful
3070: 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  l";.        brea
3080: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  k;.      case SQ
3090: 4c 49 54 45 5f 53 59 4e 43 5f 4e 4f 52 4d 41 4c  LITE_SYNC_NORMAL
30a0: 7c 53 51 4c 49 54 45 5f 53 59 4e 43 5f 44 41 54  |SQLITE_SYNC_DAT
30b0: 41 4f 4e 4c 59 3a 0a 20 20 20 20 20 20 20 20 7a  AONLY:.        z
30c0: 46 6c 61 67 73 20 3d 20 22 6e 6f 72 6d 61 6c 7c  Flags = "normal|
30d0: 64 61 74 61 6f 6e 6c 79 22 3b 0a 20 20 20 20 20  dataonly";.     
30e0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
30f0: 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43  case SQLITE_SYNC
3100: 5f 46 55 4c 4c 7c 53 51 4c 49 54 45 5f 53 59 4e  _FULL|SQLITE_SYN
3110: 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20 20 20  C_DATAONLY:.    
3120: 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 66 75      zFlags = "fu
3130: 6c 6c 7c 64 61 74 61 6f 6e 6c 79 22 3b 0a 20 20  ll|dataonly";.  
3140: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
3150: 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20     default:.    
3160: 20 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20      assert(0);. 
3170: 20 20 20 7d 0a 0a 20 20 20 20 74 76 66 73 45 78     }..    tvfsEx
3180: 65 63 54 63 6c 28 70 2c 20 22 78 53 79 6e 63 22  ecTcl(p, "xSync"
3190: 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e  , .        Tcl_N
31a0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d  ewStringObj(pFd-
31b0: 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c  >zFilename, -1),
31c0: 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20   pFd->pShmId,.  
31d0: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
31e0: 69 6e 67 4f 62 6a 28 7a 46 6c 61 67 73 2c 20 2d  ingObj(zFlags, -
31f0: 31 29 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76  1).    );.    tv
3200: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
3210: 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  &rc);.  }..  if(
3220: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
3230: 26 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c  & tvfsInjectFull
3240: 65 72 72 28 70 29 20 29 20 72 63 20 3d 20 53 51  err(p) ) rc = SQ
3250: 4c 49 54 45 5f 46 55 4c 4c 3b 0a 0a 20 20 69 66  LITE_FULL;..  if
3260: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
3270: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
3280: 74 65 33 4f 73 53 79 6e 63 28 70 46 64 2d 3e 70  te3OsSync(pFd->p
3290: 52 65 61 6c 2c 20 66 6c 61 67 73 29 3b 0a 20 20  Real, flags);.  
32a0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
32b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
32c0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 69 6c 65  the current file
32d0: 2d 73 69 7a 65 20 6f 66 20 61 6e 20 74 76 66 73  -size of an tvfs
32e0: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
32f0: 20 69 6e 74 20 74 76 66 73 46 69 6c 65 53 69 7a   int tvfsFileSiz
3300: 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  e(sqlite3_file *
3310: 70 46 69 6c 65 2c 20 73 71 6c 69 74 65 5f 69 6e  pFile, sqlite_in
3320: 74 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20 54  t64 *pSize){.  T
3330: 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74 76  estvfsFd *p = tv
3340: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
3350: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
3360: 4f 73 46 69 6c 65 53 69 7a 65 28 70 2d 3e 70 52  OsFileSize(p->pR
3370: 65 61 6c 2c 20 70 53 69 7a 65 29 3b 0a 7d 0a 0a  eal, pSize);.}..
3380: 2f 2a 0a 2a 2a 20 4c 6f 63 6b 20 61 6e 20 74 76  /*.** Lock an tv
3390: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
33a0: 69 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28  ic int tvfsLock(
33b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
33c0: 69 6c 65 2c 20 69 6e 74 20 65 4c 6f 63 6b 29 7b  ile, int eLock){
33d0: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 20  .  TestvfsFd *p 
33e0: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
33f0: 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  e);.  return sql
3400: 69 74 65 33 4f 73 4c 6f 63 6b 28 70 2d 3e 70 52  ite3OsLock(p->pR
3410: 65 61 6c 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a  eal, eLock);.}..
3420: 2f 2a 0a 2a 2a 20 55 6e 6c 6f 63 6b 20 61 6e 20  /*.** Unlock an 
3430: 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74  tvfs-file..*/.st
3440: 61 74 69 63 20 69 6e 74 20 74 76 66 73 55 6e 6c  atic int tvfsUnl
3450: 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ock(sqlite3_file
3460: 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 65 4c 6f   *pFile, int eLo
3470: 63 6b 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  ck){.  TestvfsFd
3480: 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64 28   *p = tvfsGetFd(
3490: 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e  pFile);.  return
34a0: 20 73 71 6c 69 74 65 33 4f 73 55 6e 6c 6f 63 6b   sqlite3OsUnlock
34b0: 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63 6b  (p->pReal, eLock
34c0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63  );.}../*.** Chec
34d0: 6b 20 69 66 20 61 6e 6f 74 68 65 72 20 66 69 6c  k if another fil
34e0: 65 2d 68 61 6e 64 6c 65 20 68 6f 6c 64 73 20 61  e-handle holds a
34f0: 20 52 45 53 45 52 56 45 44 20 6c 6f 63 6b 20 6f   RESERVED lock o
3500: 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  n an tvfs-file..
3510: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3520: 66 73 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c  fsCheckReservedL
3530: 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ock(sqlite3_file
3540: 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 2a 70 52   *pFile, int *pR
3550: 65 73 4f 75 74 29 7b 0a 20 20 54 65 73 74 76 66  esOut){.  Testvf
3560: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
3570: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
3580: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 43 68 65  urn sqlite3OsChe
3590: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 70  ckReservedLock(p
35a0: 2d 3e 70 52 65 61 6c 2c 20 70 52 65 73 4f 75 74  ->pReal, pResOut
35b0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6c 65  );.}../*.** File
35c0: 20 63 6f 6e 74 72 6f 6c 20 6d 65 74 68 6f 64 2e   control method.
35d0: 20 46 6f 72 20 63 75 73 74 6f 6d 20 6f 70 65 72   For custom oper
35e0: 61 74 69 6f 6e 73 20 6f 6e 20 61 6e 20 74 76 66  ations on an tvf
35f0: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
3600: 63 20 69 6e 74 20 74 76 66 73 46 69 6c 65 43 6f  c int tvfsFileCo
3610: 6e 74 72 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69  ntrol(sqlite3_fi
3620: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 6f  le *pFile, int o
3630: 70 2c 20 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a  p, void *pArg){.
3640: 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d    TestvfsFd *p =
3650: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
3660: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  );.  return sqli
3670: 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f 6c  te3OsFileControl
3680: 28 70 2d 3e 70 52 65 61 6c 2c 20 6f 70 2c 20 70  (p->pReal, op, p
3690: 41 72 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  Arg);.}../*.** R
36a0: 65 74 75 72 6e 20 74 68 65 20 73 65 63 74 6f 72  eturn the sector
36b0: 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 66  -size in bytes f
36c0: 6f 72 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  or an tvfs-file.
36d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
36e0: 76 66 73 53 65 63 74 6f 72 53 69 7a 65 28 73 71  vfsSectorSize(sq
36f0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
3700: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20  e){.  TestvfsFd 
3710: 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46 64  *pFd = tvfsGetFd
3720: 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74 76  (pFile);.  Testv
3730: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
3740: 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41   *)pFd->pVfs->pA
3750: 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20 70 2d  ppData;.  if( p-
3760: 3e 69 53 65 63 74 6f 72 73 69 7a 65 3e 3d 30 20  >iSectorsize>=0 
3770: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 2d  ){.    return p-
3780: 3e 69 53 65 63 74 6f 72 73 69 7a 65 3b 0a 20 20  >iSectorsize;.  
3790: 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  }.  return sqlit
37a0: 65 33 4f 73 53 65 63 74 6f 72 53 69 7a 65 28 70  e3OsSectorSize(p
37b0: 46 64 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f  Fd->pReal);.}../
37c0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
37d0: 64 65 76 69 63 65 20 63 68 61 72 61 63 74 65 72  device character
37e0: 69 73 74 69 63 20 66 6c 61 67 73 20 73 75 70 70  istic flags supp
37f0: 6f 72 74 65 64 20 62 79 20 61 6e 20 74 76 66 73  orted by an tvfs
3800: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
3810: 20 69 6e 74 20 74 76 66 73 44 65 76 69 63 65 43   int tvfsDeviceC
3820: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28 73  haracteristics(s
3830: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
3840: 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  le){.  TestvfsFd
3850: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
3860: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
3870: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
3880: 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70  s *)pFd->pVfs->p
3890: 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20 70  AppData;.  if( p
38a0: 2d 3e 69 44 65 76 63 68 61 72 3e 3d 30 20 29 7b  ->iDevchar>=0 ){
38b0: 0a 20 20 20 20 72 65 74 75 72 6e 20 70 2d 3e 69  .    return p->i
38c0: 44 65 76 63 68 61 72 3b 0a 20 20 7d 0a 20 20 72  Devchar;.  }.  r
38d0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 44  eturn sqlite3OsD
38e0: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
38f0: 74 69 63 73 28 70 46 64 2d 3e 70 52 65 61 6c 29  tics(pFd->pReal)
3900: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20  ;.}../*.** Open 
3910: 61 6e 20 74 76 66 73 20 66 69 6c 65 20 68 61 6e  an tvfs file han
3920: 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  dle..*/.static i
3930: 6e 74 20 74 76 66 73 4f 70 65 6e 28 0a 20 20 73  nt tvfsOpen(.  s
3940: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
3950: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
3960: 7a 4e 61 6d 65 2c 0a 20 20 73 71 6c 69 74 65 33  zName,.  sqlite3
3970: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20  _file *pFile,.  
3980: 69 6e 74 20 66 6c 61 67 73 2c 0a 20 20 69 6e 74  int flags,.  int
3990: 20 2a 70 4f 75 74 46 6c 61 67 73 0a 29 7b 0a 20   *pOutFlags.){. 
39a0: 20 69 6e 74 20 72 63 3b 0a 20 20 54 65 73 74 76   int rc;.  Testv
39b0: 66 73 46 69 6c 65 20 2a 70 54 65 73 74 66 69 6c  fsFile *pTestfil
39c0: 65 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c 65  e = (TestvfsFile
39d0: 20 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73 74   *)pFile;.  Test
39e0: 76 66 73 46 64 20 2a 70 46 64 3b 0a 20 20 54 63  vfsFd *pFd;.  Tc
39f0: 6c 5f 4f 62 6a 20 2a 70 49 64 20 3d 20 30 3b 0a  l_Obj *pId = 0;.
3a00: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
3a10: 54 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d 3e  Testvfs *)pVfs->
3a20: 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 70 46 64  pAppData;..  pFd
3a30: 20 3d 20 28 54 65 73 74 76 66 73 46 64 20 2a 29   = (TestvfsFd *)
3a40: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 54  ckalloc(sizeof(T
3a50: 65 73 74 76 66 73 46 64 29 20 2b 20 50 41 52 45  estvfsFd) + PARE
3a60: 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 73 7a 4f  NTVFS(pVfs)->szO
3a70: 73 46 69 6c 65 29 3b 0a 20 20 6d 65 6d 73 65 74  sFile);.  memset
3a80: 28 70 46 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28  (pFd, 0, sizeof(
3a90: 54 65 73 74 76 66 73 46 64 29 20 2b 20 50 41 52  TestvfsFd) + PAR
3aa0: 45 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 73 7a  ENTVFS(pVfs)->sz
3ab0: 4f 73 46 69 6c 65 29 3b 0a 20 20 70 46 64 2d 3e  OsFile);.  pFd->
3ac0: 70 53 68 6d 20 3d 20 30 3b 0a 20 20 70 46 64 2d  pShm = 0;.  pFd-
3ad0: 3e 70 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 70  >pShmId = 0;.  p
3ae0: 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d 20  Fd->zFilename = 
3af0: 7a 4e 61 6d 65 3b 0a 20 20 70 46 64 2d 3e 70 56  zName;.  pFd->pV
3b00: 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 46 64  fs = pVfs;.  pFd
3b10: 2d 3e 70 52 65 61 6c 20 3d 20 28 73 71 6c 69 74  ->pReal = (sqlit
3b20: 65 33 5f 66 69 6c 65 20 2a 29 26 70 46 64 5b 31  e3_file *)&pFd[1
3b30: 5d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 54 65 73  ];.  memset(pTes
3b40: 74 66 69 6c 65 2c 20 30 2c 20 73 69 7a 65 6f 66  tfile, 0, sizeof
3b50: 28 54 65 73 74 76 66 73 46 69 6c 65 29 29 3b 0a  (TestvfsFile));.
3b60: 20 20 70 54 65 73 74 66 69 6c 65 2d 3e 70 46 64    pTestfile->pFd
3b70: 20 3d 20 70 46 64 3b 0a 0a 20 20 2f 2a 20 45 76   = pFd;..  /* Ev
3b80: 61 6c 75 61 74 65 20 74 68 65 20 54 63 6c 20 73  aluate the Tcl s
3b90: 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a 20 20 2a  cript: .  **.  *
3ba0: 2a 20 20 20 53 43 52 49 50 54 20 78 4f 70 65 6e  *   SCRIPT xOpen
3bb0: 20 46 49 4c 45 4e 41 4d 45 20 4b 45 59 2d 56 41   FILENAME KEY-VA
3bc0: 4c 55 45 2d 41 52 47 53 0a 20 20 2a 2a 0a 20 20  LUE-ARGS.  **.  
3bd0: 2a 2a 20 49 66 20 74 68 65 20 73 63 72 69 70 74  ** If the script
3be0: 20 72 65 74 75 72 6e 73 20 61 6e 20 53 51 4c 69   returns an SQLi
3bf0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74  te error code ot
3c00: 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f  her than SQLITE_
3c10: 4f 4b 2c 20 61 6e 0a 20 20 2a 2a 20 65 72 72 6f  OK, an.  ** erro
3c20: 72 20 69 73 20 72 65 74 75 72 6e 65 64 20 74 6f  r is returned to
3c30: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 49 66 20   the caller. If 
3c40: 69 74 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  it returns SQLIT
3c50: 45 5f 4f 4b 2c 20 74 68 65 20 6e 65 77 0a 20 20  E_OK, the new.  
3c60: 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73  ** connection is
3c70: 20 6e 61 6d 65 64 20 22 61 6e 6f 6e 22 2e 20 4f   named "anon". O
3c80: 74 68 65 72 77 69 73 65 2c 20 74 68 65 20 76 61  therwise, the va
3c90: 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  lue returned by 
3ca0: 74 68 65 0a 20 20 2a 2a 20 73 63 72 69 70 74 20  the.  ** script 
3cb0: 69 73 20 75 73 65 64 20 61 73 20 74 68 65 20 63  is used as the c
3cc0: 6f 6e 6e 65 63 74 69 6f 6e 20 6e 61 6d 65 2e 0a  onnection name..
3cd0: 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74    */.  Tcl_Reset
3ce0: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
3cf0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  );.  if( p->pScr
3d00: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
3d10: 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b  ESTVFS_OPEN_MASK
3d20: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20   ){.    Tcl_Obj 
3d30: 2a 70 41 72 67 20 3d 20 54 63 6c 5f 4e 65 77 4f  *pArg = Tcl_NewO
3d40: 62 6a 28 29 3b 0a 20 20 20 20 54 63 6c 5f 49 6e  bj();.    Tcl_In
3d50: 63 72 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29  crRefCount(pArg)
3d60: 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73 26  ;.    if( flags&
3d70: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e  SQLITE_OPEN_MAIN
3d80: 5f 44 42 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e  _DB ){.      con
3d90: 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 26 7a 4e  st char *z = &zN
3da0: 61 6d 65 5b 73 74 72 6c 65 6e 28 7a 4e 61 6d 65  ame[strlen(zName
3db0: 29 2b 31 5d 3b 0a 20 20 20 20 20 20 77 68 69 6c  )+1];.      whil
3dc0: 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 20 20 20  e( *z ){.       
3dd0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
3de0: 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 41 72  ndElement(0, pAr
3df0: 67 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  g, Tcl_NewString
3e00: 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 20 20 20  Obj(z, -1));.   
3e10: 20 20 20 20 20 7a 20 2b 3d 20 73 74 72 6c 65 6e       z += strlen
3e20: 28 7a 29 20 2b 20 31 3b 0a 20 20 20 20 20 20 20  (z) + 1;.       
3e30: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
3e40: 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 41 72  ndElement(0, pAr
3e50: 67 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  g, Tcl_NewString
3e60: 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 20 20 20  Obj(z, -1));.   
3e70: 20 20 20 20 20 7a 20 2b 3d 20 73 74 72 6c 65 6e       z += strlen
3e80: 28 7a 29 20 2b 20 31 3b 0a 20 20 20 20 20 20 7d  (z) + 1;.      }
3e90: 0a 20 20 20 20 7d 0a 20 20 20 20 74 76 66 73 45  .    }.    tvfsE
3ea0: 78 65 63 54 63 6c 28 70 2c 20 22 78 4f 70 65 6e  xecTcl(p, "xOpen
3eb0: 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  ", Tcl_NewString
3ec0: 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61  Obj(pFd->zFilena
3ed0: 6d 65 2c 20 2d 31 29 2c 20 70 41 72 67 2c 20 30  me, -1), pArg, 0
3ee0: 29 3b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  );.    Tcl_DecrR
3ef0: 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a 20  efCount(pArg);. 
3f00: 20 20 20 69 66 28 20 74 76 66 73 52 65 73 75 6c     if( tvfsResul
3f10: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20 29 7b  tCode(p, &rc) ){
3f20: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
3f30: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
3f40: 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  n rc;.    }else{
3f50: 0a 20 20 20 20 20 20 70 49 64 20 3d 20 54 63 6c  .      pId = Tcl
3f60: 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 70 2d  _GetObjResult(p-
3f70: 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 7d 0a  >interp);.    }.
3f80: 20 20 7d 0a 0a 20 20 69 66 28 20 28 70 2d 3e 6d    }..  if( (p->m
3f90: 61 73 6b 26 54 45 53 54 56 46 53 5f 4f 50 45 4e  ask&TESTVFS_OPEN
3fa0: 5f 4d 41 53 4b 29 20 26 26 20 20 74 76 66 73 49  _MASK) &&  tvfsI
3fb0: 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20 29 20  njectIoerr(p) ) 
3fc0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
3fd0: 45 52 52 3b 0a 20 20 69 66 28 20 74 76 66 73 49  ERR;.  if( tvfsI
3fe0: 6e 6a 65 63 74 43 61 6e 74 6f 70 65 6e 65 72 72  njectCantopenerr
3ff0: 28 70 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c  (p) ) return SQL
4000: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 3b 0a 20 20  ITE_CANTOPEN;.  
4010: 69 66 28 20 74 76 66 73 49 6e 6a 65 63 74 46 75  if( tvfsInjectFu
4020: 6c 6c 65 72 72 28 70 29 20 29 20 72 65 74 75 72  llerr(p) ) retur
4030: 6e 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3b 0a 0a  n SQLITE_FULL;..
4040: 20 20 69 66 28 20 21 70 49 64 20 29 7b 0a 20 20    if( !pId ){.  
4050: 20 20 70 49 64 20 3d 20 54 63 6c 5f 4e 65 77 53    pId = Tcl_NewS
4060: 74 72 69 6e 67 4f 62 6a 28 22 61 6e 6f 6e 22 2c  tringObj("anon",
4070: 20 2d 31 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f   -1);.  }.  Tcl_
4080: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 49 64  IncrRefCount(pId
4090: 29 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64  );.  pFd->pShmId
40a0: 20 3d 20 70 49 64 3b 0a 20 20 54 63 6c 5f 52 65   = pId;.  Tcl_Re
40b0: 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  setResult(p->int
40c0: 65 72 70 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71  erp);..  rc = sq
40d0: 6c 69 74 65 33 4f 73 4f 70 65 6e 28 50 41 52 45  lite3OsOpen(PARE
40e0: 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a 4e 61  NTVFS(pVfs), zNa
40f0: 6d 65 2c 20 70 46 64 2d 3e 70 52 65 61 6c 2c 20  me, pFd->pReal, 
4100: 66 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73  flags, pOutFlags
4110: 29 3b 0a 20 20 69 66 28 20 70 46 64 2d 3e 70 52  );.  if( pFd->pR
4120: 65 61 6c 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b  eal->pMethods ){
4130: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f  .    sqlite3_io_
4140: 6d 65 74 68 6f 64 73 20 2a 70 4d 65 74 68 6f 64  methods *pMethod
4150: 73 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65  s;.    int nByte
4160: 3b 0a 0a 20 20 20 20 69 66 28 20 70 56 66 73 2d  ;..    if( pVfs-
4170: 3e 69 56 65 72 73 69 6f 6e 3e 31 20 29 7b 0a 20  >iVersion>1 ){. 
4180: 20 20 20 20 20 6e 42 79 74 65 20 3d 20 73 69 7a       nByte = siz
4190: 65 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  eof(sqlite3_io_m
41a0: 65 74 68 6f 64 73 29 3b 0a 20 20 20 20 7d 65 6c  ethods);.    }el
41b0: 73 65 7b 0a 20 20 20 20 20 20 6e 42 79 74 65 20  se{.      nByte 
41c0: 3d 20 6f 66 66 73 65 74 6f 66 28 73 71 6c 69 74  = offsetof(sqlit
41d0: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 2c 20 78  e3_io_methods, x
41e0: 53 68 6d 4d 61 70 29 3b 0a 20 20 20 20 7d 0a 0a  ShmMap);.    }..
41f0: 20 20 20 20 70 4d 65 74 68 6f 64 73 20 3d 20 28      pMethods = (
4200: 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f  sqlite3_io_metho
4210: 64 73 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e 42 79  ds *)ckalloc(nBy
4220: 74 65 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  te);.    memcpy(
4230: 70 4d 65 74 68 6f 64 73 2c 20 26 74 76 66 73 5f  pMethods, &tvfs_
4240: 69 6f 5f 6d 65 74 68 6f 64 73 2c 20 6e 42 79 74  io_methods, nByt
4250: 65 29 3b 0a 20 20 20 20 70 4d 65 74 68 6f 64 73  e);.    pMethods
4260: 2d 3e 69 56 65 72 73 69 6f 6e 20 3d 20 70 56 66  ->iVersion = pVf
4270: 73 2d 3e 69 56 65 72 73 69 6f 6e 3b 0a 20 20 20  s->iVersion;.   
4280: 20 69 66 28 20 70 56 66 73 2d 3e 69 56 65 72 73   if( pVfs->iVers
4290: 69 6f 6e 3e 31 20 26 26 20 28 28 54 65 73 74 76  ion>1 && ((Testv
42a0: 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44  fs *)pVfs->pAppD
42b0: 61 74 61 29 2d 3e 69 73 4e 6f 73 68 6d 20 29 7b  ata)->isNoshm ){
42c0: 0a 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d  .      pMethods-
42d0: 3e 78 53 68 6d 55 6e 6d 61 70 20 3d 20 30 3b 0a  >xShmUnmap = 0;.
42e0: 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e        pMethods->
42f0: 78 53 68 6d 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20  xShmLock = 0;.  
4300: 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53      pMethods->xS
4310: 68 6d 42 61 72 72 69 65 72 20 3d 20 30 3b 0a 20  hmBarrier = 0;. 
4320: 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e 78       pMethods->x
4330: 53 68 6d 4d 61 70 20 3d 20 30 3b 0a 20 20 20 20  ShmMap = 0;.    
4340: 7d 0a 20 20 20 20 70 46 69 6c 65 2d 3e 70 4d 65  }.    pFile->pMe
4350: 74 68 6f 64 73 20 3d 20 70 4d 65 74 68 6f 64 73  thods = pMethods
4360: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
4370: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c  rc;.}../*.** Del
4380: 65 74 65 20 74 68 65 20 66 69 6c 65 20 6c 6f 63  ete the file loc
4390: 61 74 65 64 20 61 74 20 7a 50 61 74 68 2e 20 49  ated at zPath. I
43a0: 66 20 74 68 65 20 64 69 72 53 79 6e 63 20 61 72  f the dirSync ar
43b0: 67 75 6d 65 6e 74 20 69 73 20 74 72 75 65 2c 0a  gument is true,.
43c0: 2a 2a 20 65 6e 73 75 72 65 20 74 68 65 20 66 69  ** ensure the fi
43d0: 6c 65 2d 73 79 73 74 65 6d 20 6d 6f 64 69 66 69  le-system modifi
43e0: 63 61 74 69 6f 6e 73 20 61 72 65 20 73 79 6e 63  cations are sync
43f0: 65 64 20 74 6f 20 64 69 73 6b 20 62 65 66 6f 72  ed to disk befor
4400: 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67 2e 0a  e.** returning..
4410: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
4420: 66 73 44 65 6c 65 74 65 28 73 71 6c 69 74 65 33  fsDelete(sqlite3
4430: 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f 6e 73  _vfs *pVfs, cons
4440: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 69  t char *zPath, i
4450: 6e 74 20 64 69 72 53 79 6e 63 29 7b 0a 20 20 69  nt dirSync){.  i
4460: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4470: 4b 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  K;.  Testvfs *p 
4480: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 56 66  = (Testvfs *)pVf
4490: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20  s->pAppData;..  
44a0: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
44b0: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
44c0: 53 5f 44 45 4c 45 54 45 5f 4d 41 53 4b 20 29 7b  S_DELETE_MASK ){
44d0: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
44e0: 28 70 2c 20 22 78 44 65 6c 65 74 65 22 2c 20 0a  (p, "xDelete", .
44f0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
4500: 74 72 69 6e 67 4f 62 6a 28 7a 50 61 74 68 2c 20  tringObj(zPath, 
4510: 2d 31 29 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f  -1), Tcl_NewIntO
4520: 62 6a 28 64 69 72 53 79 6e 63 29 2c 20 30 0a 20  bj(dirSync), 0. 
4530: 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65     );.    tvfsRe
4540: 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29  sultCode(p, &rc)
4550: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d  ;.  }.  if( rc==
4560: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4570: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 44   rc = sqlite3OsD
4580: 65 6c 65 74 65 28 50 41 52 45 4e 54 56 46 53 28  elete(PARENTVFS(
4590: 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 64 69  pVfs), zPath, di
45a0: 72 53 79 6e 63 29 3b 0a 20 20 7d 0a 20 20 72 65  rSync);.  }.  re
45b0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
45c0: 2a 20 54 65 73 74 20 66 6f 72 20 61 63 63 65 73  * Test for acces
45d0: 73 20 70 65 72 6d 69 73 73 69 6f 6e 73 2e 20 52  s permissions. R
45e0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68  eturn true if th
45f0: 65 20 72 65 71 75 65 73 74 65 64 20 70 65 72 6d  e requested perm
4600: 69 73 73 69 6f 6e 0a 2a 2a 20 69 73 20 61 76 61  ission.** is ava
4610: 69 6c 61 62 6c 65 2c 20 6f 72 20 66 61 6c 73 65  ilable, or false
4620: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
4630: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 41 63  tatic int tvfsAc
4640: 63 65 73 73 28 0a 20 20 73 71 6c 69 74 65 33 5f  cess(.  sqlite3_
4650: 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20 63 6f  vfs *pVfs, .  co
4660: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c  nst char *zPath,
4670: 20 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c 20 0a   .  int flags, .
4680: 20 20 69 6e 74 20 2a 70 52 65 73 4f 75 74 0a 29    int *pResOut.)
4690: 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  {.  Testvfs *p =
46a0: 20 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73   (Testvfs *)pVfs
46b0: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 69 66  ->pAppData;.  if
46c0: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
46d0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
46e0: 41 43 43 45 53 53 5f 4d 41 53 4b 20 29 7b 0a 20  ACCESS_MASK ){. 
46f0: 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 63     int rc;.    c
4700: 68 61 72 20 2a 7a 41 72 67 20 3d 20 30 3b 0a 20  har *zArg = 0;. 
4710: 20 20 20 69 66 28 20 66 6c 61 67 73 3d 3d 53 51     if( flags==SQ
4720: 4c 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53  LITE_ACCESS_EXIS
4730: 54 53 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c  TS ) zArg = "SQL
4740: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
4750: 53 22 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67  S";.    if( flag
4760: 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53 53  s==SQLITE_ACCESS
4770: 5f 52 45 41 44 57 52 49 54 45 20 29 20 7a 41 72  _READWRITE ) zAr
4780: 67 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45  g = "SQLITE_ACCE
4790: 53 53 5f 52 45 41 44 57 52 49 54 45 22 3b 0a 20  SS_READWRITE";. 
47a0: 20 20 20 69 66 28 20 66 6c 61 67 73 3d 3d 53 51     if( flags==SQ
47b0: 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44  LITE_ACCESS_READ
47c0: 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c 49 54   ) zArg = "SQLIT
47d0: 45 5f 41 43 43 45 53 53 5f 52 45 41 44 22 3b 0a  E_ACCESS_READ";.
47e0: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
47f0: 70 2c 20 22 78 41 63 63 65 73 73 22 2c 20 0a 20  p, "xAccess", . 
4800: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
4810: 72 69 6e 67 4f 62 6a 28 7a 50 61 74 68 2c 20 2d  ringObj(zPath, -
4820: 31 29 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  1), Tcl_NewStrin
4830: 67 4f 62 6a 28 7a 41 72 67 2c 20 2d 31 29 2c 20  gObj(zArg, -1), 
4840: 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  0.    );.    if(
4850: 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28   tvfsResultCode(
4860: 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20  p, &rc) ){.     
4870: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
4880: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
4890: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
48a0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
48b0: 65 72 70 20 3d 20 70 2d 3e 69 6e 74 65 72 70 3b  erp = p->interp;
48c0: 0a 20 20 20 20 20 20 69 66 28 20 54 43 4c 5f 4f  .      if( TCL_O
48d0: 4b 3d 3d 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61  K==Tcl_GetBoolea
48e0: 6e 46 72 6f 6d 4f 62 6a 28 30 2c 20 54 63 6c 5f  nFromObj(0, Tcl_
48f0: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
4900: 65 72 70 29 2c 20 70 52 65 73 4f 75 74 29 20 29  erp), pResOut) )
4910: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
4920: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
4930: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
4940: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
4950: 41 63 63 65 73 73 28 50 41 52 45 4e 54 56 46 53  Access(PARENTVFS
4960: 28 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 66  (pVfs), zPath, f
4970: 6c 61 67 73 2c 20 70 52 65 73 4f 75 74 29 3b 0a  lags, pResOut);.
4980: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74  }../*.** Populat
4990: 65 20 62 75 66 66 65 72 20 7a 4f 75 74 20 77 69  e buffer zOut wi
49a0: 74 68 20 74 68 65 20 66 75 6c 6c 20 63 61 6e 6f  th the full cano
49b0: 6e 69 63 61 6c 20 70 61 74 68 6e 61 6d 65 20 63  nical pathname c
49c0: 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20  orresponding.** 
49d0: 74 6f 20 74 68 65 20 70 61 74 68 6e 61 6d 65 20  to the pathname 
49e0: 69 6e 20 7a 50 61 74 68 2e 20 7a 4f 75 74 20 69  in zPath. zOut i
49f0: 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20  s guaranteed to 
4a00: 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65  point to a buffe
4a10: 72 0a 2a 2a 20 6f 66 20 61 74 20 6c 65 61 73 74  r.** of at least
4a20: 20 28 44 45 56 53 59 4d 5f 4d 41 58 5f 50 41 54   (DEVSYM_MAX_PAT
4a30: 48 4e 41 4d 45 2b 31 29 20 62 79 74 65 73 2e 0a  HNAME+1) bytes..
4a40: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
4a50: 66 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a  fsFullPathname(.
4a60: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70    sqlite3_vfs *p
4a70: 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  Vfs, .  const ch
4a80: 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e  ar *zPath, .  in
4a90: 74 20 6e 4f 75 74 2c 20 0a 20 20 63 68 61 72 20  t nOut, .  char 
4aa0: 2a 7a 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74 76  *zOut.){.  Testv
4ab0: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
4ac0: 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74   *)pVfs->pAppDat
4ad0: 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  a;.  if( p->pScr
4ae0: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
4af0: 45 53 54 56 46 53 5f 46 55 4c 4c 50 41 54 48 4e  ESTVFS_FULLPATHN
4b00: 41 4d 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20  AME_MASK ){.    
4b10: 69 6e 74 20 72 63 3b 0a 20 20 20 20 74 76 66 73  int rc;.    tvfs
4b20: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 46 75 6c  ExecTcl(p, "xFul
4b30: 6c 50 61 74 68 6e 61 6d 65 22 2c 20 54 63 6c 5f  lPathname", Tcl_
4b40: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 50 61  NewStringObj(zPa
4b50: 74 68 2c 20 2d 31 29 2c 20 30 2c 20 30 29 3b 0a  th, -1), 0, 0);.
4b60: 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73 75      if( tvfsResu
4b70: 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20 29  ltCode(p, &rc) )
4b80: 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  {.      if( rc!=
4b90: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
4ba0: 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d  rn rc;.    }.  }
4bb0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
4bc0: 33 4f 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  3OsFullPathname(
4bd0: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
4be0: 20 7a 50 61 74 68 2c 20 6e 4f 75 74 2c 20 7a 4f   zPath, nOut, zO
4bf0: 75 74 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20  ut);.}..#ifndef 
4c00: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
4c10: 5f 45 58 54 45 4e 53 49 4f 4e 0a 2f 2a 0a 2a 2a  _EXTENSION./*.**
4c20: 20 4f 70 65 6e 20 74 68 65 20 64 79 6e 61 6d 69   Open the dynami
4c30: 63 20 6c 69 62 72 61 72 79 20 6c 6f 63 61 74 65  c library locate
4c40: 64 20 61 74 20 7a 50 61 74 68 20 61 6e 64 20 72  d at zPath and r
4c50: 65 74 75 72 6e 20 61 20 68 61 6e 64 6c 65 2e 0a  eturn a handle..
4c60: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
4c70: 74 76 66 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74  tvfsDlOpen(sqlit
4c80: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f  e3_vfs *pVfs, co
4c90: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 29  nst char *zPath)
4ca0: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
4cb0: 65 33 4f 73 44 6c 4f 70 65 6e 28 50 41 52 45 4e  e3OsDlOpen(PAREN
4cc0: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74  TVFS(pVfs), zPat
4cd0: 68 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70  h);.}../*.** Pop
4ce0: 75 6c 61 74 65 20 74 68 65 20 62 75 66 66 65 72  ulate the buffer
4cf0: 20 7a 45 72 72 4d 73 67 20 28 73 69 7a 65 20 6e   zErrMsg (size n
4d00: 42 79 74 65 20 62 79 74 65 73 29 20 77 69 74 68  Byte bytes) with
4d10: 20 61 20 68 75 6d 61 6e 20 72 65 61 64 61 62 6c   a human readabl
4d20: 65 0a 2a 2a 20 75 74 66 2d 38 20 73 74 72 69 6e  e.** utf-8 strin
4d30: 67 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65  g describing the
4d40: 20 6d 6f 73 74 20 72 65 63 65 6e 74 20 65 72 72   most recent err
4d50: 6f 72 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 61  or encountered a
4d60: 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a 20 77 69  ssociated .** wi
4d70: 74 68 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61  th dynamic libra
4d80: 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ries..*/.static 
4d90: 76 6f 69 64 20 74 76 66 73 44 6c 45 72 72 6f 72  void tvfsDlError
4da0: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
4db0: 66 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  fs, int nByte, c
4dc0: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20  har *zErrMsg){. 
4dd0: 20 73 71 6c 69 74 65 33 4f 73 44 6c 45 72 72 6f   sqlite3OsDlErro
4de0: 72 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  r(PARENTVFS(pVfs
4df0: 29 2c 20 6e 42 79 74 65 2c 20 7a 45 72 72 4d 73  ), nByte, zErrMs
4e00: 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  g);.}../*.** Ret
4e10: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
4e20: 20 74 68 65 20 73 79 6d 62 6f 6c 20 7a 53 79 6d   the symbol zSym
4e30: 62 6f 6c 20 69 6e 20 74 68 65 20 64 79 6e 61 6d  bol in the dynam
4e40: 69 63 20 6c 69 62 72 61 72 79 20 70 48 61 6e 64  ic library pHand
4e50: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
4e60: 69 64 20 28 2a 74 76 66 73 44 6c 53 79 6d 28 73  id (*tvfsDlSym(s
4e70: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4e80: 2c 20 76 6f 69 64 20 2a 70 2c 20 63 6f 6e 73 74  , void *p, const
4e90: 20 63 68 61 72 20 2a 7a 53 79 6d 29 29 28 76 6f   char *zSym))(vo
4ea0: 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  id){.  return sq
4eb0: 6c 69 74 65 33 4f 73 44 6c 53 79 6d 28 50 41 52  lite3OsDlSym(PAR
4ec0: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 2c  ENTVFS(pVfs), p,
4ed0: 20 7a 53 79 6d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   zSym);.}../*.**
4ee0: 20 43 6c 6f 73 65 20 74 68 65 20 64 79 6e 61 6d   Close the dynam
4ef0: 69 63 20 6c 69 62 72 61 72 79 20 68 61 6e 64 6c  ic library handl
4f00: 65 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  e pHandle..*/.st
4f10: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
4f20: 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 66  Close(sqlite3_vf
4f30: 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70  s *pVfs, void *p
4f40: 48 61 6e 64 6c 65 29 7b 0a 20 20 73 71 6c 69 74  Handle){.  sqlit
4f50: 65 33 4f 73 44 6c 43 6c 6f 73 65 28 50 41 52 45  e3OsDlClose(PARE
4f60: 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 48 61  NTVFS(pVfs), pHa
4f70: 6e 64 6c 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 20  ndle);.}.#endif 
4f80: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  /* SQLITE_OMIT_L
4f90: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f  OAD_EXTENSION */
4fa0: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65  ../*.** Populate
4fb0: 20 74 68 65 20 62 75 66 66 65 72 20 70 6f 69 6e   the buffer poin
4fc0: 74 65 64 20 74 6f 20 62 79 20 7a 42 75 66 4f 75  ted to by zBufOu
4fd0: 74 20 77 69 74 68 20 6e 42 79 74 65 20 62 79 74  t with nByte byt
4fe0: 65 73 20 6f 66 20 0a 2a 2a 20 72 61 6e 64 6f 6d  es of .** random
4ff0: 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63   data..*/.static
5000: 20 69 6e 74 20 74 76 66 73 52 61 6e 64 6f 6d 6e   int tvfsRandomn
5010: 65 73 73 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ess(sqlite3_vfs 
5020: 2a 70 56 66 73 2c 20 69 6e 74 20 6e 42 79 74 65  *pVfs, int nByte
5030: 2c 20 63 68 61 72 20 2a 7a 42 75 66 4f 75 74 29  , char *zBufOut)
5040: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
5050: 65 33 4f 73 52 61 6e 64 6f 6d 6e 65 73 73 28 50  e3OsRandomness(P
5060: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
5070: 6e 42 79 74 65 2c 20 7a 42 75 66 4f 75 74 29 3b  nByte, zBufOut);
5080: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6c 65 65 70 20  .}../*.** Sleep 
5090: 66 6f 72 20 6e 4d 69 63 72 6f 20 6d 69 63 72 6f  for nMicro micro
50a0: 73 65 63 6f 6e 64 73 2e 20 52 65 74 75 72 6e 20  seconds. Return 
50b0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69  the number of mi
50c0: 63 72 6f 73 65 63 6f 6e 64 73 20 0a 2a 2a 20 61  croseconds .** a
50d0: 63 74 75 61 6c 6c 79 20 73 6c 65 70 74 2e 0a 2a  ctually slept..*
50e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
50f0: 73 53 6c 65 65 70 28 73 71 6c 69 74 65 33 5f 76  sSleep(sqlite3_v
5100: 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 4d  fs *pVfs, int nM
5110: 69 63 72 6f 29 7b 0a 20 20 72 65 74 75 72 6e 20  icro){.  return 
5120: 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 50  sqlite3OsSleep(P
5130: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
5140: 6e 4d 69 63 72 6f 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  nMicro);.}../*.*
5150: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72  * Return the cur
5160: 72 65 6e 74 20 74 69 6d 65 20 61 73 20 61 20 4a  rent time as a J
5170: 75 6c 69 61 6e 20 44 61 79 20 6e 75 6d 62 65 72  ulian Day number
5180: 20 69 6e 20 2a 70 54 69 6d 65 4f 75 74 2e 0a 2a   in *pTimeOut..*
5190: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
51a0: 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71 6c  sCurrentTime(sql
51b0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
51c0: 64 6f 75 62 6c 65 20 2a 70 54 69 6d 65 4f 75 74  double *pTimeOut
51d0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 50 41 52 45  ){.  return PARE
51e0: 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 78 43 75  NTVFS(pVfs)->xCu
51f0: 72 72 65 6e 74 54 69 6d 65 28 50 41 52 45 4e 54  rrentTime(PARENT
5200: 56 46 53 28 70 56 66 73 29 2c 20 70 54 69 6d 65  VFS(pVfs), pTime
5210: 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  Out);.}..static 
5220: 69 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28  int tvfsShmOpen(
5230: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
5240: 69 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 20  ile){.  Testvfs 
5250: 2a 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  *p;.  int rc = S
5260: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
5270: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
5280: 63 6f 64 65 20 2a 2f 0a 20 20 54 65 73 74 76 66  code */.  Testvf
5290: 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  sBuffer *pBuffer
52a0: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66  ;         /* Buf
52b0: 66 65 72 20 74 6f 20 6f 70 65 6e 20 63 6f 6e 6e  fer to open conn
52c0: 65 63 74 69 6f 6e 20 74 6f 20 2a 2f 0a 20 20 54  ection to */.  T
52d0: 65 73 74 76 66 73 46 64 20 2a 70 46 64 3b 20 20  estvfsFd *pFd;  
52e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
52f0: 2a 20 54 68 65 20 74 65 73 74 76 66 73 20 66 69  * The testvfs fi
5300: 6c 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  le structure */.
5310: 0a 20 20 70 46 64 20 3d 20 74 76 66 73 47 65 74  .  pFd = tvfsGet
5320: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 70 20 3d  Fd(pFile);.  p =
5330: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
5340: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
5350: 0a 20 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e  .  assert( pFd->
5360: 70 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70  pShmId && pFd->p
5370: 53 68 6d 3d 3d 30 20 26 26 20 70 46 64 2d 3e 70  Shm==0 && pFd->p
5380: 4e 65 78 74 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a  Next==0 );..  /*
5390: 20 45 76 61 6c 75 61 74 65 20 74 68 65 20 54 63   Evaluate the Tc
53a0: 6c 20 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a  l script: .  **.
53b0: 20 20 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53    **   SCRIPT xS
53c0: 68 6d 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45 0a  hmOpen FILENAME.
53d0: 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74    */.  Tcl_Reset
53e0: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
53f0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  );.  if( p->pScr
5400: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
5410: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
5420: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
5430: 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4f  xecTcl(p, "xShmO
5440: 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pen", Tcl_NewStr
5450: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c  ingObj(pFd->zFil
5460: 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30 2c 20 30  ename, -1), 0, 0
5470: 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52  );.    if( tvfsR
5480: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
5490: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72  ) ){.      if( r
54a0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
54b0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
54c0: 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72    }..  assert( r
54d0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
54e0: 20 20 69 66 28 20 70 2d 3e 6d 61 73 6b 26 54 45    if( p->mask&TE
54f0: 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41  STVFS_SHMOPEN_MA
5500: 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74  SK && tvfsInject
5510: 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20  Ioerr(p) ){.    
5520: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
5530: 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  ERR;.  }..  /* S
5540: 65 61 72 63 68 20 66 6f 72 20 61 20 54 65 73 74  earch for a Test
5550: 76 66 73 42 75 66 66 65 72 2e 20 43 72 65 61 74  vfsBuffer. Creat
5560: 65 20 61 20 6e 65 77 20 6f 6e 65 20 69 66 20 72  e a new one if r
5570: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 66 6f  equired. */.  fo
5580: 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75  r(pBuffer=p->pBu
5590: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70  ffer; pBuffer; p
55a0: 42 75 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e  Buffer=pBuffer->
55b0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
55c0: 30 3d 3d 73 74 72 63 6d 70 28 70 46 64 2d 3e 7a  0==strcmp(pFd->z
55d0: 46 69 6c 65 6e 61 6d 65 2c 20 70 42 75 66 66 65  Filename, pBuffe
55e0: 72 2d 3e 7a 46 69 6c 65 29 20 29 20 62 72 65 61  r->zFile) ) brea
55f0: 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 21 70 42  k;.  }.  if( !pB
5600: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 69 6e 74  uffer ){.    int
5610: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
5620: 54 65 73 74 76 66 73 42 75 66 66 65 72 29 20 2b  TestvfsBuffer) +
5630: 20 73 74 72 6c 65 6e 28 70 46 64 2d 3e 7a 46 69   strlen(pFd->zFi
5640: 6c 65 6e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 20  lename) + 1;.   
5650: 20 70 42 75 66 66 65 72 20 3d 20 28 54 65 73 74   pBuffer = (Test
5660: 76 66 73 42 75 66 66 65 72 20 2a 29 63 6b 61 6c  vfsBuffer *)ckal
5670: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
5680: 6d 65 6d 73 65 74 28 70 42 75 66 66 65 72 2c 20  memset(pBuffer, 
5690: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  0, nByte);.    p
56a0: 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 20 3d 20  Buffer->zFile = 
56b0: 28 63 68 61 72 20 2a 29 26 70 42 75 66 66 65 72  (char *)&pBuffer
56c0: 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28  [1];.    strcpy(
56d0: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
56e0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b  pFd->zFilename);
56f0: 0a 20 20 20 20 70 42 75 66 66 65 72 2d 3e 70 4e  .    pBuffer->pN
5700: 65 78 74 20 3d 20 70 2d 3e 70 42 75 66 66 65 72  ext = p->pBuffer
5710: 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66 66 65 72  ;.    p->pBuffer
5720: 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 7d 0a   = pBuffer;.  }.
5730: 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74 20 74 68  .  /* Connect th
5740: 65 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e TestvfsBuffer 
5750: 74 6f 20 74 68 65 20 6e 65 77 20 54 65 73 74 76  to the new Testv
5760: 66 73 53 68 6d 20 68 61 6e 64 6c 65 20 61 6e 64  fsShm handle and
5770: 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 70 46   return. */.  pF
5780: 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42 75 66 66  d->pNext = pBuff
5790: 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20 70 42 75  er->pFile;.  pBu
57a0: 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46  ffer->pFile = pF
57b0: 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d  d;.  pFd->pShm =
57c0: 20 70 42 75 66 66 65 72 3b 0a 20 20 72 65 74 75   pBuffer;.  retu
57d0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
57e0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66  .static void tvf
57f0: 73 41 6c 6c 6f 63 50 61 67 65 28 54 65 73 74 76  sAllocPage(Testv
5800: 66 73 42 75 66 66 65 72 20 2a 70 2c 20 69 6e 74  fsBuffer *p, int
5810: 20 69 50 61 67 65 2c 20 69 6e 74 20 70 67 73 7a   iPage, int pgsz
5820: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61  ){.  assert( iPa
5830: 67 65 3c 54 45 53 54 56 46 53 5f 4d 41 58 5f 50  ge<TESTVFS_MAX_P
5840: 41 47 45 53 20 29 3b 0a 20 20 69 66 28 20 70 2d  AGES );.  if( p-
5850: 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 3d 3d 30  >aPage[iPage]==0
5860: 20 29 7b 0a 20 20 20 20 70 2d 3e 61 50 61 67 65   ){.    p->aPage
5870: 5b 69 50 61 67 65 5d 20 3d 20 28 75 38 20 2a 29  [iPage] = (u8 *)
5880: 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20  ckalloc(pgsz);. 
5890: 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 61 50 61     memset(p->aPa
58a0: 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c 20 70 67  ge[iPage], 0, pg
58b0: 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70 67 73 7a  sz);.    p->pgsz
58c0: 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a 7d 0a 0a   = pgsz;.  }.}..
58d0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
58e0: 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33  hmMap(.  sqlite3
58f0: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20  _file *pFile,   
5900: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64           /* Hand
5910: 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62  le open on datab
5920: 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  ase file */.  in
5930: 74 20 69 50 61 67 65 2c 20 20 20 20 20 20 20 20  t iPage,        
5940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5950: 20 50 61 67 65 20 74 6f 20 72 65 74 72 69 65 76   Page to retriev
5960: 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 2c  e */.  int pgsz,
5970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5980: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
5990: 66 20 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74  f pages */.  int
59a0: 20 69 73 57 72 69 74 65 2c 20 20 20 20 20 20 20   isWrite,       
59b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
59c0: 54 72 75 65 20 74 6f 20 65 78 74 65 6e 64 20 66  True to extend f
59d0: 69 6c 65 20 69 66 20 6e 65 63 65 73 73 61 72 79  ile if necessary
59e0: 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f 6c 61 74   */.  void volat
59f0: 69 6c 65 20 2a 2a 70 70 20 20 20 20 20 20 20 20  ile **pp        
5a00: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4d 61        /* OUT: Ma
5a10: 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 29  pped memory */.)
5a20: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
5a30: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
5a40: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
5a50: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
5a60: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
5a70: 74 76 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66  tvfs *)(pFd->pVf
5a80: 73 2d 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20  s->pAppData);.. 
5a90: 20 69 66 28 20 30 3d 3d 70 46 64 2d 3e 70 53 68   if( 0==pFd->pSh
5aa0: 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 74 76  m ){.    rc = tv
5ab0: 66 73 53 68 6d 4f 70 65 6e 28 70 46 69 6c 65 29  fsShmOpen(pFile)
5ac0: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
5ad0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
5ae0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
5af0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e  }.  }..  if( p->
5b00: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
5b10: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41  sk&TESTVFS_SHMMA
5b20: 50 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54 63  P_MASK ){.    Tc
5b30: 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54 63  l_Obj *pArg = Tc
5b40: 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20  l_NewObj();.    
5b50: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
5b60: 28 70 41 72 67 29 3b 0a 20 20 20 20 54 63 6c 5f  (pArg);.    Tcl_
5b70: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
5b80: 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ment(p->interp, 
5b90: 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pArg, Tcl_NewInt
5ba0: 4f 62 6a 28 69 50 61 67 65 29 29 3b 0a 20 20 20  Obj(iPage));.   
5bb0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
5bc0: 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74  ndElement(p->int
5bd0: 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e  erp, pArg, Tcl_N
5be0: 65 77 49 6e 74 4f 62 6a 28 70 67 73 7a 29 29 3b  ewIntObj(pgsz));
5bf0: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
5c00: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
5c10: 3e 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54  >interp, pArg, T
5c20: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 73 57  cl_NewIntObj(isW
5c30: 72 69 74 65 29 29 3b 0a 20 20 20 20 74 76 66 73  rite));.    tvfs
5c40: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d  ExecTcl(p, "xShm
5c50: 4d 61 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54  Map", .        T
5c60: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
5c70: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
5c80: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
5c90: 49 64 2c 20 70 41 72 67 0a 20 20 20 20 29 3b 0a  Id, pArg.    );.
5ca0: 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f      tvfsResultCo
5cb0: 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 20 20  de(p, &rc);.    
5cc0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
5cd0: 28 70 41 72 67 29 3b 0a 20 20 7d 0a 20 20 69 66  (pArg);.  }.  if
5ce0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5cf0: 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56  && p->mask&TESTV
5d00: 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 26  FS_SHMMAP_MASK &
5d10: 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72  & tvfsInjectIoer
5d20: 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d  r(p) ){.    rc =
5d30: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20   SQLITE_IOERR;. 
5d40: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
5d50: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73 57 72 69  LITE_OK && isWri
5d60: 74 65 20 26 26 20 21 70 46 64 2d 3e 70 53 68 6d  te && !pFd->pShm
5d70: 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 20 29  ->aPage[iPage] )
5d80: 7b 0a 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50  {.    tvfsAllocP
5d90: 61 67 65 28 70 46 64 2d 3e 70 53 68 6d 2c 20 69  age(pFd->pShm, i
5da0: 50 61 67 65 2c 20 70 67 73 7a 29 3b 0a 20 20 7d  Page, pgsz);.  }
5db0: 0a 20 20 2a 70 70 20 3d 20 28 76 6f 69 64 20 76  .  *pp = (void v
5dc0: 6f 6c 61 74 69 6c 65 20 2a 29 70 46 64 2d 3e 70  olatile *)pFd->p
5dd0: 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50 61 67 65  Shm->aPage[iPage
5de0: 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ];..  return rc;
5df0: 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  .}...static int 
5e00: 74 76 66 73 53 68 6d 4c 6f 63 6b 28 0a 20 20 73  tvfsShmLock(.  s
5e10: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
5e20: 6c 65 2c 0a 20 20 69 6e 74 20 6f 66 73 74 2c 0a  le,.  int ofst,.
5e30: 20 20 69 6e 74 20 6e 2c 0a 20 20 69 6e 74 20 66    int n,.  int f
5e40: 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63  lags.){.  int rc
5e50: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
5e60: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
5e70: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
5e80: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
5e90: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46  = (Testvfs *)(pF
5ea0: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
5eb0: 61 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b  a);.  int nLock;
5ec0: 0a 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 38 30  .  char zLock[80
5ed0: 5d 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  ];..  if( p->pSc
5ee0: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
5ef0: 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f  TESTVFS_SHMLOCK_
5f00: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  MASK ){.    sqli
5f10: 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
5f20: 65 6f 66 28 7a 4c 6f 63 6b 29 2c 20 7a 4c 6f 63  eof(zLock), zLoc
5f30: 6b 2c 20 22 25 64 20 25 64 22 2c 20 6f 66 73 74  k, "%d %d", ofst
5f40: 2c 20 6e 29 3b 0a 20 20 20 20 6e 4c 6f 63 6b 20  , n);.    nLock 
5f50: 3d 20 73 74 72 6c 65 6e 28 7a 4c 6f 63 6b 29 3b  = strlen(zLock);
5f60: 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 26  .    if( flags &
5f70: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b   SQLITE_SHM_LOCK
5f80: 20 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79   ){.      strcpy
5f90: 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20  (&zLock[nLock], 
5fa0: 22 20 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d 65  " lock");.    }e
5fb0: 6c 73 65 7b 0a 20 20 20 20 20 20 73 74 72 63 70  lse{.      strcp
5fc0: 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c  y(&zLock[nLock],
5fd0: 20 22 20 75 6e 6c 6f 63 6b 22 29 3b 0a 20 20 20   " unlock");.   
5fe0: 20 7d 0a 20 20 20 20 6e 4c 6f 63 6b 20 2b 3d 20   }.    nLock += 
5ff0: 73 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e 4c  strlen(&zLock[nL
6000: 6f 63 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20 66  ock]);.    if( f
6010: 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48  lags & SQLITE_SH
6020: 4d 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20 20  M_SHARED ){.    
6030: 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b    strcpy(&zLock[
6040: 6e 4c 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65 64  nLock], " shared
6050: 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ");.    }else{. 
6060: 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f       strcpy(&zLo
6070: 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78 63  ck[nLock], " exc
6080: 6c 75 73 69 76 65 22 29 3b 0a 20 20 20 20 7d 0a  lusive");.    }.
6090: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
60a0: 70 2c 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 0a  p, "xShmLock", .
60b0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
60c0: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53  tringObj(pFd->pS
60d0: 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20  hm->zFile, -1), 
60e0: 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20 20  pFd->pShmId,.   
60f0: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
6100: 6e 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31 29  ngObj(zLock, -1)
6110: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
6120: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
6130: 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  c);.  }..  if( r
6140: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
6150: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
6160: 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 26 26 20  SHMLOCK_MASK && 
6170: 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28  tvfsInjectIoerr(
6180: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  p) ){.    rc = S
6190: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d  QLITE_IOERR;.  }
61a0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
61b0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
61c0: 20 69 73 4c 6f 63 6b 20 3d 20 28 66 6c 61 67 73   isLock = (flags
61d0: 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f   & SQLITE_SHM_LO
61e0: 43 4b 29 3b 0a 20 20 20 20 69 6e 74 20 69 73 45  CK);.    int isE
61f0: 78 63 6c 20 3d 20 28 66 6c 61 67 73 20 26 20 53  xcl = (flags & S
6200: 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53  QLITE_SHM_EXCLUS
6210: 49 56 45 29 3b 0a 20 20 20 20 75 33 32 20 6d 61  IVE);.    u32 ma
6220: 73 6b 20 3d 20 28 28 28 31 3c 3c 6e 29 2d 31 29  sk = (((1<<n)-1)
6230: 20 3c 3c 20 6f 66 73 74 29 3b 0a 20 20 20 20 69   << ofst);.    i
6240: 66 28 20 69 73 4c 6f 63 6b 20 29 7b 0a 20 20 20  f( isLock ){.   
6250: 20 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 32     TestvfsFd *p2
6260: 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 32 3d 70  ;.      for(p2=p
6270: 46 64 2d 3e 70 53 68 6d 2d 3e 70 46 69 6c 65 3b  Fd->pShm->pFile;
6280: 20 70 32 3b 20 70 32 3d 70 32 2d 3e 70 4e 65 78   p2; p2=p2->pNex
6290: 74 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t){.        if( 
62a0: 70 32 3d 3d 70 46 64 20 29 20 63 6f 6e 74 69 6e  p2==pFd ) contin
62b0: 75 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ue;.        if( 
62c0: 28 70 32 2d 3e 65 78 63 6c 6c 6f 63 6b 26 6d 61  (p2->excllock&ma
62d0: 73 6b 29 20 7c 7c 20 28 69 73 45 78 63 6c 20 26  sk) || (isExcl &
62e0: 26 20 70 32 2d 3e 73 68 61 72 65 64 6c 6f 63 6b  & p2->sharedlock
62f0: 26 6d 61 73 6b 29 20 29 7b 0a 20 20 20 20 20 20  &mask) ){.      
6300: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
6310: 42 55 53 59 3b 0a 20 20 20 20 20 20 20 20 20 20  BUSY;.          
6320: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
6330: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
6340: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6350: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
6360: 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65  isExcl )  pFd->e
6370: 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b  xcllock |= mask;
6380: 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 69 73  .        if( !is
6390: 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72  Excl ) pFd->shar
63a0: 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b 0a  edlock |= mask;.
63b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
63c0: 65 7b 0a 20 20 20 20 20 20 69 66 28 20 69 73 45  e{.      if( isE
63d0: 78 63 6c 20 29 20 20 70 46 64 2d 3e 65 78 63 6c  xcl )  pFd->excl
63e0: 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b  lock &= (~mask);
63f0: 0a 20 20 20 20 20 20 69 66 28 20 21 69 73 45 78  .      if( !isEx
6400: 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72 65 64  cl ) pFd->shared
6410: 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b  lock &= (~mask);
6420: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
6430: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
6440: 69 63 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42  ic void tvfsShmB
6450: 61 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66  arrier(sqlite3_f
6460: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
6470: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
6480: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
6490: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
64a0: 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64   (Testvfs *)(pFd
64b0: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
64c0: 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  );..  if( p->pSc
64d0: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
64e0: 54 45 53 54 56 46 53 5f 53 48 4d 42 41 52 52 49  TESTVFS_SHMBARRI
64f0: 45 52 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74  ER_MASK ){.    t
6500: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
6510: 53 68 6d 42 61 72 72 69 65 72 22 2c 20 0a 20 20  ShmBarrier", .  
6520: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
6530: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d  ingObj(pFd->pShm
6540: 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46  ->zFile, -1), pF
6550: 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20 20  d->pShmId, 0.   
6560: 20 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69   );.  }.}..stati
6570: 63 20 69 6e 74 20 74 76 66 73 53 68 6d 55 6e 6d  c int tvfsShmUnm
6580: 61 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  ap(.  sqlite3_fi
6590: 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69 6e 74  le *pFile,.  int
65a0: 20 64 65 6c 65 74 65 46 6c 61 67 0a 29 7b 0a 20   deleteFlag.){. 
65b0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
65c0: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
65d0: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
65e0: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
65f0: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
6600: 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e  s *)(pFd->pVfs->
6610: 70 41 70 70 44 61 74 61 29 3b 0a 20 20 54 65 73  pAppData);.  Tes
6620: 74 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66  tvfsBuffer *pBuf
6630: 66 65 72 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b  fer = pFd->pShm;
6640: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 2a 70  .  TestvfsFd **p
6650: 70 46 64 3b 0a 0a 20 20 69 66 28 20 21 70 42 75  pFd;..  if( !pBu
6660: 66 66 65 72 20 29 20 72 65 74 75 72 6e 20 53 51  ffer ) return SQ
6670: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61 73 73 65 72  LITE_OK;.  asser
6680: 74 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26  t( pFd->pShmId &
6690: 26 20 70 46 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a  & pFd->pShm );..
66a0: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
66b0: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
66c0: 56 46 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53  VFS_SHMCLOSE_MAS
66d0: 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65  K ){.    tvfsExe
66e0: 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 55 6e 6d  cTcl(p, "xShmUnm
66f0: 61 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  ap", .        Tc
6700: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
6710: 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c  Fd->pShm->zFile,
6720: 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49   -1), pFd->pShmI
6730: 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20  d, 0.    );.    
6740: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
6750: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 66  , &rc);.  }..  f
6760: 6f 72 28 70 70 46 64 3d 26 70 42 75 66 66 65 72  or(ppFd=&pBuffer
6770: 2d 3e 70 46 69 6c 65 3b 20 2a 70 70 46 64 21 3d  ->pFile; *ppFd!=
6780: 70 46 64 3b 20 70 70 46 64 3d 26 28 28 2a 70 70  pFd; ppFd=&((*pp
6790: 46 64 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20  Fd)->pNext));.  
67a0: 61 73 73 65 72 74 28 20 28 2a 70 70 46 64 29 3d  assert( (*ppFd)=
67b0: 3d 70 46 64 20 29 3b 0a 20 20 2a 70 70 46 64 20  =pFd );.  *ppFd 
67c0: 3d 20 70 46 64 2d 3e 70 4e 65 78 74 3b 0a 20 20  = pFd->pNext;.  
67d0: 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a  pFd->pNext = 0;.
67e0: 0a 20 20 69 66 28 20 70 42 75 66 66 65 72 2d 3e  .  if( pBuffer->
67f0: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
6800: 69 6e 74 20 69 3b 0a 20 20 20 20 54 65 73 74 76  int i;.    Testv
6810: 66 73 42 75 66 66 65 72 20 2a 2a 70 70 3b 0a 20  fsBuffer **pp;. 
6820: 20 20 20 66 6f 72 28 70 70 3d 26 70 2d 3e 70 42     for(pp=&p->pB
6830: 75 66 66 65 72 3b 20 2a 70 70 21 3d 70 42 75 66  uffer; *pp!=pBuf
6840: 66 65 72 3b 20 70 70 3d 26 28 28 2a 70 70 29 2d  fer; pp=&((*pp)-
6850: 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 2a 70  >pNext));.    *p
6860: 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74  p = (*pp)->pNext
6870: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 70  ;.    for(i=0; p
6880: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
6890: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6b  ; i++){.      ck
68a0: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 42 75  free((char *)pBu
68b0: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 29 3b  ffer->aPage[i]);
68c0: 0a 20 20 20 20 7d 0a 20 20 20 20 63 6b 66 72 65  .    }.    ckfre
68d0: 65 28 28 63 68 61 72 20 2a 29 70 42 75 66 66 65  e((char *)pBuffe
68e0: 72 29 3b 0a 20 20 7d 0a 20 20 70 46 64 2d 3e 70  r);.  }.  pFd->p
68f0: 53 68 6d 20 3d 20 30 3b 0a 0a 20 20 72 65 74 75  Shm = 0;..  retu
6900: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
6910: 20 69 6e 74 20 74 65 73 74 76 66 73 5f 6f 62 6a   int testvfs_obj
6920: 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61  _cmd(.  ClientDa
6930: 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74  ta cd,.  Tcl_Int
6940: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
6950: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
6960: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
6970: 0a 29 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  .){.  Testvfs *p
6980: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63 64   = (Testvfs *)cd
6990: 3b 0a 0a 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75  ;..  enum DB_enu
69a0: 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f 53 48 4d  m { .    CMD_SHM
69b0: 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c 20 43 4d  , CMD_DELETE, CM
69c0: 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44 5f 49 4f  D_FILTER, CMD_IO
69d0: 45 52 52 2c 20 43 4d 44 5f 53 43 52 49 50 54 2c  ERR, CMD_SCRIPT,
69e0: 20 0a 20 20 20 20 43 4d 44 5f 44 45 56 43 48 41   .    CMD_DEVCHA
69f0: 52 2c 20 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a  R, CMD_SECTORSIZ
6a00: 45 2c 20 43 4d 44 5f 46 55 4c 4c 45 52 52 2c 20  E, CMD_FULLERR, 
6a10: 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 0a  CMD_CANTOPENERR.
6a20: 20 20 7d 3b 0a 20 20 73 74 72 75 63 74 20 54 65    };.  struct Te
6a30: 73 74 76 66 73 53 75 62 63 6d 64 20 7b 0a 20 20  stvfsSubcmd {.  
6a40: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
6a50: 20 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20     enum DB_enum 
6a60: 65 43 6d 64 3b 0a 20 20 7d 20 61 53 75 62 63 6d  eCmd;.  } aSubcm
6a70: 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73  d[] = {.    { "s
6a80: 68 6d 22 2c 20 20 20 20 20 20 20 20 20 43 4d 44  hm",         CMD
6a90: 5f 53 48 4d 20 20 20 20 20 20 20 20 20 7d 2c 0a  _SHM         },.
6aa0: 20 20 20 20 7b 20 22 64 65 6c 65 74 65 22 2c 20      { "delete", 
6ab0: 20 20 20 20 20 43 4d 44 5f 44 45 4c 45 54 45 20       CMD_DELETE 
6ac0: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66       },.    { "f
6ad0: 69 6c 74 65 72 22 2c 20 20 20 20 20 20 43 4d 44  ilter",      CMD
6ae0: 5f 46 49 4c 54 45 52 20 20 20 20 20 20 7d 2c 0a  _FILTER      },.
6af0: 20 20 20 20 7b 20 22 69 6f 65 72 72 22 2c 20 20      { "ioerr",  
6b00: 20 20 20 20 20 43 4d 44 5f 49 4f 45 52 52 20 20       CMD_IOERR  
6b10: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66       },.    { "f
6b20: 75 6c 6c 65 72 72 22 2c 20 20 20 20 20 43 4d 44  ullerr",     CMD
6b30: 5f 46 55 4c 4c 45 52 52 20 20 20 20 20 7d 2c 0a  _FULLERR     },.
6b40: 20 20 20 20 7b 20 22 63 61 6e 74 6f 70 65 6e 65      { "cantopene
6b50: 72 72 22 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45  rr", CMD_CANTOPE
6b60: 4e 45 52 52 20 7d 2c 0a 20 20 20 20 7b 20 22 73  NERR },.    { "s
6b70: 63 72 69 70 74 22 2c 20 20 20 20 20 20 43 4d 44  cript",      CMD
6b80: 5f 53 43 52 49 50 54 20 20 20 20 20 20 7d 2c 0a  _SCRIPT      },.
6b90: 20 20 20 20 7b 20 22 64 65 76 63 68 61 72 22 2c      { "devchar",
6ba0: 20 20 20 20 20 43 4d 44 5f 44 45 56 43 48 41 52       CMD_DEVCHAR
6bb0: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 73       },.    { "s
6bc0: 65 63 74 6f 72 73 69 7a 65 22 2c 20 20 43 4d 44  ectorsize",  CMD
6bd0: 5f 53 45 43 54 4f 52 53 49 5a 45 20 20 7d 2c 0a  _SECTORSIZE  },.
6be0: 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 7d      { 0, 0 }.  }
6bf0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 0a 20 20  ;.  int i;.  .  
6c00: 69 66 28 20 6f 62 6a 63 3c 32 20 29 7b 0a 20 20  if( objc<2 ){.  
6c10: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
6c20: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
6c30: 6a 76 2c 20 22 53 55 42 43 4f 4d 4d 41 4e 44 20  jv, "SUBCOMMAND 
6c40: 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 65 74 75 72  ...");.    retur
6c50: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
6c60: 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e  .  if( Tcl_GetIn
6c70: 64 65 78 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74  dexFromObjStruct
6c80: 28 0a 20 20 20 20 20 20 20 20 69 6e 74 65 72 70  (.        interp
6c90: 2c 20 6f 62 6a 76 5b 31 5d 2c 20 61 53 75 62 63  , objv[1], aSubc
6ca0: 6d 64 2c 20 73 69 7a 65 6f 66 28 61 53 75 62 63  md, sizeof(aSubc
6cb0: 6d 64 5b 30 5d 29 2c 20 22 73 75 62 63 6f 6d 6d  md[0]), "subcomm
6cc0: 61 6e 64 22 2c 20 30 2c 20 26 69 29 20 0a 20 20  and", 0, &i) .  
6cd0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  ){.    return TC
6ce0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54  L_ERROR;.  }.  T
6cf0: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
6d00: 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77 69 74 63  nterp);..  switc
6d10: 68 28 20 61 53 75 62 63 6d 64 5b 69 5d 2e 65 43  h( aSubcmd[i].eC
6d20: 6d 64 20 29 7b 0a 20 20 20 20 63 61 73 65 20 43  md ){.    case C
6d30: 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20 20 20 20  MD_SHM: {.      
6d40: 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20  Tcl_Obj *pObj;. 
6d50: 20 20 20 20 20 69 6e 74 20 69 2c 20 72 63 3b 0a       int i, rc;.
6d60: 20 20 20 20 20 20 54 65 73 74 76 66 73 42 75 66        TestvfsBuf
6d70: 66 65 72 20 2a 70 42 75 66 66 65 72 3b 0a 20 20  fer *pBuffer;.  
6d80: 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b      char *zName;
6d90: 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21  .      if( objc!
6da0: 3d 33 20 26 26 20 6f 62 6a 63 21 3d 34 20 29 7b  =3 && objc!=4 ){
6db0: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f  .        Tcl_Wro
6dc0: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
6dd0: 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45  , 2, objv, "FILE
6de0: 20 3f 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20   ?VALUE?");.    
6df0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
6e00: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
6e10: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 63 6b 61 6c      zName = ckal
6e20: 6c 6f 63 28 70 2d 3e 70 50 61 72 65 6e 74 2d 3e  loc(p->pParent->
6e30: 6d 78 50 61 74 68 6e 61 6d 65 29 3b 0a 20 20 20  mxPathname);.   
6e40: 20 20 20 72 63 20 3d 20 70 2d 3e 70 50 61 72 65     rc = p->pPare
6e50: 6e 74 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d  nt->xFullPathnam
6e60: 65 28 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  e(.          p->
6e70: 70 50 61 72 65 6e 74 2c 20 54 63 6c 5f 47 65 74  pParent, Tcl_Get
6e80: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c  String(objv[2]),
6e90: 20 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70   .          p->p
6ea0: 50 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68 6e 61  Parent->mxPathna
6eb0: 6d 65 2c 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20  me, zName.      
6ec0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
6ed0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
6ee0: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
6ef0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
6f00: 66 61 69 6c 65 64 20 74 6f 20 67 65 74 20 66 75  failed to get fu
6f10: 6c 6c 20 70 61 74 68 3a 20 22 2c 0a 20 20 20 20  ll path: ",.    
6f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f30: 20 20 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69       Tcl_GetStri
6f40: 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b  ng(objv[2]), 0);
6f50: 0a 20 20 20 20 20 20 20 20 63 6b 66 72 65 65 28  .        ckfree(
6f60: 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 20 20  zName);.        
6f70: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6f80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6f90: 66 6f 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70  for(pBuffer=p->p
6fa0: 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b  Buffer; pBuffer;
6fb0: 20 70 42 75 66 66 65 72 3d 70 42 75 66 66 65 72   pBuffer=pBuffer
6fc0: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
6fd0: 20 20 69 66 28 20 30 3d 3d 73 74 72 63 6d 70 28    if( 0==strcmp(
6fe0: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
6ff0: 7a 4e 61 6d 65 29 20 29 20 62 72 65 61 6b 3b 0a  zName) ) break;.
7000: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 6b        }.      ck
7010: 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 20  free(zName);.   
7020: 20 20 20 69 66 28 20 21 70 42 75 66 66 65 72 20     if( !pBuffer 
7030: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41  ){.        Tcl_A
7040: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
7050: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 66 69 6c  rp, "no such fil
7060: 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  e: ", Tcl_GetStr
7070: 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29  ing(objv[2]), 0)
7080: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7090: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
70a0: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f 62    }.      if( ob
70b0: 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20 20  jc==4 ){.       
70c0: 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20   int n;.        
70d0: 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47 65 74 42  u8 *a = Tcl_GetB
70e0: 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28  yteArrayFromObj(
70f0: 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b 0a 20 20  objv[3], &n);.  
7100: 20 20 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d        int pgsz =
7110: 20 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b 0a   pBuffer->pgsz;.
7120: 20 20 20 20 20 20 20 20 69 66 28 20 70 67 73 7a          if( pgsz
7130: 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20 36 35 35  ==0 ) pgsz = 655
7140: 33 36 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  36;.        for(
7150: 69 3d 30 3b 20 69 2a 70 67 73 7a 3c 6e 3b 20 69  i=0; i*pgsz<n; i
7160: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ++){.          i
7170: 6e 74 20 6e 42 79 74 65 20 3d 20 70 67 73 7a 3b  nt nByte = pgsz;
7180: 0a 20 20 20 20 20 20 20 20 20 20 74 76 66 73 41  .          tvfsA
7190: 6c 6c 6f 63 50 61 67 65 28 70 42 75 66 66 65 72  llocPage(pBuffer
71a0: 2c 20 69 2c 20 70 67 73 7a 29 3b 0a 20 20 20 20  , i, pgsz);.    
71b0: 20 20 20 20 20 20 69 66 28 20 6e 2d 69 2a 70 67        if( n-i*pg
71c0: 73 7a 3c 70 67 73 7a 20 29 7b 0a 20 20 20 20 20  sz<pgsz ){.     
71d0: 20 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 6e         nByte = n
71e0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
71f0: 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70          memcpy(p
7200: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
7210: 2c 20 26 61 5b 69 2a 70 67 73 7a 5d 2c 20 6e 42  , &a[i*pgsz], nB
7220: 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  yte);.        }.
7230: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70        }..      p
7240: 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  Obj = Tcl_NewObj
7250: 28 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  ();.      for(i=
7260: 30 3b 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67  0; pBuffer->aPag
7270: 65 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  e[i]; i++){.    
7280: 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70      int pgsz = p
7290: 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b 0a 20 20  Buffer->pgsz;.  
72a0: 20 20 20 20 20 20 69 66 28 20 70 67 73 7a 3d 3d        if( pgsz==
72b0: 30 20 29 20 70 67 73 7a 20 3d 20 36 35 35 33 36  0 ) pgsz = 65536
72c0: 3b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70  ;.        Tcl_Ap
72d0: 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28 70 4f 62  pendObjToObj(pOb
72e0: 6a 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72  j, Tcl_NewByteAr
72f0: 72 61 79 4f 62 6a 28 70 42 75 66 66 65 72 2d 3e  rayObj(pBuffer->
7300: 61 50 61 67 65 5b 69 5d 2c 20 70 67 73 7a 29 29  aPage[i], pgsz))
7310: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
7320: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
7330: 28 69 6e 74 65 72 70 2c 20 70 4f 62 6a 29 3b 0a  (interp, pObj);.
7340: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
7350: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44   }..    case CMD
7360: 5f 46 49 4c 54 45 52 3a 20 7b 0a 20 20 20 20 20  _FILTER: {.     
7370: 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20 56   static struct V
7380: 66 73 4d 65 74 68 6f 64 20 7b 0a 20 20 20 20 20  fsMethod {.     
7390: 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a     char *zName;.
73a0: 20 20 20 20 20 20 20 20 69 6e 74 20 6d 61 73 6b          int mask
73b0: 3b 0a 20 20 20 20 20 20 7d 20 76 66 73 6d 65 74  ;.      } vfsmet
73c0: 68 6f 64 20 5b 5d 20 3d 20 7b 0a 20 20 20 20 20  hod [] = {.     
73d0: 20 20 20 7b 20 22 78 53 68 6d 4f 70 65 6e 22 2c     { "xShmOpen",
73e0: 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 53 48        TESTVFS_SH
73f0: 4d 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20  MOPEN_MASK },.  
7400: 20 20 20 20 20 20 7b 20 22 78 53 68 6d 4c 6f 63        { "xShmLoc
7410: 6b 22 2c 20 20 20 20 20 20 54 45 53 54 56 46 53  k",      TESTVFS
7420: 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 7d 2c  _SHMLOCK_MASK },
7430: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d  .        { "xShm
7440: 42 61 72 72 69 65 72 22 2c 20 20 20 54 45 53 54  Barrier",   TEST
7450: 56 46 53 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d  VFS_SHMBARRIER_M
7460: 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  ASK },.        {
7470: 20 22 78 53 68 6d 55 6e 6d 61 70 22 2c 20 20 20   "xShmUnmap",   
7480: 20 20 54 45 53 54 56 46 53 5f 53 48 4d 43 4c 4f    TESTVFS_SHMCLO
7490: 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  SE_MASK },.     
74a0: 20 20 20 7b 20 22 78 53 68 6d 4d 61 70 22 2c 20     { "xShmMap", 
74b0: 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 53 48        TESTVFS_SH
74c0: 4d 4d 41 50 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  MMAP_MASK },.   
74d0: 20 20 20 20 20 7b 20 22 78 53 79 6e 63 22 2c 20       { "xSync", 
74e0: 20 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f          TESTVFS_
74f0: 53 59 4e 43 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  SYNC_MASK },.   
7500: 20 20 20 20 20 7b 20 22 78 44 65 6c 65 74 65 22       { "xDelete"
7510: 2c 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f  ,       TESTVFS_
7520: 44 45 4c 45 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20  DELETE_MASK },. 
7530: 20 20 20 20 20 20 20 7b 20 22 78 57 72 69 74 65         { "xWrite
7540: 22 2c 20 20 20 20 20 20 20 20 54 45 53 54 56 46  ",        TESTVF
7550: 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 7d 2c 0a  S_WRITE_MASK },.
7560: 20 20 20 20 20 20 20 20 7b 20 22 78 52 65 61 64          { "xRead
7570: 22 2c 20 20 20 20 20 20 20 20 20 54 45 53 54 56  ",         TESTV
7580: 46 53 5f 52 45 41 44 5f 4d 41 53 4b 20 7d 2c 0a  FS_READ_MASK },.
7590: 20 20 20 20 20 20 20 20 7b 20 22 78 54 72 75 6e          { "xTrun
75a0: 63 61 74 65 22 2c 20 20 20 20 20 54 45 53 54 56  cate",     TESTV
75b0: 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53 4b  FS_TRUNCATE_MASK
75c0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
75d0: 4f 70 65 6e 22 2c 20 20 20 20 20 20 20 20 20 54  Open",         T
75e0: 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b  ESTVFS_OPEN_MASK
75f0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
7600: 43 6c 6f 73 65 22 2c 20 20 20 20 20 20 20 20 54  Close",        T
7610: 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d 41 53  ESTVFS_CLOSE_MAS
7620: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
7630: 78 41 63 63 65 73 73 22 2c 20 20 20 20 20 20 20  xAccess",       
7640: 54 45 53 54 56 46 53 5f 41 43 43 45 53 53 5f 4d  TESTVFS_ACCESS_M
7650: 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  ASK },.        {
7660: 20 22 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 22   "xFullPathname"
7670: 2c 20 54 45 53 54 56 46 53 5f 46 55 4c 4c 50 41  , TESTVFS_FULLPA
7680: 54 48 4e 41 4d 45 5f 4d 41 53 4b 20 7d 2c 0a 20  THNAME_MASK },. 
7690: 20 20 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63       };.      Tc
76a0: 6c 5f 4f 62 6a 20 2a 2a 61 70 45 6c 65 6d 20 3d  l_Obj **apElem =
76b0: 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 45   0;.      int nE
76c0: 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  lem = 0;.      i
76d0: 6e 74 20 69 3b 0a 20 20 20 20 20 20 69 6e 74 20  nt i;.      int 
76e0: 6d 61 73 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  mask = 0;.      
76f0: 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20  if( objc!=3 ){. 
7700: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
7710: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
7720: 32 2c 20 6f 62 6a 76 2c 20 22 4c 49 53 54 22 29  2, objv, "LIST")
7730: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7740: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
7750: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 54 63    }.      if( Tc
7760: 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d  l_ListObjGetElem
7770: 65 6e 74 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a  ents(interp, obj
7780: 76 5b 32 5d 2c 20 26 6e 45 6c 65 6d 2c 20 26 61  v[2], &nElem, &a
7790: 70 45 6c 65 6d 29 20 29 7b 0a 20 20 20 20 20 20  pElem) ){.      
77a0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
77b0: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
77c0: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
77d0: 74 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20  t(interp);.     
77e0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 45 6c 65   for(i=0; i<nEle
77f0: 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  m; i++){.       
7800: 20 69 6e 74 20 69 4d 65 74 68 6f 64 3b 0a 20 20   int iMethod;.  
7810: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 45 6c 65        char *zEle
7820: 6d 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  m = Tcl_GetStrin
7830: 67 28 61 70 45 6c 65 6d 5b 69 5d 29 3b 0a 20 20  g(apElem[i]);.  
7840: 20 20 20 20 20 20 66 6f 72 28 69 4d 65 74 68 6f        for(iMetho
7850: 64 3d 30 3b 20 69 4d 65 74 68 6f 64 3c 41 72 72  d=0; iMethod<Arr
7860: 61 79 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64  aySize(vfsmethod
7870: 29 3b 20 69 4d 65 74 68 6f 64 2b 2b 29 7b 0a 20  ); iMethod++){. 
7880: 20 20 20 20 20 20 20 20 20 69 66 28 20 73 74 72           if( str
7890: 63 6d 70 28 7a 45 6c 65 6d 2c 20 76 66 73 6d 65  cmp(zElem, vfsme
78a0: 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e 7a 4e  thod[iMethod].zN
78b0: 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ame)==0 ){.     
78c0: 20 20 20 20 20 20 20 6d 61 73 6b 20 7c 3d 20 76         mask |= v
78d0: 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64  fsmethod[iMethod
78e0: 5d 2e 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20 20  ].mask;.        
78f0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
7900: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
7910: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 4d 65  .        if( iMe
7920: 74 68 6f 64 3d 3d 41 72 72 61 79 53 69 7a 65 28  thod==ArraySize(
7930: 76 66 73 6d 65 74 68 6f 64 29 20 29 7b 0a 20 20  vfsmethod) ){.  
7940: 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65          Tcl_Appe
7950: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
7960: 20 22 75 6e 6b 6e 6f 77 6e 20 6d 65 74 68 6f 64   "unknown method
7970: 3a 20 22 2c 20 7a 45 6c 65 6d 2c 20 30 29 3b 0a  : ", zElem, 0);.
7980: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
7990: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
79a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
79b0: 20 20 20 20 70 2d 3e 6d 61 73 6b 20 3d 20 6d 61      p->mask = ma
79c0: 73 6b 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  sk;.      break;
79d0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
79e0: 20 43 4d 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20   CMD_SCRIPT: {. 
79f0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33       if( objc==3
7a00: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
7a10: 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 20 20 69  nByte;.        i
7a20: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29 7b  f( p->pScript ){
7a30: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 44  .          Tcl_D
7a40: 65 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70  ecrRefCount(p->p
7a50: 53 63 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20  Script);.       
7a60: 20 20 20 70 2d 3e 70 53 63 72 69 70 74 20 3d 20     p->pScript = 
7a70: 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  0;.        }.   
7a80: 20 20 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69       Tcl_GetStri
7a90: 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32  ngFromObj(objv[2
7aa0: 5d 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20  ], &nByte);.    
7ab0: 20 20 20 20 69 66 28 20 6e 42 79 74 65 3e 30 20      if( nByte>0 
7ac0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  ){.          p->
7ad0: 70 53 63 72 69 70 74 20 3d 20 54 63 6c 5f 44 75  pScript = Tcl_Du
7ae0: 70 6c 69 63 61 74 65 4f 62 6a 28 6f 62 6a 76 5b  plicateObj(objv[
7af0: 32 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 54  2]);.          T
7b00: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
7b10: 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 20  p->pScript);.   
7b20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c       }.      }el
7b30: 73 65 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29  se if( objc!=2 )
7b40: 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72  {.        Tcl_Wr
7b50: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
7b60: 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 53 43  p, 2, objv, "?SC
7b70: 52 49 50 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  RIPT?");.       
7b80: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7b90: 52 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  R;.      }..    
7ba0: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
7bb0: 74 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20  t(interp);.     
7bc0: 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20   if( p->pScript 
7bd0: 29 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75  ) Tcl_SetObjResu
7be0: 6c 74 28 69 6e 74 65 72 70 2c 20 70 2d 3e 70 53  lt(interp, p->pS
7bf0: 63 72 69 70 74 29 3b 0a 0a 20 20 20 20 20 20 62  cript);..      b
7c00: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
7c10: 20 2f 2a 0a 20 20 20 20 2a 2a 20 54 45 53 54 56   /*.    ** TESTV
7c20: 46 53 20 69 6f 65 72 72 20 3f 49 46 41 49 4c 20  FS ioerr ?IFAIL 
7c30: 50 45 52 53 49 53 54 3f 0a 20 20 20 20 2a 2a 0a  PERSIST?.    **.
7c40: 20 20 20 20 2a 2a 20 20 20 57 68 65 72 65 20 49      **   Where I
7c50: 46 41 49 4c 20 69 73 20 61 6e 20 69 6e 74 65 67  FAIL is an integ
7c60: 65 72 20 61 6e 64 20 50 45 52 53 49 53 54 20 69  er and PERSIST i
7c70: 73 20 62 6f 6f 6c 65 61 6e 2e 0a 20 20 20 20 2a  s boolean..    *
7c80: 2f 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 43  /.    case CMD_C
7c90: 41 4e 54 4f 50 45 4e 45 52 52 3a 0a 20 20 20 20  ANTOPENERR:.    
7ca0: 63 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a 0a  case CMD_IOERR:.
7cb0: 20 20 20 20 63 61 73 65 20 43 4d 44 5f 46 55 4c      case CMD_FUL
7cc0: 4c 45 52 52 3a 20 7b 0a 20 20 20 20 20 20 54 65  LERR: {.      Te
7cd0: 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 2a 70  stFaultInject *p
7ce0: 54 65 73 74 3b 0a 20 20 20 20 20 20 69 6e 74 20  Test;.      int 
7cf0: 69 52 65 74 3b 0a 0a 20 20 20 20 20 20 73 77 69  iRet;..      swi
7d00: 74 63 68 28 20 61 53 75 62 63 6d 64 5b 69 5d 2e  tch( aSubcmd[i].
7d10: 65 43 6d 64 20 29 7b 0a 20 20 20 20 20 20 20 20  eCmd ){.        
7d20: 63 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a 20  case CMD_IOERR: 
7d30: 70 54 65 73 74 20 3d 20 26 70 2d 3e 69 6f 65 72  pTest = &p->ioer
7d40: 72 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20 20  r_err; break;.  
7d50: 20 20 20 20 20 20 63 61 73 65 20 43 4d 44 5f 46        case CMD_F
7d60: 55 4c 4c 45 52 52 3a 20 70 54 65 73 74 20 3d 20  ULLERR: pTest = 
7d70: 26 70 2d 3e 66 75 6c 6c 5f 65 72 72 3b 20 62 72  &p->full_err; br
7d80: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
7d90: 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45 52  e CMD_CANTOPENER
7da0: 52 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 63  R: pTest = &p->c
7db0: 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 20 62 72 65  antopen_err; bre
7dc0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 64 65 66 61  ak;.        defa
7dd0: 75 6c 74 3a 20 61 73 73 65 72 74 28 30 29 3b 0a  ult: assert(0);.
7de0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 52        }.      iR
7df0: 65 74 20 3d 20 70 54 65 73 74 2d 3e 6e 46 61 69  et = pTest->nFai
7e00: 6c 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d 3e  l;.      pTest->
7e10: 6e 46 61 69 6c 20 3d 20 30 3b 0a 20 20 20 20 20  nFail = 0;.     
7e20: 20 70 54 65 73 74 2d 3e 65 46 61 75 6c 74 20 3d   pTest->eFault =
7e30: 20 30 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d   0;.      pTest-
7e40: 3e 69 43 6e 74 20 3d 20 30 3b 0a 0a 20 20 20 20  >iCnt = 0;..    
7e50: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20 29 7b    if( objc==4 ){
7e60: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 43 6e  .        int iCn
7e70: 74 2c 20 69 50 65 72 73 69 73 74 3b 0a 20 20 20  t, iPersist;.   
7e80: 20 20 20 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21       if( TCL_OK!
7e90: 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f  =Tcl_GetIntFromO
7ea0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
7eb0: 32 5d 2c 20 26 69 43 6e 74 29 0a 20 20 20 20 20  2], &iCnt).     
7ec0: 20 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b 21 3d 54      || TCL_OK!=T
7ed0: 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f  cl_GetBooleanFro
7ee0: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
7ef0: 76 5b 33 5d 2c 20 26 69 50 65 72 73 69 73 74 29  v[3], &iPersist)
7f00: 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20  .        ){.    
7f10: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
7f20: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20  _ERROR;.        
7f30: 7d 0a 20 20 20 20 20 20 20 20 70 54 65 73 74 2d  }.        pTest-
7f40: 3e 65 46 61 75 6c 74 20 3d 20 69 50 65 72 73 69  >eFault = iPersi
7f50: 73 74 3f 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f  st?FAULT_INJECT_
7f60: 50 45 52 53 49 53 54 45 4e 54 3a 46 41 55 4c 54  PERSISTENT:FAULT
7f70: 5f 49 4e 4a 45 43 54 5f 54 52 41 4e 53 49 45 4e  _INJECT_TRANSIEN
7f80: 54 3b 0a 20 20 20 20 20 20 20 20 70 54 65 73 74  T;.        pTest
7f90: 2d 3e 69 43 6e 74 20 3d 20 69 43 6e 74 3b 0a 20  ->iCnt = iCnt;. 
7fa0: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6f       }else if( o
7fb0: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 20 20  bjc!=2 ){.      
7fc0: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
7fd0: 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62  gs(interp, 2, ob
7fe0: 6a 76 2c 20 22 3f 43 4e 54 20 50 45 52 53 49 53  jv, "?CNT PERSIS
7ff0: 54 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  T?");.        re
8000: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
8010: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63        }.      Tc
8020: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
8030: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e  nterp, Tcl_NewIn
8040: 74 4f 62 6a 28 69 52 65 74 29 29 3b 0a 20 20 20  tObj(iRet));.   
8050: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
8060: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 44 45  .    case CMD_DE
8070: 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20 20 54 63  LETE: {.      Tc
8080: 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61 6e 64 28  l_DeleteCommand(
8090: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53  interp, Tcl_GetS
80a0: 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 29 3b  tring(objv[0]));
80b0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
80c0: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d    }..    case CM
80d0: 44 5f 44 45 56 43 48 41 52 3a 20 7b 0a 20 20 20  D_DEVCHAR: {.   
80e0: 20 20 20 73 74 72 75 63 74 20 44 65 76 69 63 65     struct Device
80f0: 46 6c 61 67 20 7b 0a 20 20 20 20 20 20 20 20 63  Flag {.        c
8100: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
8110: 20 20 20 20 69 6e 74 20 69 56 61 6c 75 65 3b 0a      int iValue;.
8120: 20 20 20 20 20 20 7d 20 61 46 6c 61 67 5b 5d 20        } aFlag[] 
8130: 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 64  = {.        { "d
8140: 65 66 61 75 6c 74 22 2c 20 20 20 20 20 20 20 20  efault",        
8150: 20 20 20 20 20 20 20 2d 31 20 7d 2c 0a 20 20 20         -1 },.   
8160: 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 22 2c       { "atomic",
8170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8180: 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f  SQLITE_IOCAP_ATO
8190: 4d 49 43 20 20 20 20 20 20 7d 2c 0a 20 20 20 20  MIC      },.    
81a0: 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 35 31 32      { "atomic512
81b0: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 53  ",             S
81c0: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d  QLITE_IOCAP_ATOM
81d0: 49 43 35 31 32 20 20 20 7d 2c 0a 20 20 20 20 20  IC512   },.     
81e0: 20 20 20 7b 20 22 61 74 6f 6d 69 63 31 6b 22 2c     { "atomic1k",
81f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
8200: 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49  LITE_IOCAP_ATOMI
8210: 43 31 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20  C1K    },.      
8220: 20 20 7b 20 22 61 74 6f 6d 69 63 32 6b 22 2c 20    { "atomic2k", 
8230: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
8240: 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43  ITE_IOCAP_ATOMIC
8250: 32 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20  2K    },.       
8260: 20 7b 20 22 61 74 6f 6d 69 63 34 6b 22 2c 20 20   { "atomic4k",  
8270: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
8280: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 34  TE_IOCAP_ATOMIC4
8290: 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20  K    },.        
82a0: 7b 20 22 61 74 6f 6d 69 63 38 6b 22 2c 20 20 20  { "atomic8k",   
82b0: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
82c0: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 38 4b  E_IOCAP_ATOMIC8K
82d0: 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b      },.        {
82e0: 20 22 61 74 6f 6d 69 63 31 36 6b 22 2c 20 20 20   "atomic16k",   
82f0: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8300: 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 31 36 4b  _IOCAP_ATOMIC16K
8310: 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20     },.        { 
8320: 22 61 74 6f 6d 69 63 33 32 6b 22 2c 20 20 20 20  "atomic32k",    
8330: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
8340: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 33 32 4b 20  IOCAP_ATOMIC32K 
8350: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22    },.        { "
8360: 61 74 6f 6d 69 63 36 34 6b 22 2c 20 20 20 20 20  atomic64k",     
8370: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49          SQLITE_I
8380: 4f 43 41 50 5f 41 54 4f 4d 49 43 36 34 4b 20 20  OCAP_ATOMIC64K  
8390: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 73   },.        { "s
83a0: 65 71 75 65 6e 74 69 61 6c 22 2c 20 20 20 20 20  equential",     
83b0: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f         SQLITE_IO
83c0: 43 41 50 5f 53 45 51 55 45 4e 54 49 41 4c 20 20  CAP_SEQUENTIAL  
83d0: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 73 61  },.        { "sa
83e0: 66 65 5f 61 70 70 65 6e 64 22 2c 20 20 20 20 20  fe_append",     
83f0: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
8400: 41 50 5f 53 41 46 45 5f 41 50 50 45 4e 44 20 7d  AP_SAFE_APPEND }
8410: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 75 6e 64  ,.        { "und
8420: 65 6c 65 74 61 62 6c 65 5f 77 68 65 6e 5f 6f 70  eletable_when_op
8430: 65 6e 22 2c 20 53 51 4c 49 54 45 5f 49 4f 43 41  en", SQLITE_IOCA
8440: 50 5f 55 4e 44 45 4c 45 54 41 42 4c 45 5f 57 48  P_UNDELETABLE_WH
8450: 45 4e 5f 4f 50 45 4e 20 7d 2c 0a 20 20 20 20 20  EN_OPEN },.     
8460: 20 20 20 7b 20 22 7a 65 72 6f 5f 64 61 6d 61 67     { "zero_damag
8470: 65 22 2c 20 20 20 20 20 20 20 20 20 20 20 53 51  e",           SQ
8480: 4c 49 54 45 5f 49 4f 43 41 50 5f 5a 45 52 4f 5f  LITE_IOCAP_ZERO_
8490: 44 41 4d 41 47 45 20 7d 2c 0a 20 20 20 20 20 20  DAMAGE },.      
84a0: 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 20 20 20    { 0, 0 }.     
84b0: 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62   };.      Tcl_Ob
84c0: 6a 20 2a 70 52 65 74 3b 0a 20 20 20 20 20 20 69  j *pRet;.      i
84d0: 6e 74 20 69 46 6c 61 67 3b 0a 0a 20 20 20 20 20  nt iFlag;..     
84e0: 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20   if( objc>3 ){. 
84f0: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
8500: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
8510: 32 2c 20 6f 62 6a 76 2c 20 22 3f 41 54 54 52 2d  2, objv, "?ATTR-
8520: 4c 49 53 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  LIST?");.       
8530: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8540: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
8550: 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a   if( objc==3 ){.
8560: 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b 0a 20          int j;. 
8570: 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65 77 20         int iNew 
8580: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 54 63 6c  = 0;.        Tcl
8590: 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73 20 3d 20 30  _Obj **flags = 0
85a0: 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 46  ;.        int nF
85b0: 6c 61 67 73 20 3d 20 30 3b 0a 0a 20 20 20 20 20  lags = 0;..     
85c0: 20 20 20 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f     if( Tcl_ListO
85d0: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e  bjGetElements(in
85e0: 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26  terp, objv[2], &
85f0: 6e 46 6c 61 67 73 2c 20 26 66 6c 61 67 73 29 20  nFlags, &flags) 
8600: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74  ){.          ret
8610: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
8620: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
8630: 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 46 6c    for(j=0; j<nFl
8640: 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  ags; j++){.     
8650: 20 20 20 20 20 69 6e 74 20 69 64 78 20 3d 20 30       int idx = 0
8660: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
8670: 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d  Tcl_GetIndexFrom
8680: 4f 62 6a 53 74 72 75 63 74 28 69 6e 74 65 72 70  ObjStruct(interp
8690: 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20 61 46 6c 61  , flags[j], aFla
86a0: 67 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  g, .            
86b0: 20 20 20 20 73 69 7a 65 6f 66 28 61 46 6c 61 67      sizeof(aFlag
86c0: 5b 30 5d 29 2c 20 22 66 6c 61 67 22 2c 20 30 2c  [0]), "flag", 0,
86d0: 20 26 69 64 78 29 20 0a 20 20 20 20 20 20 20 20   &idx) .        
86e0: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20    ){.           
86f0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8700: 52 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  R;.          }. 
8710: 20 20 20 20 20 20 20 20 20 69 66 28 20 61 46 6c           if( aFl
8720: 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3c 30  ag[idx].iValue<0
8730: 20 26 26 20 6e 46 6c 61 67 73 3e 31 20 29 7b 0a   && nFlags>1 ){.
8740: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
8750: 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74  AppendResult(int
8760: 65 72 70 2c 20 22 62 61 64 20 66 6c 61 67 73 3a  erp, "bad flags:
8770: 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e   ", Tcl_GetStrin
8780: 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a  g(objv[2]), 0);.
8790: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
87a0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
87b0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
87c0: 20 20 20 20 69 4e 65 77 20 7c 3d 20 61 46 6c 61      iNew |= aFla
87d0: 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3b 0a 20  g[idx].iValue;. 
87e0: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
87f0: 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20 3d 20    p->iDevchar = 
8800: 69 4e 65 77 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  iNew;.      }.. 
8810: 20 20 20 20 20 70 52 65 74 20 3d 20 54 63 6c 5f       pRet = Tcl_
8820: 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20  NewObj();.      
8830: 66 6f 72 28 69 46 6c 61 67 3d 30 3b 20 69 46 6c  for(iFlag=0; iFl
8840: 61 67 3c 73 69 7a 65 6f 66 28 61 46 6c 61 67 29  ag<sizeof(aFlag)
8850: 2f 73 69 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d  /sizeof(aFlag[0]
8860: 29 3b 20 69 46 6c 61 67 2b 2b 29 7b 0a 20 20 20  ); iFlag++){.   
8870: 20 20 20 20 20 69 66 28 20 70 2d 3e 69 44 65 76       if( p->iDev
8880: 63 68 61 72 20 26 20 61 46 6c 61 67 5b 69 46 6c  char & aFlag[iFl
8890: 61 67 5d 2e 69 56 61 6c 75 65 20 29 7b 0a 20 20  ag].iValue ){.  
88a0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74          Tcl_List
88b0: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
88c0: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
88d0: 69 6e 74 65 72 70 2c 20 70 52 65 74 2c 20 54 63  interp, pRet, Tc
88e0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61  l_NewStringObj(a
88f0: 46 6c 61 67 5b 69 46 6c 61 67 5d 2e 7a 4e 61 6d  Flag[iFlag].zNam
8900: 65 2c 20 2d 31 29 0a 20 20 20 20 20 20 20 20 20  e, -1).         
8910: 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   );.        }.  
8920: 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f      }.      Tcl_
8930: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
8940: 65 72 70 2c 20 70 52 65 74 29 3b 0a 0a 20 20 20  erp, pRet);..   
8950: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
8960: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 53 45  .    case CMD_SE
8970: 43 54 4f 52 53 49 5a 45 3a 20 7b 0a 20 20 20 20  CTORSIZE: {.    
8980: 20 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a    if( objc>3 ){.
8990: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
89a0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
89b0: 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 56 41 4c 55   2, objv, "?VALU
89c0: 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  E?");.        re
89d0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
89e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
89f0: 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20  ( objc==3 ){.   
8a00: 20 20 20 20 20 69 6e 74 20 69 4e 65 77 20 3d 20       int iNew = 
8a10: 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 54  0;.        if( T
8a20: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
8a30: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d  (interp, objv[2]
8a40: 2c 20 26 69 4e 65 77 29 20 29 7b 0a 20 20 20 20  , &iNew) ){.    
8a50: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
8a60: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20  _ERROR;.        
8a70: 7d 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 53 65  }.        p->iSe
8a80: 63 74 6f 72 73 69 7a 65 20 3d 20 69 4e 65 77 3b  ctorsize = iNew;
8a90: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54  .      }.      T
8aa0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
8ab0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49  interp, Tcl_NewI
8ac0: 6e 74 4f 62 6a 28 70 2d 3e 69 53 65 63 74 6f 72  ntObj(p->iSector
8ad0: 73 69 7a 65 29 29 3b 0a 20 20 20 20 20 20 62 72  size));.      br
8ae0: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
8af0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
8b00: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
8b10: 74 65 73 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 28  testvfs_obj_del(
8b20: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 29 7b 0a  ClientData cd){.
8b30: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
8b40: 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a 20 20  Testvfs *)cd;.  
8b50: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29  if( p->pScript )
8b60: 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e   Tcl_DecrRefCoun
8b70: 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20  t(p->pScript);. 
8b80: 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72   sqlite3_vfs_unr
8b90: 65 67 69 73 74 65 72 28 70 2d 3e 70 56 66 73 29  egister(p->pVfs)
8ba0: 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61 72  ;.  ckfree((char
8bb0: 20 2a 29 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63   *)p->pVfs);.  c
8bc0: 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 29  kfree((char *)p)
8bd0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65  ;.}../*.** Usage
8be0: 3a 20 20 74 65 73 74 76 66 73 20 56 46 53 4e 41  :  testvfs VFSNA
8bf0: 4d 45 20 3f 53 57 49 54 43 48 45 53 3f 0a 2a 2a  ME ?SWITCHES?.**
8c00: 0a 2a 2a 20 53 77 69 74 63 68 65 73 20 61 72 65  .** Switches are
8c10: 3a 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d  :.**.**   -noshm
8c20: 20 20 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20     BOOLEAN      
8c30: 20 20 20 20 20 20 20 28 54 72 75 65 20 74 6f 20         (True to 
8c40: 6f 6d 69 74 20 73 68 6d 20 6d 65 74 68 6f 64 73  omit shm methods
8c50: 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29  . Default false)
8c60: 0a 2a 2a 20 20 20 2d 64 65 66 61 75 6c 74 20 42  .**   -default B
8c70: 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20 20 20 20  OOLEAN          
8c80: 20 20 20 28 54 72 75 65 20 74 6f 20 6d 61 6b 65     (True to make
8c90: 20 74 68 65 20 76 66 73 20 64 65 66 61 75 6c 74   the vfs default
8ca0: 2e 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29  . Default false)
8cb0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 6f 6d 6d  .**.** This comm
8cc0: 61 6e 64 20 63 72 65 61 74 65 73 20 74 77 6f 20  and creates two 
8cd0: 74 68 69 6e 67 73 20 77 68 65 6e 20 69 74 20 69  things when it i
8ce0: 73 20 69 6e 76 6f 6b 65 64 3a 20 61 6e 20 53 51  s invoked: an SQ
8cf0: 4c 69 74 65 20 56 46 53 2c 20 61 6e 64 0a 2a 2a  Lite VFS, and.**
8d00: 20 61 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20   a Tcl command. 
8d10: 42 6f 74 68 20 61 72 65 20 6e 61 6d 65 64 20 56  Both are named V
8d20: 46 53 4e 41 4d 45 2e 20 54 68 65 20 56 46 53 20  FSNAME. The VFS 
8d30: 69 73 20 69 6e 73 74 61 6c 6c 65 64 2e 20 49 74  is installed. It
8d40: 20 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 73 74 61   is not.** insta
8d50: 6c 6c 65 64 20 61 73 20 74 68 65 20 64 65 66 61  lled as the defa
8d60: 75 6c 74 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 54  ult VFS..**.** T
8d70: 68 65 20 56 46 53 20 70 61 73 73 65 73 20 61 6c  he VFS passes al
8d80: 6c 20 66 69 6c 65 20 49 2f 4f 20 63 61 6c 6c 73  l file I/O calls
8d90: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20   through to the 
8da0: 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 2e 0a  underlying VFS..
8db0: 2a 2a 0a 2a 2a 20 57 68 65 6e 65 76 65 72 20 74  **.** Whenever t
8dc0: 68 65 20 78 53 68 6d 4d 61 70 20 6d 65 74 68 6f  he xShmMap metho
8dd0: 64 20 6f 66 20 74 68 65 20 56 46 53 0a 2a 2a 20  d of the VFS.** 
8de0: 69 73 20 69 6e 76 6f 6b 65 64 2c 20 74 68 65 20  is invoked, the 
8df0: 53 43 52 49 50 54 20 69 73 20 65 78 65 63 75 74  SCRIPT is execut
8e00: 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  ed as follows:.*
8e10: 2a 0a 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53  *.**   SCRIPT xS
8e20: 68 6d 4d 61 70 20 20 20 20 46 49 4c 45 4e 41 4d  hmMap    FILENAM
8e30: 45 20 49 44 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76  E ID.**.** The v
8e40: 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79  alue returned by
8e50: 20 74 68 65 20 69 6e 76 6f 63 61 74 69 6f 6e 20   the invocation 
8e60: 6f 66 20 53 43 52 49 50 54 20 61 62 6f 76 65 20  of SCRIPT above 
8e70: 69 73 20 69 6e 74 65 72 70 72 65 74 65 64 20 61  is interpreted a
8e80: 73 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65  s.** an SQLite e
8e90: 72 72 6f 72 20 63 6f 64 65 20 61 6e 64 20 72 65  rror code and re
8ea0: 74 75 72 6e 65 64 20 74 6f 20 53 51 4c 69 74 65  turned to SQLite
8eb0: 2e 20 45 69 74 68 65 72 20 61 20 73 79 6d 62 6f  . Either a symbo
8ec0: 6c 69 63 20 0a 2a 2a 20 22 53 51 4c 49 54 45 5f  lic .** "SQLITE_
8ed0: 4f 4b 22 20 6f 72 20 6e 75 6d 65 72 69 63 20 22  OK" or numeric "
8ee0: 30 22 20 76 61 6c 75 65 20 6d 61 79 20 62 65 20  0" value may be 
8ef0: 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  returned..**.** 
8f00: 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  The contents of 
8f10: 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72  the shared-memor
8f20: 79 20 62 75 66 66 65 72 20 61 73 73 6f 63 69 61  y buffer associa
8f30: 74 65 64 20 77 69 74 68 20 61 20 67 69 76 65 6e  ted with a given
8f40: 20 66 69 6c 65 0a 2a 2a 20 6d 61 79 20 62 65 20   file.** may be 
8f50: 72 65 61 64 20 61 6e 64 20 73 65 74 20 75 73 69  read and set usi
8f60: 6e 67 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ng the following
8f70: 20 63 6f 6d 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20   command:.**.** 
8f80: 20 20 56 46 53 4e 41 4d 45 20 73 68 6d 20 46 49    VFSNAME shm FI
8f90: 4c 45 4e 41 4d 45 20 3f 4e 45 57 56 41 4c 55 45  LENAME ?NEWVALUE
8fa0: 3f 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65  ?.**.** When the
8fb0: 20 78 53 68 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64   xShmLock method
8fc0: 20 69 73 20 69 6e 76 6f 6b 65 64 20 62 79 20 53   is invoked by S
8fd0: 51 4c 69 74 65 2c 20 74 68 65 20 66 6f 6c 6c 6f  QLite, the follo
8fe0: 77 69 6e 67 20 73 63 72 69 70 74 20 69 73 0a 2a  wing script is.*
8ff0: 2a 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53  * run:.**.**   S
9000: 43 52 49 50 54 20 78 53 68 6d 4c 6f 63 6b 20 20  CRIPT xShmLock  
9010: 20 20 46 49 4c 45 4e 41 4d 45 20 49 44 20 4c 4f    FILENAME ID LO
9020: 43 4b 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 4c  CK.**.** where L
9030: 4f 43 4b 20 69 73 20 6f 66 20 74 68 65 20 66 6f  OCK is of the fo
9040: 72 6d 20 22 4f 46 46 53 45 54 20 4e 42 59 54 45  rm "OFFSET NBYTE
9050: 20 6c 6f 63 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61   lock/unlock sha
9060: 72 65 64 2f 65 78 63 6c 75 73 69 76 65 22 0a 2a  red/exclusive".*
9070: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73  /.static int tes
9080: 74 76 66 73 5f 63 6d 64 28 0a 20 20 43 6c 69 65  tvfs_cmd(.  Clie
9090: 6e 74 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c  ntData cd,.  Tcl
90a0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
90b0: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54  .  int objc,.  T
90c0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
90d0: 6a 76 5b 5d 0a 29 7b 0a 20 20 73 74 61 74 69 63  jv[].){.  static
90e0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 74 76 66   sqlite3_vfs tvf
90f0: 73 5f 76 66 73 20 3d 20 7b 0a 20 20 20 20 32 2c  s_vfs = {.    2,
9100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9110: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
9120: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30  Version */.    0
9130: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9140: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9150: 73 7a 4f 73 46 69 6c 65 20 2a 2f 0a 20 20 20 20  szOsFile */.    
9160: 30 2c 20 20 20 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 2f 2a                /*
9180: 20 6d 78 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20   mxPathname */. 
9190: 20 20 20 30 2c 20 20 20 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 2f 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20   /* pNext */.   
91c0: 20 30 2c 20 20 20 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 2f                 /
91e0: 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 20 20 30  * zName */.    0
91f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9210: 70 41 70 70 44 61 74 61 20 2a 2f 0a 20 20 20 20  pAppData */.    
9220: 74 76 66 73 4f 70 65 6e 2c 20 20 20 20 20 20 20  tvfsOpen,       
9230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9240: 20 78 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76   xOpen */.    tv
9250: 66 73 44 65 6c 65 74 65 2c 20 20 20 20 20 20 20  fsDelete,       
9260: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9270: 44 65 6c 65 74 65 20 2a 2f 0a 20 20 20 20 74 76  Delete */.    tv
9280: 66 73 41 63 63 65 73 73 2c 20 20 20 20 20 20 20  fsAccess,       
9290: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
92a0: 41 63 63 65 73 73 20 2a 2f 0a 20 20 20 20 74 76  Access */.    tv
92b0: 66 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20  fsFullPathname, 
92c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
92d0: 46 75 6c 6c 50 61 74 68 6e 61 6d 65 20 2a 2f 0a  FullPathname */.
92e0: 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f  #ifndef SQLITE_O
92f0: 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49  MIT_LOAD_EXTENSI
9300: 4f 4e 0a 20 20 20 20 74 76 66 73 44 6c 4f 70 65  ON.    tvfsDlOpe
9310: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
9320: 20 20 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20       /* xDlOpen 
9330: 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c 45 72 72  */.    tvfsDlErr
9340: 6f 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  or,             
9350: 20 20 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72       /* xDlError
9360: 20 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c 53 79   */.    tvfsDlSy
9370: 6d 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m,              
9380: 20 20 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20        /* xDlSym 
9390: 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c 43 6c 6f  */.    tvfsDlClo
93a0: 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
93b0: 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65       /* xDlClose
93c0: 20 2a 2f 0a 23 65 6c 73 65 0a 20 20 20 20 30 2c   */.#else.    0,
93d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
93f0: 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 30 2c  DlOpen */.    0,
9400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9410: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9420: 44 6c 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30  DlError */.    0
9430: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9440: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9450: 78 44 6c 53 79 6d 20 2a 2f 0a 20 20 20 20 30 2c  xDlSym */.    0,
9460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9470: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9480: 44 6c 43 6c 6f 73 65 20 2a 2f 0a 23 65 6e 64 69  DlClose */.#endi
9490: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54  f /* SQLITE_OMIT
94a0: 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20  _LOAD_EXTENSION 
94b0: 2a 2f 0a 20 20 20 20 74 76 66 73 52 61 6e 64 6f  */.    tvfsRando
94c0: 6d 6e 65 73 73 2c 20 20 20 20 20 20 20 20 20 20  mness,          
94d0: 20 20 20 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e       /* xRandomn
94e0: 65 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 53  ess */.    tvfsS
94f0: 6c 65 65 70 2c 20 20 20 20 20 20 20 20 20 20 20  leep,           
9500: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 6c 65           /* xSle
9510: 65 70 20 2a 2f 0a 20 20 20 20 74 76 66 73 43 75  ep */.    tvfsCu
9520: 72 72 65 6e 74 54 69 6d 65 2c 20 20 20 20 20 20  rrentTime,      
9530: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72          /* xCurr
9540: 65 6e 74 54 69 6d 65 20 2a 2f 0a 20 20 20 20 30  entTime */.    0
9550: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9560: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9570: 78 47 65 74 4c 61 73 74 45 72 72 6f 72 20 2a 2f  xGetLastError */
9580: 0a 20 20 20 20 30 2c 20 20 20 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 2f 2a 20 78 43 75 72 72 65 6e 74 54 69     /* xCurrentTi
95b0: 6d 65 49 6e 74 36 34 20 2a 2f 0a 20 20 7d 3b 0a  meInt64 */.  };.
95c0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 3b 20 20  .  Testvfs *p;  
95d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
95e0: 20 20 20 2f 2a 20 4e 65 77 20 6f 62 6a 65 63 74     /* New object
95f0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66   */.  sqlite3_vf
9600: 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20 20 20  s *pVfs;        
9610: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 56 46 53        /* New VFS
9620: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 56 66 73   */.  char *zVfs
9630: 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  ;.  int nByte;  
9640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9650: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
9660: 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74  space to allocat
9670: 65 20 61 74 20 70 20 2a 2f 0a 0a 20 20 69 6e 74  e at p */..  int
9680: 20 69 3b 0a 20 20 69 6e 74 20 69 73 4e 6f 73 68   i;.  int isNosh
9690: 6d 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  m = 0;          
96a0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
96b0: 20 2d 6e 6f 73 68 6d 20 69 73 20 70 61 73 73 65   -noshm is passe
96c0: 64 20 2a 2f 0a 20 20 69 6e 74 20 69 73 44 65 66  d */.  int isDef
96d0: 61 75 6c 74 20 3d 20 30 3b 20 20 20 20 20 20 20  ault = 0;       
96e0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
96f0: 66 20 2d 64 65 66 61 75 6c 74 20 69 73 20 70 61  f -default is pa
9700: 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ssed */.  int sz
9710: 4f 73 46 69 6c 65 20 3d 20 30 3b 20 20 20 20 20  OsFile = 0;     
9720: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
9730: 75 65 20 70 61 73 73 65 64 20 74 6f 20 2d 73 7a  ue passed to -sz
9740: 6f 73 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  osfile */.  int 
9750: 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20 2d 31 3b  mxPathname = -1;
9760: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
9770: 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f 20 2d  alue passed to -
9780: 6d 78 70 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20  mxpathname */.  
9790: 69 6e 74 20 69 56 65 72 73 69 6f 6e 20 3d 20 32  int iVersion = 2
97a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
97b0: 2f 2a 20 56 61 6c 75 65 20 70 61 73 73 65 64 20  /* Value passed 
97c0: 74 6f 20 2d 69 76 65 72 73 69 6f 6e 20 2a 2f 0a  to -iversion */.
97d0: 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20 7c 7c  .  if( objc<2 ||
97e0: 20 30 21 3d 28 6f 62 6a 63 25 32 29 20 29 20 67   0!=(objc%2) ) g
97f0: 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b 0a 20 20  oto bad_args;.  
9800: 66 6f 72 28 69 3d 32 3b 20 69 3c 6f 62 6a 63 3b  for(i=2; i<objc;
9810: 20 69 20 2b 3d 20 32 29 7b 0a 20 20 20 20 69 6e   i += 2){.    in
9820: 74 20 6e 53 77 69 74 63 68 3b 0a 20 20 20 20 63  t nSwitch;.    c
9830: 68 61 72 20 2a 7a 53 77 69 74 63 68 3b 0a 20 20  har *zSwitch;.  
9840: 20 20 7a 53 77 69 74 63 68 20 3d 20 54 63 6c 5f    zSwitch = Tcl_
9850: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
9860: 28 6f 62 6a 76 5b 69 5d 2c 20 26 6e 53 77 69 74  (objv[i], &nSwit
9870: 63 68 29 3b 20 0a 0a 20 20 20 20 69 66 28 20 6e  ch); ..    if( n
9880: 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73  Switch>2 && 0==s
9890: 74 72 6e 63 6d 70 28 22 2d 6e 6f 73 68 6d 22 2c  trncmp("-noshm",
98a0: 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63   zSwitch, nSwitc
98b0: 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  h) ){.      if( 
98c0: 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72  Tcl_GetBooleanFr
98d0: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
98e0: 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 4e 6f 73 68  jv[i+1], &isNosh
98f0: 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  m) ){.        re
9900: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
9910: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
9920: 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74    else if( nSwit
9930: 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63  ch>2 && 0==strnc
9940: 6d 70 28 22 2d 64 65 66 61 75 6c 74 22 2c 20 7a  mp("-default", z
9950: 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29  Switch, nSwitch)
9960: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63   ){.      if( Tc
9970: 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d  l_GetBooleanFrom
9980: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
9990: 5b 69 2b 31 5d 2c 20 26 69 73 44 65 66 61 75 6c  [i+1], &isDefaul
99a0: 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  t) ){.        re
99b0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
99c0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
99d0: 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74    else if( nSwit
99e0: 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63  ch>2 && 0==strnc
99f0: 6d 70 28 22 2d 73 7a 6f 73 66 69 6c 65 22 2c 20  mp("-szosfile", 
9a00: 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68  zSwitch, nSwitch
9a10: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54  ) ){.      if( T
9a20: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
9a30: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b  (interp, objv[i+
9a40: 31 5d 2c 20 26 73 7a 4f 73 46 69 6c 65 29 20 29  1], &szOsFile) )
9a50: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
9a60: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9a70: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c    }.    }.    el
9a80: 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32  se if( nSwitch>2
9a90: 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22   && 0==strncmp("
9aa0: 2d 6d 78 70 61 74 68 6e 61 6d 65 22 2c 20 7a 53  -mxpathname", zS
9ab0: 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20  witch, nSwitch) 
9ac0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c  ){.      if( Tcl
9ad0: 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  _GetIntFromObj(i
9ae0: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d  nterp, objv[i+1]
9af0: 2c 20 26 6d 78 50 61 74 68 6e 61 6d 65 29 20 29  , &mxPathname) )
9b00: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
9b10: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9b20: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c    }.    }.    el
9b30: 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32  se if( nSwitch>2
9b40: 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22   && 0==strncmp("
9b50: 2d 69 76 65 72 73 69 6f 6e 22 2c 20 7a 53 77 69  -iversion", zSwi
9b60: 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b  tch, nSwitch) ){
9b70: 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47  .      if( Tcl_G
9b80: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
9b90: 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20  erp, objv[i+1], 
9ba0: 26 69 56 65 72 73 69 6f 6e 29 20 29 7b 0a 20 20  &iVersion) ){.  
9bb0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
9bc0: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a  _ERROR;.      }.
9bd0: 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 7b 0a      }.    else{.
9be0: 20 20 20 20 20 20 67 6f 74 6f 20 62 61 64 5f 61        goto bad_a
9bf0: 72 67 73 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  rgs;.    }.  }..
9c00: 20 20 69 66 28 20 73 7a 4f 73 46 69 6c 65 3c 73    if( szOsFile<s
9c10: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 69 6c  izeof(TestvfsFil
9c20: 65 29 20 29 7b 0a 20 20 20 20 73 7a 4f 73 46 69  e) ){.    szOsFi
9c30: 6c 65 20 3d 20 73 69 7a 65 6f 66 28 54 65 73 74  le = sizeof(Test
9c40: 76 66 73 46 69 6c 65 29 3b 0a 20 20 7d 0a 0a 20  vfsFile);.  }.. 
9c50: 20 7a 56 66 73 20 3d 20 54 63 6c 5f 47 65 74 53   zVfs = Tcl_GetS
9c60: 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a  tring(objv[1]);.
9c70: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
9c80: 28 54 65 73 74 76 66 73 29 20 2b 20 73 74 72 6c  (Testvfs) + strl
9c90: 65 6e 28 7a 56 66 73 29 2b 31 3b 0a 20 20 70 20  en(zVfs)+1;.  p 
9ca0: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63 6b 61  = (Testvfs *)cka
9cb0: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 6d  lloc(nByte);.  m
9cc0: 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74  emset(p, 0, nByt
9cd0: 65 29 3b 0a 20 20 70 2d 3e 69 44 65 76 63 68 61  e);.  p->iDevcha
9ce0: 72 20 3d 20 2d 31 3b 0a 20 20 70 2d 3e 69 53 65  r = -1;.  p->iSe
9cf0: 63 74 6f 72 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a  ctorsize = -1;..
9d00: 20 20 2f 2a 20 43 72 65 61 74 65 20 74 68 65 20    /* Create the 
9d10: 6e 65 77 20 6f 62 6a 65 63 74 20 63 6f 6d 6d 61  new object comma
9d20: 6e 64 20 62 65 66 6f 72 65 20 71 75 65 72 79 69  nd before queryi
9d30: 6e 67 20 53 51 4c 69 74 65 20 66 6f 72 20 61 20  ng SQLite for a 
9d40: 64 65 66 61 75 6c 74 20 56 46 53 0a 20 20 2a 2a  default VFS.  **
9d50: 20 74 6f 20 75 73 65 20 66 6f 72 20 27 72 65 61   to use for 'rea
9d60: 6c 27 20 49 4f 20 6f 70 65 72 61 74 69 6f 6e 73  l' IO operations
9d70: 2e 20 54 68 69 73 20 69 73 20 62 65 63 61 75 73  . This is becaus
9d80: 65 20 63 72 65 61 74 69 6e 67 20 74 68 65 20 6e  e creating the n
9d90: 65 77 20 56 46 53 0a 20 20 2a 2a 20 6d 61 79 20  ew VFS.  ** may 
9da0: 64 65 6c 65 74 65 20 61 6e 20 65 78 69 73 74 69  delete an existi
9db0: 6e 67 20 5b 74 65 73 74 76 66 73 5d 20 56 46 53  ng [testvfs] VFS
9dc0: 20 6f 66 20 74 68 65 20 73 61 6d 65 20 6e 61 6d   of the same nam
9dd0: 65 2e 20 49 66 20 73 75 63 68 20 61 20 56 46 53  e. If such a VFS
9de0: 0a 20 20 2a 2a 20 69 73 20 63 75 72 72 65 6e 74  .  ** is current
9df0: 6c 79 20 74 68 65 20 64 65 66 61 75 6c 74 2c 20  ly the default, 
9e00: 74 68 65 20 6e 65 77 20 5b 74 65 73 74 76 66 73  the new [testvfs
9e10: 5d 20 6d 61 79 20 65 6e 64 20 75 70 20 63 61 6c  ] may end up cal
9e20: 6c 69 6e 67 20 74 68 65 20 0a 20 20 2a 2a 20 6d  ling the .  ** m
9e30: 65 74 68 6f 64 73 20 6f 66 20 61 20 64 65 6c 65  ethods of a dele
9e40: 74 65 64 20 6f 62 6a 65 63 74 2e 0a 20 20 2a 2f  ted object..  */
9e50: 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  .  Tcl_CreateObj
9e60: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
9e70: 7a 56 66 73 2c 20 74 65 73 74 76 66 73 5f 6f 62  zVfs, testvfs_ob
9e80: 6a 5f 63 6d 64 2c 20 70 2c 20 74 65 73 74 76 66  j_cmd, p, testvf
9e90: 73 5f 6f 62 6a 5f 64 65 6c 29 3b 0a 20 20 70 2d  s_obj_del);.  p-
9ea0: 3e 70 50 61 72 65 6e 74 20 3d 20 73 71 6c 69 74  >pParent = sqlit
9eb0: 65 33 5f 76 66 73 5f 66 69 6e 64 28 30 29 3b 0a  e3_vfs_find(0);.
9ec0: 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d 20 69 6e    p->interp = in
9ed0: 74 65 72 70 3b 0a 0a 20 20 70 2d 3e 7a 4e 61 6d  terp;..  p->zNam
9ee0: 65 20 3d 20 28 63 68 61 72 20 2a 29 26 70 5b 31  e = (char *)&p[1
9ef0: 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 2d 3e 7a  ];.  memcpy(p->z
9f00: 4e 61 6d 65 2c 20 7a 56 66 73 2c 20 73 74 72 6c  Name, zVfs, strl
9f10: 65 6e 28 7a 56 66 73 29 2b 31 29 3b 0a 0a 20 20  en(zVfs)+1);..  
9f20: 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65 33 5f  pVfs = (sqlite3_
9f30: 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63 28 73 69  vfs *)ckalloc(si
9f40: 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 66 73  zeof(sqlite3_vfs
9f50: 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 56 66  ));.  memcpy(pVf
9f60: 73 2c 20 26 74 76 66 73 5f 76 66 73 2c 20 73 69  s, &tvfs_vfs, si
9f70: 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 66 73  zeof(sqlite3_vfs
9f80: 29 29 3b 0a 20 20 70 56 66 73 2d 3e 70 41 70 70  ));.  pVfs->pApp
9f90: 44 61 74 61 20 3d 20 28 76 6f 69 64 20 2a 29 70  Data = (void *)p
9fa0: 3b 0a 20 20 70 56 66 73 2d 3e 69 56 65 72 73 69  ;.  pVfs->iVersi
9fb0: 6f 6e 20 3d 20 69 56 65 72 73 69 6f 6e 3b 0a 20  on = iVersion;. 
9fc0: 20 70 56 66 73 2d 3e 7a 4e 61 6d 65 20 3d 20 70   pVfs->zName = p
9fd0: 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 70 56 66 73 2d  ->zName;.  pVfs-
9fe0: 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20 70 2d  >mxPathname = p-
9ff0: 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68  >pParent->mxPath
a000: 6e 61 6d 65 3b 0a 20 20 69 66 28 20 6d 78 50 61  name;.  if( mxPa
a010: 74 68 6e 61 6d 65 3e 3d 30 20 26 26 20 6d 78 50  thname>=0 && mxP
a020: 61 74 68 6e 61 6d 65 3c 70 56 66 73 2d 3e 6d 78  athname<pVfs->mx
a030: 50 61 74 68 6e 61 6d 65 20 29 7b 0a 20 20 20 20  Pathname ){.    
a040: 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65  pVfs->mxPathname
a050: 20 3d 20 6d 78 50 61 74 68 6e 61 6d 65 3b 0a 20   = mxPathname;. 
a060: 20 7d 0a 20 20 70 56 66 73 2d 3e 73 7a 4f 73 46   }.  pVfs->szOsF
a070: 69 6c 65 20 3d 20 73 7a 4f 73 46 69 6c 65 3b 0a  ile = szOsFile;.
a080: 20 20 70 2d 3e 70 56 66 73 20 3d 20 70 56 66 73    p->pVfs = pVfs
a090: 3b 0a 20 20 70 2d 3e 69 73 4e 6f 73 68 6d 20 3d  ;.  p->isNoshm =
a0a0: 20 69 73 4e 6f 73 68 6d 3b 0a 20 20 70 2d 3e 6d   isNoshm;.  p->m
a0b0: 61 73 6b 20 3d 20 54 45 53 54 56 46 53 5f 41 4c  ask = TESTVFS_AL
a0c0: 4c 5f 4d 41 53 4b 3b 0a 0a 20 20 73 71 6c 69 74  L_MASK;..  sqlit
a0d0: 65 33 5f 76 66 73 5f 72 65 67 69 73 74 65 72 28  e3_vfs_register(
a0e0: 70 56 66 73 2c 20 69 73 44 65 66 61 75 6c 74 29  pVfs, isDefault)
a0f0: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  ;..  return TCL_
a100: 4f 4b 3b 0a 0a 20 62 61 64 5f 61 72 67 73 3a 0a  OK;.. bad_args:.
a110: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
a120: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
a130: 6a 76 2c 20 22 56 46 53 4e 41 4d 45 20 3f 2d 6e  jv, "VFSNAME ?-n
a140: 6f 73 68 6d 20 42 4f 4f 4c 3f 20 3f 2d 64 65 66  oshm BOOL? ?-def
a150: 61 75 6c 74 20 42 4f 4f 4c 3f 20 3f 2d 6d 78 70  ault BOOL? ?-mxp
a160: 61 74 68 6e 61 6d 65 20 49 4e 54 3f 20 3f 2d 73  athname INT? ?-s
a170: 7a 6f 73 66 69 6c 65 20 49 4e 54 3f 20 3f 2d 69  zosfile INT? ?-i
a180: 76 65 72 73 69 6f 6e 20 49 4e 54 3f 22 29 3b 0a  version INT?");.
a190: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
a1a0: 4f 52 3b 0a 7d 0a 0a 69 6e 74 20 53 71 6c 69 74  OR;.}..int Sqlit
a1b0: 65 74 65 73 74 76 66 73 5f 49 6e 69 74 28 54 63  etestvfs_Init(Tc
a1c0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a1d0: 29 7b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  ){.  Tcl_CreateO
a1e0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
a1f0: 2c 20 22 74 65 73 74 76 66 73 22 2c 20 74 65 73  , "testvfs", tes
a200: 74 76 66 73 5f 63 6d 64 2c 20 30 2c 20 30 29 3b  tvfs_cmd, 0, 0);
a210: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
a220: 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a              ;.}..#endif.