/ Hex Artifact Content
Login

Artifact 73f46bd9b5183ebcb77da22773886b81157cdc3d:


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 69 66 28 20 6f 70 3d 3d 53 51 4c  );.  if( op==SQL
3670: 49 54 45 5f 46 43 4e 54 4c 5f 50 52 41 47 4d 41  ITE_FCNTL_PRAGMA
3680: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 2a 61   ){.    char **a
3690: 72 67 76 20 3d 20 28 63 68 61 72 2a 2a 29 70 41  rgv = (char**)pA
36a0: 72 67 3b 0a 20 20 20 20 69 66 28 20 73 71 6c 69  rg;.    if( sqli
36b0: 74 65 33 5f 73 74 72 69 63 6d 70 28 61 72 67 76  te3_stricmp(argv
36c0: 5b 31 5d 2c 22 65 72 72 6f 72 22 29 3d 3d 30 20  [1],"error")==0 
36d0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 20  ){.      int rc 
36e0: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
36f0: 20 20 20 20 20 20 69 66 28 20 61 72 67 76 5b 32        if( argv[2
3700: 5d 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e  ] ){.        con
3710: 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 61 72 67  st char *z = arg
3720: 76 5b 32 5d 3b 0a 20 20 20 20 20 20 20 20 69 6e  v[2];.        in
3730: 74 20 78 20 3d 20 61 74 6f 69 28 7a 29 3b 0a 20  t x = atoi(z);. 
3740: 20 20 20 20 20 20 20 69 66 28 20 78 20 29 7b 0a         if( x ){.
3750: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 78            rc = x
3760: 3b 0a 20 20 20 20 20 20 20 20 20 20 77 68 69 6c  ;.          whil
3770: 65 28 20 73 71 6c 69 74 65 33 49 73 64 69 67 69  e( sqlite3Isdigi
3780: 74 28 7a 5b 30 5d 29 20 29 7b 20 7a 2b 2b 3b 20  t(z[0]) ){ z++; 
3790: 7d 0a 20 20 20 20 20 20 20 20 20 20 77 68 69 6c  }.          whil
37a0: 65 28 20 73 71 6c 69 74 65 33 49 73 73 70 61 63  e( sqlite3Isspac
37b0: 65 28 7a 5b 30 5d 29 20 29 7b 20 7a 2b 2b 3b 20  e(z[0]) ){ z++; 
37c0: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
37d0: 20 20 20 20 69 66 28 20 7a 5b 30 5d 20 29 20 61      if( z[0] ) a
37e0: 72 67 76 5b 30 5d 20 3d 20 73 71 6c 69 74 65 33  rgv[0] = sqlite3
37f0: 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a  _mprintf("%s", z
3800: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
3810: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
3820: 7d 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65  }.    if( sqlite
3830: 33 5f 73 74 72 69 63 6d 70 28 61 72 67 76 5b 31  3_stricmp(argv[1
3840: 5d 2c 20 22 66 69 6c 65 6e 61 6d 65 22 29 3d 3d  ], "filename")==
3850: 30 20 29 7b 0a 20 20 20 20 20 20 61 72 67 76 5b  0 ){.      argv[
3860: 30 5d 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  0] = sqlite3_mpr
3870: 69 6e 74 66 28 22 25 73 22 2c 20 70 2d 3e 7a 46  intf("%s", p->zF
3880: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20  ilename);.      
3890: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
38a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
38b0: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 69  turn sqlite3OsFi
38c0: 6c 65 43 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65  leControl(p->pRe
38d0: 61 6c 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d  al, op, pArg);.}
38e0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
38f0: 68 65 20 73 65 63 74 6f 72 2d 73 69 7a 65 20 69  he sector-size i
3900: 6e 20 62 79 74 65 73 20 66 6f 72 20 61 6e 20 74  n bytes for an t
3910: 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  vfs-file..*/.sta
3920: 74 69 63 20 69 6e 74 20 74 76 66 73 53 65 63 74  tic int tvfsSect
3930: 6f 72 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66  orSize(sqlite3_f
3940: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
3950: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
3960: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
3970: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
3980: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
3990: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
39a0: 0a 20 20 69 66 28 20 70 2d 3e 69 53 65 63 74 6f  .  if( p->iSecto
39b0: 72 73 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20  rsize>=0 ){.    
39c0: 72 65 74 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f  return p->iSecto
39d0: 72 73 69 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74  rsize;.  }.  ret
39e0: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 65 63  urn sqlite3OsSec
39f0: 74 6f 72 53 69 7a 65 28 70 46 64 2d 3e 70 52 65  torSize(pFd->pRe
3a00: 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  al);.}../*.** Re
3a10: 74 75 72 6e 20 74 68 65 20 64 65 76 69 63 65 20  turn the device 
3a20: 63 68 61 72 61 63 74 65 72 69 73 74 69 63 20 66  characteristic f
3a30: 6c 61 67 73 20 73 75 70 70 6f 72 74 65 64 20 62  lags supported b
3a40: 79 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  y an tvfs-file..
3a50: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3a60: 66 73 44 65 76 69 63 65 43 68 61 72 61 63 74 65  fsDeviceCharacte
3a70: 72 69 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f  ristics(sqlite3_
3a80: 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20  file *pFile){.  
3a90: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
3aa0: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
3ab0: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
3ac0: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
3ad0: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
3ae0: 3b 0a 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63  ;.  if( p->iDevc
3af0: 68 61 72 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65  har>=0 ){.    re
3b00: 74 75 72 6e 20 70 2d 3e 69 44 65 76 63 68 61 72  turn p->iDevchar
3b10: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
3b20: 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65 43 68  qlite3OsDeviceCh
3b30: 61 72 61 63 74 65 72 69 73 74 69 63 73 28 70 46  aracteristics(pF
3b40: 64 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a  d->pReal);.}../*
3b50: 0a 2a 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73  .** Open an tvfs
3b60: 20 66 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f   file handle..*/
3b70: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3b80: 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  Open(.  sqlite3_
3b90: 76 66 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e  vfs *pVfs,.  con
3ba0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a  st char *zName,.
3bb0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3bc0: 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61  pFile,.  int fla
3bd0: 67 73 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46  gs,.  int *pOutF
3be0: 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63  lags.){.  int rc
3bf0: 3b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20  ;.  TestvfsFile 
3c00: 2a 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65  *pTestfile = (Te
3c10: 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c  stvfsFile *)pFil
3c20: 65 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  e;.  TestvfsFd *
3c30: 70 46 64 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  pFd;.  Tcl_Obj *
3c40: 70 49 64 20 3d 20 30 3b 0a 20 20 54 65 73 74 76  pId = 0;.  Testv
3c50: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
3c60: 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74   *)pVfs->pAppDat
3c70: 61 3b 0a 0a 20 20 70 46 64 20 3d 20 28 54 65 73  a;..  pFd = (Tes
3c80: 74 76 66 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63  tvfsFd *)ckalloc
3c90: 28 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46  (sizeof(TestvfsF
3ca0: 64 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70  d) + PARENTVFS(p
3cb0: 56 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b  Vfs)->szOsFile);
3cc0: 0a 20 20 6d 65 6d 73 65 74 28 70 46 64 2c 20 30  .  memset(pFd, 0
3cd0: 2c 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  , sizeof(Testvfs
3ce0: 46 64 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28  Fd) + PARENTVFS(
3cf0: 70 56 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29  pVfs)->szOsFile)
3d00: 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20  ;.  pFd->pShm = 
3d10: 30 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64  0;.  pFd->pShmId
3d20: 20 3d 20 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69   = 0;.  pFd->zFi
3d30: 6c 65 6e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a  lename = zName;.
3d40: 20 20 70 46 64 2d 3e 70 56 66 73 20 3d 20 70 56    pFd->pVfs = pV
3d50: 66 73 3b 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c  fs;.  pFd->pReal
3d60: 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65   = (sqlite3_file
3d70: 20 2a 29 26 70 46 64 5b 31 5d 3b 0a 20 20 6d 65   *)&pFd[1];.  me
3d80: 6d 73 65 74 28 70 54 65 73 74 66 69 6c 65 2c 20  mset(pTestfile, 
3d90: 30 2c 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66  0, sizeof(Testvf
3da0: 73 46 69 6c 65 29 29 3b 0a 20 20 70 54 65 73 74  sFile));.  pTest
3db0: 66 69 6c 65 2d 3e 70 46 64 20 3d 20 70 46 64 3b  file->pFd = pFd;
3dc0: 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61 74 65 20  ..  /* Evaluate 
3dd0: 74 68 65 20 54 63 6c 20 73 63 72 69 70 74 3a 20  the Tcl script: 
3de0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43 52  .  **.  **   SCR
3df0: 49 50 54 20 78 4f 70 65 6e 20 46 49 4c 45 4e 41  IPT xOpen FILENA
3e00: 4d 45 20 4b 45 59 2d 56 41 4c 55 45 2d 41 52 47  ME KEY-VALUE-ARG
3e10: 53 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 74  S.  **.  ** If t
3e20: 68 65 20 73 63 72 69 70 74 20 72 65 74 75 72 6e  he script return
3e30: 73 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  s an SQLite erro
3e40: 72 20 63 6f 64 65 20 6f 74 68 65 72 20 74 68 61  r code other tha
3e50: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 61 6e 0a  n SQLITE_OK, an.
3e60: 20 20 2a 2a 20 65 72 72 6f 72 20 69 73 20 72 65    ** error is re
3e70: 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61  turned to the ca
3e80: 6c 6c 65 72 2e 20 49 66 20 69 74 20 72 65 74 75  ller. If it retu
3e90: 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 74  rns SQLITE_OK, t
3ea0: 68 65 20 6e 65 77 0a 20 20 2a 2a 20 63 6f 6e 6e  he new.  ** conn
3eb0: 65 63 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20  ection is named 
3ec0: 22 61 6e 6f 6e 22 2e 20 4f 74 68 65 72 77 69 73  "anon". Otherwis
3ed0: 65 2c 20 74 68 65 20 76 61 6c 75 65 20 72 65 74  e, the value ret
3ee0: 75 72 6e 65 64 20 62 79 20 74 68 65 0a 20 20 2a  urned by the.  *
3ef0: 2a 20 73 63 72 69 70 74 20 69 73 20 75 73 65 64  * script is used
3f00: 20 61 73 20 74 68 65 20 63 6f 6e 6e 65 63 74 69   as the connecti
3f10: 6f 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20  on name..  */.  
3f20: 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28  Tcl_ResetResult(
3f30: 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66  p->interp);.  if
3f40: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
3f50: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
3f60: 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  OPEN_MASK ){.   
3f70: 20 54 63 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d   Tcl_Obj *pArg =
3f80: 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20   Tcl_NewObj();. 
3f90: 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f     Tcl_IncrRefCo
3fa0: 75 6e 74 28 70 41 72 67 29 3b 0a 20 20 20 20 69  unt(pArg);.    i
3fb0: 66 28 20 66 6c 61 67 73 26 53 51 4c 49 54 45 5f  f( flags&SQLITE_
3fc0: 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 20 29 7b 0a  OPEN_MAIN_DB ){.
3fd0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
3fe0: 20 2a 7a 20 3d 20 26 7a 4e 61 6d 65 5b 73 74 72   *z = &zName[str
3ff0: 6c 65 6e 28 7a 4e 61 6d 65 29 2b 31 5d 3b 0a 20  len(zName)+1];. 
4000: 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 29       while( *z )
4010: 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69  {.        Tcl_Li
4020: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
4030: 6e 74 28 30 2c 20 70 41 72 67 2c 20 54 63 6c 5f  nt(0, pArg, Tcl_
4040: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20  NewStringObj(z, 
4050: 2d 31 29 29 3b 0a 20 20 20 20 20 20 20 20 7a 20  -1));.        z 
4060: 2b 3d 20 73 74 72 6c 65 6e 28 7a 29 20 2b 20 31  += strlen(z) + 1
4070: 3b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69  ;.        Tcl_Li
4080: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
4090: 6e 74 28 30 2c 20 70 41 72 67 2c 20 54 63 6c 5f  nt(0, pArg, Tcl_
40a0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20  NewStringObj(z, 
40b0: 2d 31 29 29 3b 0a 20 20 20 20 20 20 20 20 7a 20  -1));.        z 
40c0: 2b 3d 20 73 74 72 6c 65 6e 28 7a 29 20 2b 20 31  += strlen(z) + 1
40d0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
40e0: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
40f0: 70 2c 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c 5f  p, "xOpen", Tcl_
4100: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
4110: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29  ->zFilename, -1)
4120: 2c 20 70 41 72 67 2c 20 30 29 3b 0a 20 20 20 20  , pArg, 0);.    
4130: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
4140: 28 70 41 72 67 29 3b 0a 20 20 20 20 69 66 28 20  (pArg);.    if( 
4150: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
4160: 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20  , &rc) ){.      
4170: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
4180: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
4190: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
41a0: 70 49 64 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a  pId = Tcl_GetObj
41b0: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
41c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
41d0: 69 66 28 20 28 70 2d 3e 6d 61 73 6b 26 54 45 53  if( (p->mask&TES
41e0: 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 29 20  TVFS_OPEN_MASK) 
41f0: 26 26 20 20 74 76 66 73 49 6e 6a 65 63 74 49 6f  &&  tvfsInjectIo
4200: 65 72 72 28 70 29 20 29 20 72 65 74 75 72 6e 20  err(p) ) return 
4210: 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20  SQLITE_IOERR;.  
4220: 69 66 28 20 74 76 66 73 49 6e 6a 65 63 74 43 61  if( tvfsInjectCa
4230: 6e 74 6f 70 65 6e 65 72 72 28 70 29 20 29 20 72  ntopenerr(p) ) r
4240: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 41 4e  eturn SQLITE_CAN
4250: 54 4f 50 45 4e 3b 0a 20 20 69 66 28 20 74 76 66  TOPEN;.  if( tvf
4260: 73 49 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28 70  sInjectFullerr(p
4270: 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ) ) return SQLIT
4280: 45 5f 46 55 4c 4c 3b 0a 0a 20 20 69 66 28 20 21  E_FULL;..  if( !
4290: 70 49 64 20 29 7b 0a 20 20 20 20 70 49 64 20 3d  pId ){.    pId =
42a0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
42b0: 6a 28 22 61 6e 6f 6e 22 2c 20 2d 31 29 3b 0a 20  j("anon", -1);. 
42c0: 20 7d 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66   }.  Tcl_IncrRef
42d0: 43 6f 75 6e 74 28 70 49 64 29 3b 0a 20 20 70 46  Count(pId);.  pF
42e0: 64 2d 3e 70 53 68 6d 49 64 20 3d 20 70 49 64 3b  d->pShmId = pId;
42f0: 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75  .  Tcl_ResetResu
4300: 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 0a  lt(p->interp);..
4310: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
4320: 4f 70 65 6e 28 50 41 52 45 4e 54 56 46 53 28 70  Open(PARENTVFS(p
4330: 56 66 73 29 2c 20 7a 4e 61 6d 65 2c 20 70 46 64  Vfs), zName, pFd
4340: 2d 3e 70 52 65 61 6c 2c 20 66 6c 61 67 73 2c 20  ->pReal, flags, 
4350: 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 69 66  pOutFlags);.  if
4360: 28 20 70 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d  ( pFd->pReal->pM
4370: 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 73 71  ethods ){.    sq
4380: 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73  lite3_io_methods
4390: 20 2a 70 4d 65 74 68 6f 64 73 3b 0a 20 20 20 20   *pMethods;.    
43a0: 69 6e 74 20 6e 42 79 74 65 3b 0a 0a 20 20 20 20  int nByte;..    
43b0: 69 66 28 20 70 56 66 73 2d 3e 69 56 65 72 73 69  if( pVfs->iVersi
43c0: 6f 6e 3e 31 20 29 7b 0a 20 20 20 20 20 20 6e 42  on>1 ){.      nB
43d0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c  yte = sizeof(sql
43e0: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29  ite3_io_methods)
43f0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
4400: 20 20 20 6e 42 79 74 65 20 3d 20 6f 66 66 73 65     nByte = offse
4410: 74 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  tof(sqlite3_io_m
4420: 65 74 68 6f 64 73 2c 20 78 53 68 6d 4d 61 70 29  ethods, xShmMap)
4430: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4d 65  ;.    }..    pMe
4440: 74 68 6f 64 73 20 3d 20 28 73 71 6c 69 74 65 33  thods = (sqlite3
4450: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 29 63 6b  _io_methods *)ck
4460: 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20  alloc(nByte);.  
4470: 20 20 6d 65 6d 63 70 79 28 70 4d 65 74 68 6f 64    memcpy(pMethod
4480: 73 2c 20 26 74 76 66 73 5f 69 6f 5f 6d 65 74 68  s, &tvfs_io_meth
4490: 6f 64 73 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  ods, nByte);.   
44a0: 20 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73   pMethods->iVers
44b0: 69 6f 6e 20 3d 20 70 56 66 73 2d 3e 69 56 65 72  ion = pVfs->iVer
44c0: 73 69 6f 6e 3b 0a 20 20 20 20 69 66 28 20 70 56  sion;.    if( pV
44d0: 66 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 31 20 26  fs->iVersion>1 &
44e0: 26 20 28 28 54 65 73 74 76 66 73 20 2a 29 70 56  & ((Testvfs *)pV
44f0: 66 73 2d 3e 70 41 70 70 44 61 74 61 29 2d 3e 69  fs->pAppData)->i
4500: 73 4e 6f 73 68 6d 20 29 7b 0a 20 20 20 20 20 20  sNoshm ){.      
4510: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e  pMethods->xShmUn
4520: 6d 61 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  map = 0;.      p
4530: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63  Methods->xShmLoc
4540: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65  k = 0;.      pMe
4550: 74 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72 69  thods->xShmBarri
4560: 65 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d  er = 0;.      pM
4570: 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 20  ethods->xShmMap 
4580: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  = 0;.    }.    p
4590: 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 20 3d  File->pMethods =
45a0: 20 70 4d 65 74 68 6f 64 73 3b 0a 20 20 7d 0a 0a   pMethods;.  }..
45b0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
45c0: 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 74 68 65  /*.** Delete the
45d0: 20 66 69 6c 65 20 6c 6f 63 61 74 65 64 20 61 74   file located at
45e0: 20 7a 50 61 74 68 2e 20 49 66 20 74 68 65 20 64   zPath. If the d
45f0: 69 72 53 79 6e 63 20 61 72 67 75 6d 65 6e 74 20  irSync argument 
4600: 69 73 20 74 72 75 65 2c 0a 2a 2a 20 65 6e 73 75  is true,.** ensu
4610: 72 65 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74  re the file-syst
4620: 65 6d 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73  em modifications
4630: 20 61 72 65 20 73 79 6e 63 65 64 20 74 6f 20 64   are synced to d
4640: 69 73 6b 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65  isk before.** re
4650: 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  turning..*/.stat
4660: 69 63 20 69 6e 74 20 74 76 66 73 44 65 6c 65 74  ic int tvfsDelet
4670: 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  e(sqlite3_vfs *p
4680: 56 66 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Vfs, const char 
4690: 2a 7a 50 61 74 68 2c 20 69 6e 74 20 64 69 72 53  *zPath, int dirS
46a0: 79 6e 63 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ync){.  int rc =
46b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
46c0: 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74  stvfs *p = (Test
46d0: 76 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70  vfs *)pVfs->pApp
46e0: 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  Data;..  if( p->
46f0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
4700: 73 6b 26 54 45 53 54 56 46 53 5f 44 45 4c 45 54  sk&TESTVFS_DELET
4710: 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76  E_MASK ){.    tv
4720: 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 44  fsExecTcl(p, "xD
4730: 65 6c 65 74 65 22 2c 20 0a 20 20 20 20 20 20 20  elete", .       
4740: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
4750: 6a 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63  j(zPath, -1), Tc
4760: 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 64 69 72 53  l_NewIntObj(dirS
4770: 79 6e 63 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20  ync), 0.    );. 
4780: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
4790: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20  e(p, &rc);.  }. 
47a0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
47b0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  OK ){.    rc = s
47c0: 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28 50  qlite3OsDelete(P
47d0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
47e0: 7a 50 61 74 68 2c 20 64 69 72 53 79 6e 63 29 3b  zPath, dirSync);
47f0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
4800: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20  ;.}../*.** Test 
4810: 66 6f 72 20 61 63 63 65 73 73 20 70 65 72 6d 69  for access permi
4820: 73 73 69 6f 6e 73 2e 20 52 65 74 75 72 6e 20 74  ssions. Return t
4830: 72 75 65 20 69 66 20 74 68 65 20 72 65 71 75 65  rue if the reque
4840: 73 74 65 64 20 70 65 72 6d 69 73 73 69 6f 6e 0a  sted permission.
4850: 2a 2a 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2c  ** is available,
4860: 20 6f 72 20 66 61 6c 73 65 20 6f 74 68 65 72 77   or false otherw
4870: 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
4880: 6e 74 20 74 76 66 73 41 63 63 65 73 73 28 0a 20  nt tvfsAccess(. 
4890: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
48a0: 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  fs, .  const cha
48b0: 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74  r *zPath, .  int
48c0: 20 66 6c 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a   flags, .  int *
48d0: 70 52 65 73 4f 75 74 0a 29 7b 0a 20 20 54 65 73  pResOut.){.  Tes
48e0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
48f0: 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44  fs *)pVfs->pAppD
4900: 61 74 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53  ata;.  if( p->pS
4910: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
4920: 26 54 45 53 54 56 46 53 5f 41 43 43 45 53 53 5f  &TESTVFS_ACCESS_
4930: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  MASK ){.    int 
4940: 72 63 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41  rc;.    char *zA
4950: 72 67 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20  rg = 0;.    if( 
4960: 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43  flags==SQLITE_AC
4970: 43 45 53 53 5f 45 58 49 53 54 53 20 29 20 7a 41  CESS_EXISTS ) zA
4980: 72 67 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43  rg = "SQLITE_ACC
4990: 45 53 53 5f 45 58 49 53 54 53 22 3b 0a 20 20 20  ESS_EXISTS";.   
49a0: 20 69 66 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49   if( flags==SQLI
49b0: 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52  TE_ACCESS_READWR
49c0: 49 54 45 20 29 20 7a 41 72 67 20 3d 20 22 53 51  ITE ) zArg = "SQ
49d0: 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44  LITE_ACCESS_READ
49e0: 57 52 49 54 45 22 3b 0a 20 20 20 20 69 66 28 20  WRITE";.    if( 
49f0: 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43  flags==SQLITE_AC
4a00: 43 45 53 53 5f 52 45 41 44 20 29 20 7a 41 72 67  CESS_READ ) zArg
4a10: 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53   = "SQLITE_ACCES
4a20: 53 5f 52 45 41 44 22 3b 0a 20 20 20 20 74 76 66  S_READ";.    tvf
4a30: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 41 63  sExecTcl(p, "xAc
4a40: 63 65 73 73 22 2c 20 0a 20 20 20 20 20 20 20 20  cess", .        
4a50: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
4a60: 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c  (zPath, -1), Tcl
4a70: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 41  _NewStringObj(zA
4a80: 72 67 2c 20 2d 31 29 2c 20 30 0a 20 20 20 20 29  rg, -1), 0.    )
4a90: 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52 65  ;.    if( tvfsRe
4aa0: 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29  sultCode(p, &rc)
4ab0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63   ){.      if( rc
4ac0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65  !=SQLITE_OK ) re
4ad0: 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c  turn rc;.    }el
4ae0: 73 65 7b 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e  se{.      Tcl_In
4af0: 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70  terp *interp = p
4b00: 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 20 20 20 20  ->interp;.      
4b10: 69 66 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f  if( TCL_OK==Tcl_
4b20: 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62  GetBooleanFromOb
4b30: 6a 28 30 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52  j(0, Tcl_GetObjR
4b40: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 70  esult(interp), p
4b50: 52 65 73 4f 75 74 29 20 29 7b 0a 20 20 20 20 20  ResOut) ){.     
4b60: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
4b70: 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  _OK;.      }.   
4b80: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
4b90: 73 71 6c 69 74 65 33 4f 73 41 63 63 65 73 73 28  sqlite3OsAccess(
4ba0: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
4bb0: 20 7a 50 61 74 68 2c 20 66 6c 61 67 73 2c 20 70   zPath, flags, p
4bc0: 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  ResOut);.}../*.*
4bd0: 2a 20 50 6f 70 75 6c 61 74 65 20 62 75 66 66 65  * Populate buffe
4be0: 72 20 7a 4f 75 74 20 77 69 74 68 20 74 68 65 20  r zOut with the 
4bf0: 66 75 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70  full canonical p
4c00: 61 74 68 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f  athname correspo
4c10: 6e 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20  nding.** to the 
4c20: 70 61 74 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74  pathname in zPat
4c30: 68 2e 20 7a 4f 75 74 20 69 73 20 67 75 61 72 61  h. zOut is guara
4c40: 6e 74 65 65 64 20 74 6f 20 70 6f 69 6e 74 20 74  nteed to point t
4c50: 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66  o a buffer.** of
4c60: 20 61 74 20 6c 65 61 73 74 20 28 44 45 56 53 59   at least (DEVSY
4c70: 4d 5f 4d 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31  M_MAX_PATHNAME+1
4c80: 29 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74  ) bytes..*/.stat
4c90: 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c 50  ic int tvfsFullP
4ca0: 61 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74  athname(.  sqlit
4cb0: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 0a 20  e3_vfs *pVfs, . 
4cc0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61   const char *zPa
4cd0: 74 68 2c 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c  th, .  int nOut,
4ce0: 20 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29   .  char *zOut.)
4cf0: 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  {.  Testvfs *p =
4d00: 20 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73   (Testvfs *)pVfs
4d10: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 69 66  ->pAppData;.  if
4d20: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
4d30: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
4d40: 46 55 4c 4c 50 41 54 48 4e 41 4d 45 5f 4d 41 53  FULLPATHNAME_MAS
4d50: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b  K ){.    int rc;
4d60: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
4d70: 28 70 2c 20 22 78 46 75 6c 6c 50 61 74 68 6e 61  (p, "xFullPathna
4d80: 6d 65 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  me", Tcl_NewStri
4d90: 6e 67 4f 62 6a 28 7a 50 61 74 68 2c 20 2d 31 29  ngObj(zPath, -1)
4da0: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28  , 0, 0);.    if(
4db0: 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28   tvfsResultCode(
4dc0: 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20  p, &rc) ){.     
4dd0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
4de0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
4df0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
4e00: 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 75 6c 6c  rn sqlite3OsFull
4e10: 50 61 74 68 6e 61 6d 65 28 50 41 52 45 4e 54 56  Pathname(PARENTV
4e20: 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74 68 2c  FS(pVfs), zPath,
4e30: 20 6e 4f 75 74 2c 20 7a 4f 75 74 29 3b 0a 7d 0a   nOut, zOut);.}.
4e40: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
4e50: 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53  OMIT_LOAD_EXTENS
4e60: 49 4f 4e 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 74  ION./*.** Open t
4e70: 68 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61  he dynamic libra
4e80: 72 79 20 6c 6f 63 61 74 65 64 20 61 74 20 7a 50  ry located at zP
4e90: 61 74 68 20 61 6e 64 20 72 65 74 75 72 6e 20 61  ath and return a
4ea0: 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74   handle..*/.stat
4eb0: 69 63 20 76 6f 69 64 20 2a 74 76 66 73 44 6c 4f  ic void *tvfsDlO
4ec0: 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73 20  pen(sqlite3_vfs 
4ed0: 2a 70 56 66 73 2c 20 63 6f 6e 73 74 20 63 68 61  *pVfs, const cha
4ee0: 72 20 2a 7a 50 61 74 68 29 7b 0a 20 20 72 65 74  r *zPath){.  ret
4ef0: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 44 6c 4f  urn sqlite3OsDlO
4f00: 70 65 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56  pen(PARENTVFS(pV
4f10: 66 73 29 2c 20 7a 50 61 74 68 29 3b 0a 7d 0a 0a  fs), zPath);.}..
4f20: 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 74  /*.** Populate t
4f30: 68 65 20 62 75 66 66 65 72 20 7a 45 72 72 4d 73  he buffer zErrMs
4f40: 67 20 28 73 69 7a 65 20 6e 42 79 74 65 20 62 79  g (size nByte by
4f50: 74 65 73 29 20 77 69 74 68 20 61 20 68 75 6d 61  tes) with a huma
4f60: 6e 20 72 65 61 64 61 62 6c 65 0a 2a 2a 20 75 74  n readable.** ut
4f70: 66 2d 38 20 73 74 72 69 6e 67 20 64 65 73 63 72  f-8 string descr
4f80: 69 62 69 6e 67 20 74 68 65 20 6d 6f 73 74 20 72  ibing the most r
4f90: 65 63 65 6e 74 20 65 72 72 6f 72 20 65 6e 63 6f  ecent error enco
4fa0: 75 6e 74 65 72 65 64 20 61 73 73 6f 63 69 61 74  untered associat
4fb0: 65 64 20 0a 2a 2a 20 77 69 74 68 20 64 79 6e 61  ed .** with dyna
4fc0: 6d 69 63 20 6c 69 62 72 61 72 69 65 73 2e 0a 2a  mic libraries..*
4fd0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76  /.static void tv
4fe0: 66 73 44 6c 45 72 72 6f 72 28 73 71 6c 69 74 65  fsDlError(sqlite
4ff0: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69 6e 74  3_vfs *pVfs, int
5000: 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a 7a 45   nByte, char *zE
5010: 72 72 4d 73 67 29 7b 0a 20 20 73 71 6c 69 74 65  rrMsg){.  sqlite
5020: 33 4f 73 44 6c 45 72 72 6f 72 28 50 41 52 45 4e  3OsDlError(PAREN
5030: 54 56 46 53 28 70 56 66 73 29 2c 20 6e 42 79 74  TVFS(pVfs), nByt
5040: 65 2c 20 7a 45 72 72 4d 73 67 29 3b 0a 7d 0a 0a  e, zErrMsg);.}..
5050: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70  /*.** Return a p
5060: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 73 79  ointer to the sy
5070: 6d 62 6f 6c 20 7a 53 79 6d 62 6f 6c 20 69 6e 20  mbol zSymbol in 
5080: 74 68 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72  the dynamic libr
5090: 61 72 79 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a  ary pHandle..*/.
50a0: 73 74 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76  static void (*tv
50b0: 66 73 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f  fsDlSym(sqlite3_
50c0: 76 66 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20  vfs *pVfs, void 
50d0: 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  *p, const char *
50e0: 7a 53 79 6d 29 29 28 76 6f 69 64 29 7b 0a 20 20  zSym))(void){.  
50f0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
5100: 44 6c 53 79 6d 28 50 41 52 45 4e 54 56 46 53 28  DlSym(PARENTVFS(
5110: 70 56 66 73 29 2c 20 70 2c 20 7a 53 79 6d 29 3b  pVfs), p, zSym);
5120: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
5130: 74 68 65 20 64 79 6e 61 6d 69 63 20 6c 69 62 72  the dynamic libr
5140: 61 72 79 20 68 61 6e 64 6c 65 20 70 48 61 6e 64  ary handle pHand
5150: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
5160: 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28 73  id tvfsDlClose(s
5170: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
5180: 2c 20 76 6f 69 64 20 2a 70 48 61 6e 64 6c 65 29  , void *pHandle)
5190: 7b 0a 20 20 73 71 6c 69 74 65 33 4f 73 44 6c 43  {.  sqlite3OsDlC
51a0: 6c 6f 73 65 28 50 41 52 45 4e 54 56 46 53 28 70  lose(PARENTVFS(p
51b0: 56 66 73 29 2c 20 70 48 61 6e 64 6c 65 29 3b 0a  Vfs), pHandle);.
51c0: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
51d0: 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54  TE_OMIT_LOAD_EXT
51e0: 45 4e 53 49 4f 4e 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  ENSION */../*.**
51f0: 20 50 6f 70 75 6c 61 74 65 20 74 68 65 20 62 75   Populate the bu
5200: 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20  ffer pointed to 
5210: 62 79 20 7a 42 75 66 4f 75 74 20 77 69 74 68 20  by zBufOut with 
5220: 6e 42 79 74 65 20 62 79 74 65 73 20 6f 66 20 0a  nByte bytes of .
5230: 2a 2a 20 72 61 6e 64 6f 6d 20 64 61 74 61 2e 0a  ** random data..
5240: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
5250: 66 73 52 61 6e 64 6f 6d 6e 65 73 73 28 73 71 6c  fsRandomness(sql
5260: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
5270: 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20  int nByte, char 
5280: 2a 7a 42 75 66 4f 75 74 29 7b 0a 20 20 72 65 74  *zBufOut){.  ret
5290: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 61 6e  urn sqlite3OsRan
52a0: 64 6f 6d 6e 65 73 73 28 50 41 52 45 4e 54 56 46  domness(PARENTVF
52b0: 53 28 70 56 66 73 29 2c 20 6e 42 79 74 65 2c 20  S(pVfs), nByte, 
52c0: 7a 42 75 66 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a  zBufOut);.}../*.
52d0: 2a 2a 20 53 6c 65 65 70 20 66 6f 72 20 6e 4d 69  ** Sleep for nMi
52e0: 63 72 6f 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73  cro microseconds
52f0: 2e 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  . Return the num
5300: 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65 63 6f  ber of microseco
5310: 6e 64 73 20 0a 2a 2a 20 61 63 74 75 61 6c 6c 79  nds .** actually
5320: 20 73 6c 65 70 74 2e 0a 2a 2f 0a 73 74 61 74 69   slept..*/.stati
5330: 63 20 69 6e 74 20 74 76 66 73 53 6c 65 65 70 28  c int tvfsSleep(
5340: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
5350: 73 2c 20 69 6e 74 20 6e 4d 69 63 72 6f 29 7b 0a  s, int nMicro){.
5360: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
5370: 4f 73 53 6c 65 65 70 28 50 41 52 45 4e 54 56 46  OsSleep(PARENTVF
5380: 53 28 70 56 66 73 29 2c 20 6e 4d 69 63 72 6f 29  S(pVfs), nMicro)
5390: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
53a0: 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 69  n the current ti
53b0: 6d 65 20 61 73 20 61 20 4a 75 6c 69 61 6e 20 44  me as a Julian D
53c0: 61 79 20 6e 75 6d 62 65 72 20 69 6e 20 2a 70 54  ay number in *pT
53d0: 69 6d 65 4f 75 74 2e 0a 2a 2f 0a 73 74 61 74 69  imeOut..*/.stati
53e0: 63 20 69 6e 74 20 74 76 66 73 43 75 72 72 65 6e  c int tvfsCurren
53f0: 74 54 69 6d 65 28 73 71 6c 69 74 65 33 5f 76 66  tTime(sqlite3_vf
5400: 73 20 2a 70 56 66 73 2c 20 64 6f 75 62 6c 65 20  s *pVfs, double 
5410: 2a 70 54 69 6d 65 4f 75 74 29 7b 0a 20 20 72 65  *pTimeOut){.  re
5420: 74 75 72 6e 20 50 41 52 45 4e 54 56 46 53 28 70  turn PARENTVFS(p
5430: 56 66 73 29 2d 3e 78 43 75 72 72 65 6e 74 54 69  Vfs)->xCurrentTi
5440: 6d 65 28 50 41 52 45 4e 54 56 46 53 28 70 56 66  me(PARENTVFS(pVf
5450: 73 29 2c 20 70 54 69 6d 65 4f 75 74 29 3b 0a 7d  s), pTimeOut);.}
5460: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ..static int tvf
5470: 73 53 68 6d 4f 70 65 6e 28 73 71 6c 69 74 65 33  sShmOpen(sqlite3
5480: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20  _file *pFile){. 
5490: 20 54 65 73 74 76 66 73 20 2a 70 3b 0a 20 20 69   Testvfs *p;.  i
54a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
54b0: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
54c0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
54d0: 0a 20 20 54 65 73 74 76 66 73 42 75 66 66 65 72  .  TestvfsBuffer
54e0: 20 2a 70 42 75 66 66 65 72 3b 20 20 20 20 20 20   *pBuffer;      
54f0: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
5500: 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  open connection 
5510: 74 6f 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 46  to */.  TestvfsF
5520: 64 20 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20  d *pFd;         
5530: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 74          /* The t
5540: 65 73 74 76 66 73 20 66 69 6c 65 20 73 74 72 75  estvfs file stru
5550: 63 74 75 72 65 20 2a 2f 0a 0a 20 20 70 46 64 20  cture */..  pFd 
5560: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
5570: 65 29 3b 0a 20 20 70 20 3d 20 28 54 65 73 74 76  e);.  p = (Testv
5580: 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e  fs *)pFd->pVfs->
5590: 70 41 70 70 44 61 74 61 3b 0a 20 20 61 73 73 65  pAppData;.  asse
55a0: 72 74 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20  rt( pFd->pShmId 
55b0: 26 26 20 70 46 64 2d 3e 70 53 68 6d 3d 3d 30 20  && pFd->pShm==0 
55c0: 26 26 20 70 46 64 2d 3e 70 4e 65 78 74 3d 3d 30  && pFd->pNext==0
55d0: 20 29 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61   );..  /* Evalua
55e0: 74 65 20 74 68 65 20 54 63 6c 20 73 63 72 69 70  te the Tcl scrip
55f0: 74 3a 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  t: .  **.  **   
5600: 53 43 52 49 50 54 20 78 53 68 6d 4f 70 65 6e 20  SCRIPT xShmOpen 
5610: 46 49 4c 45 4e 41 4d 45 0a 20 20 2a 2f 0a 20 20  FILENAME.  */.  
5620: 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28  Tcl_ResetResult(
5630: 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66  p->interp);.  if
5640: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
5650: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
5660: 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a  SHMOPEN_MASK ){.
5670: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
5680: 70 2c 20 22 78 53 68 6d 4f 70 65 6e 22 2c 20 54  p, "xShmOpen", T
5690: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
56a0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
56b0: 2d 31 29 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20  -1), 0, 0);.    
56c0: 69 66 28 20 74 76 66 73 52 65 73 75 6c 74 43 6f  if( tvfsResultCo
56d0: 64 65 28 70 2c 20 26 72 63 29 20 29 7b 0a 20 20  de(p, &rc) ){.  
56e0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
56f0: 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72  TE_OK ) return r
5700: 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  c;.    }.  }..  
5710: 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
5720: 54 45 5f 4f 4b 20 29 3b 0a 20 20 69 66 28 20 70  TE_OK );.  if( p
5730: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
5740: 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 26 26 20 74  HMOPEN_MASK && t
5750: 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70  vfsInjectIoerr(p
5760: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
5770: 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20  SQLITE_IOERR;.  
5780: 7d 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 66  }..  /* Search f
5790: 6f 72 20 61 20 54 65 73 74 76 66 73 42 75 66 66  or a TestvfsBuff
57a0: 65 72 2e 20 43 72 65 61 74 65 20 61 20 6e 65 77  er. Create a new
57b0: 20 6f 6e 65 20 69 66 20 72 65 71 75 69 72 65 64   one if required
57c0: 2e 20 2a 2f 0a 20 20 66 6f 72 28 70 42 75 66 66  . */.  for(pBuff
57d0: 65 72 3d 70 2d 3e 70 42 75 66 66 65 72 3b 20 70  er=p->pBuffer; p
57e0: 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72 3d  Buffer; pBuffer=
57f0: 70 42 75 66 66 65 72 2d 3e 70 4e 65 78 74 29 7b  pBuffer->pNext){
5800: 0a 20 20 20 20 69 66 28 20 30 3d 3d 73 74 72 63  .    if( 0==strc
5810: 6d 70 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  mp(pFd->zFilenam
5820: 65 2c 20 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c  e, pBuffer->zFil
5830: 65 29 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  e) ) break;.  }.
5840: 20 20 69 66 28 20 21 70 42 75 66 66 65 72 20 29    if( !pBuffer )
5850: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
5860: 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  = sizeof(Testvfs
5870: 42 75 66 66 65 72 29 20 2b 20 73 74 72 6c 65 6e  Buffer) + strlen
5880: 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29  (pFd->zFilename)
5890: 20 2b 20 31 3b 0a 20 20 20 20 70 42 75 66 66 65   + 1;.    pBuffe
58a0: 72 20 3d 20 28 54 65 73 74 76 66 73 42 75 66 66  r = (TestvfsBuff
58b0: 65 72 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e 42 79  er *)ckalloc(nBy
58c0: 74 65 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  te);.    memset(
58d0: 70 42 75 66 66 65 72 2c 20 30 2c 20 6e 42 79 74  pBuffer, 0, nByt
58e0: 65 29 3b 0a 20 20 20 20 70 42 75 66 66 65 72 2d  e);.    pBuffer-
58f0: 3e 7a 46 69 6c 65 20 3d 20 28 63 68 61 72 20 2a  >zFile = (char *
5900: 29 26 70 42 75 66 66 65 72 5b 31 5d 3b 0a 20 20  )&pBuffer[1];.  
5910: 20 20 73 74 72 63 70 79 28 70 42 75 66 66 65 72    strcpy(pBuffer
5920: 2d 3e 7a 46 69 6c 65 2c 20 70 46 64 2d 3e 7a 46  ->zFile, pFd->zF
5930: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 70 42  ilename);.    pB
5940: 75 66 66 65 72 2d 3e 70 4e 65 78 74 20 3d 20 70  uffer->pNext = p
5950: 2d 3e 70 42 75 66 66 65 72 3b 0a 20 20 20 20 70  ->pBuffer;.    p
5960: 2d 3e 70 42 75 66 66 65 72 20 3d 20 70 42 75 66  ->pBuffer = pBuf
5970: 66 65 72 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  fer;.  }..  /* C
5980: 6f 6e 6e 65 63 74 20 74 68 65 20 54 65 73 74 76  onnect the Testv
5990: 66 73 42 75 66 66 65 72 20 74 6f 20 74 68 65 20  fsBuffer to the 
59a0: 6e 65 77 20 54 65 73 74 76 66 73 53 68 6d 20 68  new TestvfsShm h
59b0: 61 6e 64 6c 65 20 61 6e 64 20 72 65 74 75 72 6e  andle and return
59c0: 2e 20 2a 2f 0a 20 20 70 46 64 2d 3e 70 4e 65 78  . */.  pFd->pNex
59d0: 74 20 3d 20 70 42 75 66 66 65 72 2d 3e 70 46 69  t = pBuffer->pFi
59e0: 6c 65 3b 0a 20 20 70 42 75 66 66 65 72 2d 3e 70  le;.  pBuffer->p
59f0: 46 69 6c 65 20 3d 20 70 46 64 3b 0a 20 20 70 46  File = pFd;.  pF
5a00: 64 2d 3e 70 53 68 6d 20 3d 20 70 42 75 66 66 65  d->pShm = pBuffe
5a10: 72 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  r;.  return SQLI
5a20: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63  TE_OK;.}..static
5a30: 20 76 6f 69 64 20 74 76 66 73 41 6c 6c 6f 63 50   void tvfsAllocP
5a40: 61 67 65 28 54 65 73 74 76 66 73 42 75 66 66 65  age(TestvfsBuffe
5a50: 72 20 2a 70 2c 20 69 6e 74 20 69 50 61 67 65 2c  r *p, int iPage,
5a60: 20 69 6e 74 20 70 67 73 7a 29 7b 0a 20 20 61 73   int pgsz){.  as
5a70: 73 65 72 74 28 20 69 50 61 67 65 3c 54 45 53 54  sert( iPage<TEST
5a80: 56 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 29 3b  VFS_MAX_PAGES );
5a90: 0a 20 20 69 66 28 20 70 2d 3e 61 50 61 67 65 5b  .  if( p->aPage[
5aa0: 69 50 61 67 65 5d 3d 3d 30 20 29 7b 0a 20 20 20  iPage]==0 ){.   
5ab0: 20 70 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d   p->aPage[iPage]
5ac0: 20 3d 20 28 75 38 20 2a 29 63 6b 61 6c 6c 6f 63   = (u8 *)ckalloc
5ad0: 28 70 67 73 7a 29 3b 0a 20 20 20 20 6d 65 6d 73  (pgsz);.    mems
5ae0: 65 74 28 70 2d 3e 61 50 61 67 65 5b 69 50 61 67  et(p->aPage[iPag
5af0: 65 5d 2c 20 30 2c 20 70 67 73 7a 29 3b 0a 20 20  e], 0, pgsz);.  
5b00: 20 20 70 2d 3e 70 67 73 7a 20 3d 20 70 67 73 7a    p->pgsz = pgsz
5b10: 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
5b20: 69 6e 74 20 74 76 66 73 53 68 6d 4d 61 70 28 0a  int tvfsShmMap(.
5b30: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
5b40: 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20  pFile,          
5b50: 20 20 2f 2a 20 48 61 6e 64 6c 65 20 6f 70 65 6e    /* Handle open
5b60: 20 6f 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c   on database fil
5b70: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 50 61 67 65  e */.  int iPage
5b80: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5b90: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 74         /* Page t
5ba0: 6f 20 72 65 74 72 69 65 76 65 20 2a 2f 0a 20 20  o retrieve */.  
5bb0: 69 6e 74 20 70 67 73 7a 2c 20 20 20 20 20 20 20  int pgsz,       
5bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5bd0: 2f 2a 20 53 69 7a 65 20 6f 66 20 70 61 67 65 73  /* Size of pages
5be0: 20 2a 2f 0a 20 20 69 6e 74 20 69 73 57 72 69 74   */.  int isWrit
5bf0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
5c00: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
5c10: 20 65 78 74 65 6e 64 20 66 69 6c 65 20 69 66 20   extend file if 
5c20: 6e 65 63 65 73 73 61 72 79 20 2a 2f 0a 20 20 76  necessary */.  v
5c30: 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 70  oid volatile **p
5c40: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  p              /
5c50: 2a 20 4f 55 54 3a 20 4d 61 70 70 65 64 20 6d 65  * OUT: Mapped me
5c60: 6d 6f 72 79 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  mory */.){.  int
5c70: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
5c80: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
5c90: 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  d = tvfsGetFd(pF
5ca0: 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20  ile);.  Testvfs 
5cb0: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
5cc0: 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70  (pFd->pVfs->pApp
5cd0: 44 61 74 61 29 3b 0a 0a 20 20 69 66 28 20 30 3d  Data);..  if( 0=
5ce0: 3d 70 46 64 2d 3e 70 53 68 6d 20 29 7b 0a 20 20  =pFd->pShm ){.  
5cf0: 20 20 72 63 20 3d 20 74 76 66 73 53 68 6d 4f 70    rc = tvfsShmOp
5d00: 65 6e 28 70 46 69 6c 65 29 3b 0a 20 20 20 20 69  en(pFile);.    i
5d10: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5d20: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
5d30: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   rc;.    }.  }..
5d40: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
5d50: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
5d60: 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20  VFS_SHMMAP_MASK 
5d70: 29 7b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a  ){.    Tcl_Obj *
5d80: 70 41 72 67 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  pArg = Tcl_NewOb
5d90: 6a 28 29 3b 0a 20 20 20 20 54 63 6c 5f 49 6e 63  j();.    Tcl_Inc
5da0: 72 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b  rRefCount(pArg);
5db0: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
5dc0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
5dd0: 3e 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54  >interp, pArg, T
5de0: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 50 61  cl_NewIntObj(iPa
5df0: 67 65 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69  ge));.    Tcl_Li
5e00: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
5e10: 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41  nt(p->interp, pA
5e20: 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62  rg, Tcl_NewIntOb
5e30: 6a 28 70 67 73 7a 29 29 3b 0a 20 20 20 20 54 63  j(pgsz));.    Tc
5e40: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
5e50: 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70  lement(p->interp
5e60: 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49  , pArg, Tcl_NewI
5e70: 6e 74 4f 62 6a 28 69 73 57 72 69 74 65 29 29 3b  ntObj(isWrite));
5e80: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
5e90: 28 70 2c 20 22 78 53 68 6d 4d 61 70 22 2c 20 0a  (p, "xShmMap", .
5ea0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
5eb0: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53  tringObj(pFd->pS
5ec0: 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20  hm->zFile, -1), 
5ed0: 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 70 41 72  pFd->pShmId, pAr
5ee0: 67 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66  g.    );.    tvf
5ef0: 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26  sResultCode(p, &
5f00: 72 63 29 3b 0a 20 20 20 20 54 63 6c 5f 44 65 63  rc);.    Tcl_Dec
5f10: 72 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b  rRefCount(pArg);
5f20: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
5f30: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d  QLITE_OK && p->m
5f40: 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d  ask&TESTVFS_SHMM
5f50: 41 50 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49  AP_MASK && tvfsI
5f60: 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b  njectIoerr(p) ){
5f70: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
5f80: 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69  _IOERR;.  }..  i
5f90: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
5fa0: 20 26 26 20 69 73 57 72 69 74 65 20 26 26 20 21   && isWrite && !
5fb0: 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65  pFd->pShm->aPage
5fc0: 5b 69 50 61 67 65 5d 20 29 7b 0a 20 20 20 20 74  [iPage] ){.    t
5fd0: 76 66 73 41 6c 6c 6f 63 50 61 67 65 28 70 46 64  vfsAllocPage(pFd
5fe0: 2d 3e 70 53 68 6d 2c 20 69 50 61 67 65 2c 20 70  ->pShm, iPage, p
5ff0: 67 73 7a 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20  gsz);.  }.  *pp 
6000: 3d 20 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65  = (void volatile
6010: 20 2a 29 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50   *)pFd->pShm->aP
6020: 61 67 65 5b 69 50 61 67 65 5d 3b 0a 0a 20 20 72  age[iPage];..  r
6030: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74  eturn rc;.}...st
6040: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
6050: 4c 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f  Lock(.  sqlite3_
6060: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69  file *pFile,.  i
6070: 6e 74 20 6f 66 73 74 2c 0a 20 20 69 6e 74 20 6e  nt ofst,.  int n
6080: 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 0a 29 7b  ,.  int flags.){
6090: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
60a0: 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73  TE_OK;.  Testvfs
60b0: 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65  Fd *pFd = tvfsGe
60c0: 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65  tFd(pFile);.  Te
60d0: 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74  stvfs *p = (Test
60e0: 76 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73  vfs *)(pFd->pVfs
60f0: 2d 3e 70 41 70 70 44 61 74 61 29 3b 0a 20 20 69  ->pAppData);.  i
6100: 6e 74 20 6e 4c 6f 63 6b 3b 0a 20 20 63 68 61 72  nt nLock;.  char
6110: 20 7a 4c 6f 63 6b 5b 38 30 5d 3b 0a 0a 20 20 69   zLock[80];..  i
6120: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
6130: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
6140: 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b  _SHMLOCK_MASK ){
6150: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70  .    sqlite3_snp
6160: 72 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4c 6f  rintf(sizeof(zLo
6170: 63 6b 29 2c 20 7a 4c 6f 63 6b 2c 20 22 25 64 20  ck), zLock, "%d 
6180: 25 64 22 2c 20 6f 66 73 74 2c 20 6e 29 3b 0a 20  %d", ofst, n);. 
6190: 20 20 20 6e 4c 6f 63 6b 20 3d 20 73 74 72 6c 65     nLock = strle
61a0: 6e 28 7a 4c 6f 63 6b 29 3b 0a 20 20 20 20 69 66  n(zLock);.    if
61b0: 28 20 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45  ( flags & SQLITE
61c0: 5f 53 48 4d 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  _SHM_LOCK ){.   
61d0: 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b     strcpy(&zLock
61e0: 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 6c 6f 63 6b 22  [nLock], " lock"
61f0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
6200: 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63      strcpy(&zLoc
6210: 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 75 6e 6c 6f  k[nLock], " unlo
6220: 63 6b 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  ck");.    }.    
6230: 6e 4c 6f 63 6b 20 2b 3d 20 73 74 72 6c 65 6e 28  nLock += strlen(
6240: 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 29 3b 0a  &zLock[nLock]);.
6250: 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 26 20      if( flags & 
6260: 53 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45  SQLITE_SHM_SHARE
6270: 44 20 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70  D ){.      strcp
6280: 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c  y(&zLock[nLock],
6290: 20 22 20 73 68 61 72 65 64 22 29 3b 0a 20 20 20   " shared");.   
62a0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 74   }else{.      st
62b0: 72 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63  rcpy(&zLock[nLoc
62c0: 6b 5d 2c 20 22 20 65 78 63 6c 75 73 69 76 65 22  k], " exclusive"
62d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 74 76 66  );.    }.    tvf
62e0: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68  sExecTcl(p, "xSh
62f0: 6d 4c 6f 63 6b 22 2c 20 0a 20 20 20 20 20 20 20  mLock", .       
6300: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
6310: 6a 28 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69  j(pFd->pShm->zFi
6320: 6c 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53  le, -1), pFd->pS
6330: 68 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63  hmId,.        Tc
6340: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a  l_NewStringObj(z
6350: 4c 6f 63 6b 2c 20 2d 31 29 0a 20 20 20 20 29 3b  Lock, -1).    );
6360: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
6370: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
6380: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
6390: 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b  TE_OK && p->mask
63a0: 26 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b  &TESTVFS_SHMLOCK
63b0: 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a  _MASK && tvfsInj
63c0: 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20  ectIoerr(p) ){. 
63d0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49     rc = SQLITE_I
63e0: 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  OERR;.  }..  if(
63f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
6400: 7b 0a 20 20 20 20 69 6e 74 20 69 73 4c 6f 63 6b  {.    int isLock
6410: 20 3d 20 28 66 6c 61 67 73 20 26 20 53 51 4c 49   = (flags & SQLI
6420: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 29 3b 0a 20 20  TE_SHM_LOCK);.  
6430: 20 20 69 6e 74 20 69 73 45 78 63 6c 20 3d 20 28    int isExcl = (
6440: 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  flags & SQLITE_S
6450: 48 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20  HM_EXCLUSIVE);. 
6460: 20 20 20 75 33 32 20 6d 61 73 6b 20 3d 20 28 28     u32 mask = ((
6470: 28 31 3c 3c 6e 29 2d 31 29 20 3c 3c 20 6f 66 73  (1<<n)-1) << ofs
6480: 74 29 3b 0a 20 20 20 20 69 66 28 20 69 73 4c 6f  t);.    if( isLo
6490: 63 6b 20 29 7b 0a 20 20 20 20 20 20 54 65 73 74  ck ){.      Test
64a0: 76 66 73 46 64 20 2a 70 32 3b 0a 20 20 20 20 20  vfsFd *p2;.     
64b0: 20 66 6f 72 28 70 32 3d 70 46 64 2d 3e 70 53 68   for(p2=pFd->pSh
64c0: 6d 2d 3e 70 46 69 6c 65 3b 20 70 32 3b 20 70 32  m->pFile; p2; p2
64d0: 3d 70 32 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  =p2->pNext){.   
64e0: 20 20 20 20 20 69 66 28 20 70 32 3d 3d 70 46 64       if( p2==pFd
64f0: 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
6500: 20 20 20 20 20 69 66 28 20 28 70 32 2d 3e 65 78       if( (p2->ex
6510: 63 6c 6c 6f 63 6b 26 6d 61 73 6b 29 20 7c 7c 20  cllock&mask) || 
6520: 28 69 73 45 78 63 6c 20 26 26 20 70 32 2d 3e 73  (isExcl && p2->s
6530: 68 61 72 65 64 6c 6f 63 6b 26 6d 61 73 6b 29 20  haredlock&mask) 
6540: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
6550: 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20  = SQLITE_BUSY;. 
6560: 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a           break;.
6570: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
6580: 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
6590: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
65a0: 20 20 20 20 20 69 66 28 20 69 73 45 78 63 6c 20       if( isExcl 
65b0: 29 20 20 70 46 64 2d 3e 65 78 63 6c 6c 6f 63 6b  )  pFd->excllock
65c0: 20 7c 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20   |= mask;.      
65d0: 20 20 69 66 28 20 21 69 73 45 78 63 6c 20 29 20    if( !isExcl ) 
65e0: 70 46 64 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 20  pFd->sharedlock 
65f0: 7c 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 7d  |= mask;.      }
6600: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6610: 20 20 69 66 28 20 69 73 45 78 63 6c 20 29 20 20    if( isExcl )  
6620: 70 46 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20 26 3d  pFd->excllock &=
6630: 20 28 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 20 20   (~mask);.      
6640: 69 66 28 20 21 69 73 45 78 63 6c 20 29 20 70 46  if( !isExcl ) pF
6650: 64 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 20 26 3d  d->sharedlock &=
6660: 20 28 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 7d 0a   (~mask);.    }.
6670: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
6680: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
6690: 20 74 76 66 73 53 68 6d 42 61 72 72 69 65 72 28   tvfsShmBarrier(
66a0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
66b0: 69 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46  ile){.  TestvfsF
66c0: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
66d0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
66e0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
66f0: 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d  fs *)(pFd->pVfs-
6700: 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69  >pAppData);..  i
6710: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
6720: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
6730: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
6740: 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63   ){.    tvfsExec
6750: 54 63 6c 28 70 2c 20 22 78 53 68 6d 42 61 72 72  Tcl(p, "xShmBarr
6760: 69 65 72 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ier", .        T
6770: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
6780: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
6790: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
67a0: 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d  Id, 0.    );.  }
67b0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
67c0: 76 66 73 53 68 6d 55 6e 6d 61 70 28 0a 20 20 73  vfsShmUnmap(.  s
67d0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
67e0: 6c 65 2c 0a 20 20 69 6e 74 20 64 65 6c 65 74 65  le,.  int delete
67f0: 46 6c 61 67 0a 29 7b 0a 20 20 69 6e 74 20 72 63  Flag.){.  int rc
6800: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
6810: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
6820: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
6830: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
6840: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46  = (Testvfs *)(pF
6850: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
6860: 61 29 3b 0a 20 20 54 65 73 74 76 66 73 42 75 66  a);.  TestvfsBuf
6870: 66 65 72 20 2a 70 42 75 66 66 65 72 20 3d 20 70  fer *pBuffer = p
6880: 46 64 2d 3e 70 53 68 6d 3b 0a 20 20 54 65 73 74  Fd->pShm;.  Test
6890: 76 66 73 46 64 20 2a 2a 70 70 46 64 3b 0a 0a 20  vfsFd **ppFd;.. 
68a0: 20 69 66 28 20 21 70 42 75 66 66 65 72 20 29 20   if( !pBuffer ) 
68b0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
68c0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 46 64 2d  ;.  assert( pFd-
68d0: 3e 70 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e  >pShmId && pFd->
68e0: 70 53 68 6d 20 29 3b 0a 0a 20 20 69 66 28 20 70  pShm );..  if( p
68f0: 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e  ->pScript && p->
6900: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d  mask&TESTVFS_SHM
6910: 43 4c 4f 53 45 5f 4d 41 53 4b 20 29 7b 0a 20 20  CLOSE_MASK ){.  
6920: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
6930: 20 22 78 53 68 6d 55 6e 6d 61 70 22 2c 20 0a 20   "xShmUnmap", . 
6940: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
6950: 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68  ringObj(pFd->pSh
6960: 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70  m->zFile, -1), p
6970: 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20  Fd->pShmId, 0.  
6980: 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73    );.    tvfsRes
6990: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b  ultCode(p, &rc);
69a0: 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70 70 46 64  .  }..  for(ppFd
69b0: 3d 26 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65  =&pBuffer->pFile
69c0: 3b 20 2a 70 70 46 64 21 3d 70 46 64 3b 20 70 70  ; *ppFd!=pFd; pp
69d0: 46 64 3d 26 28 28 2a 70 70 46 64 29 2d 3e 70 4e  Fd=&((*ppFd)->pN
69e0: 65 78 74 29 29 3b 0a 20 20 61 73 73 65 72 74 28  ext));.  assert(
69f0: 20 28 2a 70 70 46 64 29 3d 3d 70 46 64 20 29 3b   (*ppFd)==pFd );
6a00: 0a 20 20 2a 70 70 46 64 20 3d 20 70 46 64 2d 3e  .  *ppFd = pFd->
6a10: 70 4e 65 78 74 3b 0a 20 20 70 46 64 2d 3e 70 4e  pNext;.  pFd->pN
6a20: 65 78 74 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20  ext = 0;..  if( 
6a30: 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65 3d 3d  pBuffer->pFile==
6a40: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  0 ){.    int i;.
6a50: 20 20 20 20 54 65 73 74 76 66 73 42 75 66 66 65      TestvfsBuffe
6a60: 72 20 2a 2a 70 70 3b 0a 20 20 20 20 66 6f 72 28  r **pp;.    for(
6a70: 70 70 3d 26 70 2d 3e 70 42 75 66 66 65 72 3b 20  pp=&p->pBuffer; 
6a80: 2a 70 70 21 3d 70 42 75 66 66 65 72 3b 20 70 70  *pp!=pBuffer; pp
6a90: 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  =&((*pp)->pNext)
6aa0: 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20 28 2a 70  );.    *pp = (*p
6ab0: 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 66  p)->pNext;.    f
6ac0: 6f 72 28 69 3d 30 3b 20 70 42 75 66 66 65 72 2d  or(i=0; pBuffer-
6ad0: 3e 61 50 61 67 65 5b 69 5d 3b 20 69 2b 2b 29 7b  >aPage[i]; i++){
6ae0: 0a 20 20 20 20 20 20 63 6b 66 72 65 65 28 28 63  .      ckfree((c
6af0: 68 61 72 20 2a 29 70 42 75 66 66 65 72 2d 3e 61  har *)pBuffer->a
6b00: 50 61 67 65 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a  Page[i]);.    }.
6b10: 20 20 20 20 63 6b 66 72 65 65 28 28 63 68 61 72      ckfree((char
6b20: 20 2a 29 70 42 75 66 66 65 72 29 3b 0a 20 20 7d   *)pBuffer);.  }
6b30: 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30  .  pFd->pShm = 0
6b40: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ;..  return rc;.
6b50: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65  }..static int te
6b60: 73 74 76 66 73 5f 6f 62 6a 5f 63 6d 64 28 0a 20  stvfs_obj_cmd(. 
6b70: 20 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a   ClientData cd,.
6b80: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
6b90: 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63  terp,.  int objc
6ba0: 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  ,.  Tcl_Obj *CON
6bb0: 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 54  ST objv[].){.  T
6bc0: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
6bd0: 74 76 66 73 20 2a 29 63 64 3b 0a 0a 20 20 65 6e  tvfs *)cd;..  en
6be0: 75 6d 20 44 42 5f 65 6e 75 6d 20 7b 20 0a 20 20  um DB_enum { .  
6bf0: 20 20 43 4d 44 5f 53 48 4d 2c 20 43 4d 44 5f 44    CMD_SHM, CMD_D
6c00: 45 4c 45 54 45 2c 20 43 4d 44 5f 46 49 4c 54 45  ELETE, CMD_FILTE
6c10: 52 2c 20 43 4d 44 5f 49 4f 45 52 52 2c 20 43 4d  R, CMD_IOERR, CM
6c20: 44 5f 53 43 52 49 50 54 2c 20 0a 20 20 20 20 43  D_SCRIPT, .    C
6c30: 4d 44 5f 44 45 56 43 48 41 52 2c 20 43 4d 44 5f  MD_DEVCHAR, CMD_
6c40: 53 45 43 54 4f 52 53 49 5a 45 2c 20 43 4d 44 5f  SECTORSIZE, CMD_
6c50: 46 55 4c 4c 45 52 52 2c 20 43 4d 44 5f 43 41 4e  FULLERR, CMD_CAN
6c60: 54 4f 50 45 4e 45 52 52 0a 20 20 7d 3b 0a 20 20  TOPENERR.  };.  
6c70: 73 74 72 75 63 74 20 54 65 73 74 76 66 73 53 75  struct TestvfsSu
6c80: 62 63 6d 64 20 7b 0a 20 20 20 20 63 68 61 72 20  bcmd {.    char 
6c90: 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 65 6e 75 6d  *zName;.    enum
6ca0: 20 44 42 5f 65 6e 75 6d 20 65 43 6d 64 3b 0a 20   DB_enum eCmd;. 
6cb0: 20 7d 20 61 53 75 62 63 6d 64 5b 5d 20 3d 20 7b   } aSubcmd[] = {
6cc0: 0a 20 20 20 20 7b 20 22 73 68 6d 22 2c 20 20 20  .    { "shm",   
6cd0: 20 20 20 20 20 20 43 4d 44 5f 53 48 4d 20 20 20        CMD_SHM   
6ce0: 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22        },.    { "
6cf0: 64 65 6c 65 74 65 22 2c 20 20 20 20 20 20 43 4d  delete",      CM
6d00: 44 5f 44 45 4c 45 54 45 20 20 20 20 20 20 7d 2c  D_DELETE      },
6d10: 0a 20 20 20 20 7b 20 22 66 69 6c 74 65 72 22 2c  .    { "filter",
6d20: 20 20 20 20 20 20 43 4d 44 5f 46 49 4c 54 45 52        CMD_FILTER
6d30: 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22        },.    { "
6d40: 69 6f 65 72 72 22 2c 20 20 20 20 20 20 20 43 4d  ioerr",       CM
6d50: 44 5f 49 4f 45 52 52 20 20 20 20 20 20 20 7d 2c  D_IOERR       },
6d60: 0a 20 20 20 20 7b 20 22 66 75 6c 6c 65 72 72 22  .    { "fullerr"
6d70: 2c 20 20 20 20 20 43 4d 44 5f 46 55 4c 4c 45 52  ,     CMD_FULLER
6d80: 52 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22  R     },.    { "
6d90: 63 61 6e 74 6f 70 65 6e 65 72 72 22 2c 20 43 4d  cantopenerr", CM
6da0: 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 20 7d 2c  D_CANTOPENERR },
6db0: 0a 20 20 20 20 7b 20 22 73 63 72 69 70 74 22 2c  .    { "script",
6dc0: 20 20 20 20 20 20 43 4d 44 5f 53 43 52 49 50 54        CMD_SCRIPT
6dd0: 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22        },.    { "
6de0: 64 65 76 63 68 61 72 22 2c 20 20 20 20 20 43 4d  devchar",     CM
6df0: 44 5f 44 45 56 43 48 41 52 20 20 20 20 20 7d 2c  D_DEVCHAR     },
6e00: 0a 20 20 20 20 7b 20 22 73 65 63 74 6f 72 73 69  .    { "sectorsi
6e10: 7a 65 22 2c 20 20 43 4d 44 5f 53 45 43 54 4f 52  ze",  CMD_SECTOR
6e20: 53 49 5a 45 20 20 7d 2c 0a 20 20 20 20 7b 20 30  SIZE  },.    { 0
6e30: 2c 20 30 20 7d 0a 20 20 7d 3b 0a 20 20 69 6e 74  , 0 }.  };.  int
6e40: 20 69 3b 0a 20 20 0a 20 20 69 66 28 20 6f 62 6a   i;.  .  if( obj
6e50: 63 3c 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  c<2 ){.    Tcl_W
6e60: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
6e70: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 53 55  rp, 1, objv, "SU
6e80: 42 43 4f 4d 4d 41 4e 44 20 2e 2e 2e 22 29 3b 0a  BCOMMAND ...");.
6e90: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
6ea0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  RROR;.  }.  if( 
6eb0: 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d  Tcl_GetIndexFrom
6ec0: 4f 62 6a 53 74 72 75 63 74 28 0a 20 20 20 20 20  ObjStruct(.     
6ed0: 20 20 20 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b     interp, objv[
6ee0: 31 5d 2c 20 61 53 75 62 63 6d 64 2c 20 73 69 7a  1], aSubcmd, siz
6ef0: 65 6f 66 28 61 53 75 62 63 6d 64 5b 30 5d 29 2c  eof(aSubcmd[0]),
6f00: 20 22 73 75 62 63 6f 6d 6d 61 6e 64 22 2c 20 30   "subcommand", 0
6f10: 2c 20 26 69 29 20 0a 20 20 29 7b 0a 20 20 20 20  , &i) .  ){.    
6f20: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6f30: 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65  ;.  }.  Tcl_Rese
6f40: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  tResult(interp);
6f50: 0a 0a 20 20 73 77 69 74 63 68 28 20 61 53 75 62  ..  switch( aSub
6f60: 63 6d 64 5b 69 5d 2e 65 43 6d 64 20 29 7b 0a 20  cmd[i].eCmd ){. 
6f70: 20 20 20 63 61 73 65 20 43 4d 44 5f 53 48 4d 3a     case CMD_SHM:
6f80: 20 7b 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a   {.      Tcl_Obj
6f90: 20 2a 70 4f 62 6a 3b 0a 20 20 20 20 20 20 69 6e   *pObj;.      in
6fa0: 74 20 69 2c 20 72 63 3b 0a 20 20 20 20 20 20 54  t i, rc;.      T
6fb0: 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 42  estvfsBuffer *pB
6fc0: 75 66 66 65 72 3b 0a 20 20 20 20 20 20 63 68 61  uffer;.      cha
6fd0: 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20  r *zName;.      
6fe0: 69 66 28 20 6f 62 6a 63 21 3d 33 20 26 26 20 6f  if( objc!=3 && o
6ff0: 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20 20 20 20  bjc!=4 ){.      
7000: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
7010: 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62  gs(interp, 2, ob
7020: 6a 76 2c 20 22 46 49 4c 45 20 3f 56 41 4c 55 45  jv, "FILE ?VALUE
7030: 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  ?");.        ret
7040: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7050: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e 61       }.      zNa
7060: 6d 65 20 3d 20 63 6b 61 6c 6c 6f 63 28 70 2d 3e  me = ckalloc(p->
7070: 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68 6e  pParent->mxPathn
7080: 61 6d 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  ame);.      rc =
7090: 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46 75   p->pParent->xFu
70a0: 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 20 20  llPathname(.    
70b0: 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74        p->pParent
70c0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
70d0: 6f 62 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20 20  objv[2]), .     
70e0: 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74 2d       p->pParent-
70f0: 3e 6d 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e 61  >mxPathname, zNa
7100: 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  me.      );.    
7110: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
7120: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 54  _OK ){.        T
7130: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
7140: 69 6e 74 65 72 70 2c 20 22 66 61 69 6c 65 64 20  interp, "failed 
7150: 74 6f 20 67 65 74 20 66 75 6c 6c 20 70 61 74 68  to get full path
7160: 3a 20 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  : ",.           
7170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
7180: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
7190: 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 20 20  [2]), 0);.      
71a0: 20 20 63 6b 66 72 65 65 28 7a 4e 61 6d 65 29 3b    ckfree(zName);
71b0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
71c0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
71d0: 20 7d 0a 20 20 20 20 20 20 66 6f 72 28 70 42 75   }.      for(pBu
71e0: 66 66 65 72 3d 70 2d 3e 70 42 75 66 66 65 72 3b  ffer=p->pBuffer;
71f0: 20 70 42 75 66 66 65 72 3b 20 70 42 75 66 66 65   pBuffer; pBuffe
7200: 72 3d 70 42 75 66 66 65 72 2d 3e 70 4e 65 78 74  r=pBuffer->pNext
7210: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 30  ){.        if( 0
7220: 3d 3d 73 74 72 63 6d 70 28 70 42 75 66 66 65 72  ==strcmp(pBuffer
7230: 2d 3e 7a 46 69 6c 65 2c 20 7a 4e 61 6d 65 29 20  ->zFile, zName) 
7240: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d  ) break;.      }
7250: 0a 20 20 20 20 20 20 63 6b 66 72 65 65 28 7a 4e  .      ckfree(zN
7260: 61 6d 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ame);.      if( 
7270: 21 70 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  !pBuffer ){.    
7280: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
7290: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f  sult(interp, "no
72a0: 20 73 75 63 68 20 66 69 6c 65 3a 20 22 2c 20 54   such file: ", T
72b0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
72c0: 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 20  v[2]), 0);.     
72d0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
72e0: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
72f0: 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20 29     if( objc==4 )
7300: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b  {.        int n;
7310: 0a 20 20 20 20 20 20 20 20 75 38 20 2a 61 20 3d  .        u8 *a =
7320: 20 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72 61   Tcl_GetByteArra
7330: 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 33 5d  yFromObj(objv[3]
7340: 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20 20 20 69  , &n);.        i
7350: 6e 74 20 70 67 73 7a 20 3d 20 70 42 75 66 66 65  nt pgsz = pBuffe
7360: 72 2d 3e 70 67 73 7a 3b 0a 20 20 20 20 20 20 20  r->pgsz;.       
7370: 20 69 66 28 20 70 67 73 7a 3d 3d 30 20 29 20 70   if( pgsz==0 ) p
7380: 67 73 7a 20 3d 20 36 35 35 33 36 3b 0a 20 20 20  gsz = 65536;.   
7390: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 2a       for(i=0; i*
73a0: 70 67 73 7a 3c 6e 3b 20 69 2b 2b 29 7b 0a 20 20  pgsz<n; i++){.  
73b0: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74          int nByt
73c0: 65 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20 20  e = pgsz;.      
73d0: 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50 61 67      tvfsAllocPag
73e0: 65 28 70 42 75 66 66 65 72 2c 20 69 2c 20 70 67  e(pBuffer, i, pg
73f0: 73 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  sz);.          i
7400: 66 28 20 6e 2d 69 2a 70 67 73 7a 3c 70 67 73 7a  f( n-i*pgsz<pgsz
7410: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
7420: 6e 42 79 74 65 20 3d 20 6e 3b 0a 20 20 20 20 20  nByte = n;.     
7430: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
7440: 20 6d 65 6d 63 70 79 28 70 42 75 66 66 65 72 2d   memcpy(pBuffer-
7450: 3e 61 50 61 67 65 5b 69 5d 2c 20 26 61 5b 69 2a  >aPage[i], &a[i*
7460: 70 67 73 7a 5d 2c 20 6e 42 79 74 65 29 3b 0a 20  pgsz], nByte);. 
7470: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
7480: 0a 0a 20 20 20 20 20 20 70 4f 62 6a 20 3d 20 54  ..      pObj = T
7490: 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20  cl_NewObj();.   
74a0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 70 42 75 66     for(i=0; pBuf
74b0: 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 3b 20 69  fer->aPage[i]; i
74c0: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  ++){.        int
74d0: 20 70 67 73 7a 20 3d 20 70 42 75 66 66 65 72 2d   pgsz = pBuffer-
74e0: 3e 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20 69  >pgsz;.        i
74f0: 66 28 20 70 67 73 7a 3d 3d 30 20 29 20 70 67 73  f( pgsz==0 ) pgs
7500: 7a 20 3d 20 36 35 35 33 36 3b 0a 20 20 20 20 20  z = 65536;.     
7510: 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 4f 62 6a     Tcl_AppendObj
7520: 54 6f 4f 62 6a 28 70 4f 62 6a 2c 20 54 63 6c 5f  ToObj(pObj, Tcl_
7530: 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a 28  NewByteArrayObj(
7540: 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69  pBuffer->aPage[i
7550: 5d 2c 20 70 67 73 7a 29 29 3b 0a 20 20 20 20 20  ], pgsz));.     
7560: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74   }.      Tcl_Set
7570: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
7580: 2c 20 70 4f 62 6a 29 3b 0a 20 20 20 20 20 20 62  , pObj);.      b
7590: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
75a0: 20 63 61 73 65 20 43 4d 44 5f 46 49 4c 54 45 52   case CMD_FILTER
75b0: 3a 20 7b 0a 20 20 20 20 20 20 73 74 61 74 69 63  : {.      static
75c0: 20 73 74 72 75 63 74 20 56 66 73 4d 65 74 68 6f   struct VfsMetho
75d0: 64 20 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72  d {.        char
75e0: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20   *zName;.       
75f0: 20 69 6e 74 20 6d 61 73 6b 3b 0a 20 20 20 20 20   int mask;.     
7600: 20 7d 20 76 66 73 6d 65 74 68 6f 64 20 5b 5d 20   } vfsmethod [] 
7610: 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 78  = {.        { "x
7620: 53 68 6d 4f 70 65 6e 22 2c 20 20 20 20 20 20 54  ShmOpen",      T
7630: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
7640: 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  ASK },.        {
7650: 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 20 20 20   "xShmLock",    
7660: 20 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43    TESTVFS_SHMLOC
7670: 4b 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20  K_MASK },.      
7680: 20 20 7b 20 22 78 53 68 6d 42 61 72 72 69 65 72    { "xShmBarrier
7690: 22 2c 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d  ",   TESTVFS_SHM
76a0: 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a  BARRIER_MASK },.
76b0: 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 55          { "xShmU
76c0: 6e 6d 61 70 22 2c 20 20 20 20 20 54 45 53 54 56  nmap",     TESTV
76d0: 46 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b  FS_SHMCLOSE_MASK
76e0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
76f0: 53 68 6d 4d 61 70 22 2c 20 20 20 20 20 20 20 54  ShmMap",       T
7700: 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41  ESTVFS_SHMMAP_MA
7710: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
7720: 22 78 53 79 6e 63 22 2c 20 20 20 20 20 20 20 20  "xSync",        
7730: 20 54 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41   TESTVFS_SYNC_MA
7740: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
7750: 22 78 44 65 6c 65 74 65 22 2c 20 20 20 20 20 20  "xDelete",      
7760: 20 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45 5f   TESTVFS_DELETE_
7770: 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20  MASK },.        
7780: 7b 20 22 78 57 72 69 74 65 22 2c 20 20 20 20 20  { "xWrite",     
7790: 20 20 20 54 45 53 54 56 46 53 5f 57 52 49 54 45     TESTVFS_WRITE
77a0: 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20  _MASK },.       
77b0: 20 7b 20 22 78 52 65 61 64 22 2c 20 20 20 20 20   { "xRead",     
77c0: 20 20 20 20 54 45 53 54 56 46 53 5f 52 45 41 44      TESTVFS_READ
77d0: 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20  _MASK },.       
77e0: 20 7b 20 22 78 54 72 75 6e 63 61 74 65 22 2c 20   { "xTruncate", 
77f0: 20 20 20 20 54 45 53 54 56 46 53 5f 54 52 55 4e      TESTVFS_TRUN
7800: 43 41 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  CATE_MASK },.   
7810: 20 20 20 20 20 7b 20 22 78 4f 70 65 6e 22 2c 20       { "xOpen", 
7820: 20 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f          TESTVFS_
7830: 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  OPEN_MASK },.   
7840: 20 20 20 20 20 7b 20 22 78 43 6c 6f 73 65 22 2c       { "xClose",
7850: 20 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f          TESTVFS_
7860: 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20  CLOSE_MASK },.  
7870: 20 20 20 20 20 20 7b 20 22 78 41 63 63 65 73 73        { "xAccess
7880: 22 2c 20 20 20 20 20 20 20 54 45 53 54 56 46 53  ",       TESTVFS
7890: 5f 41 43 43 45 53 53 5f 4d 41 53 4b 20 7d 2c 0a  _ACCESS_MASK },.
78a0: 20 20 20 20 20 20 20 20 7b 20 22 78 46 75 6c 6c          { "xFull
78b0: 50 61 74 68 6e 61 6d 65 22 2c 20 54 45 53 54 56  Pathname", TESTV
78c0: 46 53 5f 46 55 4c 4c 50 41 54 48 4e 41 4d 45 5f  FS_FULLPATHNAME_
78d0: 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 7d 3b  MASK },.      };
78e0: 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a  .      Tcl_Obj *
78f0: 2a 61 70 45 6c 65 6d 20 3d 20 30 3b 0a 20 20 20  *apElem = 0;.   
7900: 20 20 20 69 6e 74 20 6e 45 6c 65 6d 20 3d 20 30     int nElem = 0
7910: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  ;.      int i;. 
7920: 20 20 20 20 20 69 6e 74 20 6d 61 73 6b 20 3d 20       int mask = 
7930: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a  0;.      if( obj
7940: 63 21 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20  c!=3 ){.        
7950: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
7960: 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76  (interp, 2, objv
7970: 2c 20 22 4c 49 53 54 22 29 3b 0a 20 20 20 20 20  , "LIST");.     
7980: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
7990: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
79a0: 20 20 20 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f     if( Tcl_ListO
79b0: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e  bjGetElements(in
79c0: 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26  terp, objv[2], &
79d0: 6e 45 6c 65 6d 2c 20 26 61 70 45 6c 65 6d 29 20  nElem, &apElem) 
79e0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
79f0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
7a00: 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 52     }.      Tcl_R
7a10: 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  esetResult(inter
7a20: 70 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  p);.      for(i=
7a30: 30 3b 20 69 3c 6e 45 6c 65 6d 3b 20 69 2b 2b 29  0; i<nElem; i++)
7a40: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 4d  {.        int iM
7a50: 65 74 68 6f 64 3b 0a 20 20 20 20 20 20 20 20 63  ethod;.        c
7a60: 68 61 72 20 2a 7a 45 6c 65 6d 20 3d 20 54 63 6c  har *zElem = Tcl
7a70: 5f 47 65 74 53 74 72 69 6e 67 28 61 70 45 6c 65  _GetString(apEle
7a80: 6d 5b 69 5d 29 3b 0a 20 20 20 20 20 20 20 20 66  m[i]);.        f
7a90: 6f 72 28 69 4d 65 74 68 6f 64 3d 30 3b 20 69 4d  or(iMethod=0; iM
7aa0: 65 74 68 6f 64 3c 41 72 72 61 79 53 69 7a 65 28  ethod<ArraySize(
7ab0: 76 66 73 6d 65 74 68 6f 64 29 3b 20 69 4d 65 74  vfsmethod); iMet
7ac0: 68 6f 64 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  hod++){.        
7ad0: 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 45 6c    if( strcmp(zEl
7ae0: 65 6d 2c 20 76 66 73 6d 65 74 68 6f 64 5b 69 4d  em, vfsmethod[iM
7af0: 65 74 68 6f 64 5d 2e 7a 4e 61 6d 65 29 3d 3d 30  ethod].zName)==0
7b00: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
7b10: 6d 61 73 6b 20 7c 3d 20 76 66 73 6d 65 74 68 6f  mask |= vfsmetho
7b20: 64 5b 69 4d 65 74 68 6f 64 5d 2e 6d 61 73 6b 3b  d[iMethod].mask;
7b30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65  .            bre
7b40: 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ak;.          }.
7b50: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7b60: 20 20 69 66 28 20 69 4d 65 74 68 6f 64 3d 3d 41    if( iMethod==A
7b70: 72 72 61 79 53 69 7a 65 28 76 66 73 6d 65 74 68  rraySize(vfsmeth
7b80: 6f 64 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  od) ){.         
7b90: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
7ba0: 74 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f  t(interp, "unkno
7bb0: 77 6e 20 6d 65 74 68 6f 64 3a 20 22 2c 20 7a 45  wn method: ", zE
7bc0: 6c 65 6d 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  lem, 0);.       
7bd0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
7be0: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ROR;.        }. 
7bf0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 2d 3e       }.      p->
7c00: 6d 61 73 6b 20 3d 20 6d 61 73 6b 3b 0a 20 20 20  mask = mask;.   
7c10: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
7c20: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 53 43  .    case CMD_SC
7c30: 52 49 50 54 3a 20 7b 0a 20 20 20 20 20 20 69 66  RIPT: {.      if
7c40: 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20  ( objc==3 ){.   
7c50: 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a       int nByte;.
7c60: 20 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e 70          if( p->p
7c70: 53 63 72 69 70 74 20 29 7b 0a 20 20 20 20 20 20  Script ){.      
7c80: 20 20 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43      Tcl_DecrRefC
7c90: 6f 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29  ount(p->pScript)
7ca0: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70  ;.          p->p
7cb0: 53 63 72 69 70 74 20 3d 20 30 3b 0a 20 20 20 20  Script = 0;.    
7cc0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 54 63      }.        Tc
7cd0: 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f  l_GetStringFromO
7ce0: 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26 6e 42 79  bj(objv[2], &nBy
7cf0: 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  te);.        if(
7d00: 20 6e 42 79 74 65 3e 30 20 29 7b 0a 20 20 20 20   nByte>0 ){.    
7d10: 20 20 20 20 20 20 70 2d 3e 70 53 63 72 69 70 74        p->pScript
7d20: 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65   = Tcl_Duplicate
7d30: 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29 3b 0a 20 20  Obj(objv[2]);.  
7d40: 20 20 20 20 20 20 20 20 54 63 6c 5f 49 6e 63 72          Tcl_Incr
7d50: 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72  RefCount(p->pScr
7d60: 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ipt);.        }.
7d70: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
7d80: 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 20  objc!=2 ){.     
7d90: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
7da0: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
7db0: 62 6a 76 2c 20 22 3f 53 43 52 49 50 54 3f 22 29  bjv, "?SCRIPT?")
7dc0: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7dd0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
7de0: 20 20 7d 0a 0a 20 20 20 20 20 20 54 63 6c 5f 52    }..      Tcl_R
7df0: 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  esetResult(inter
7e00: 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 2d  p);.      if( p-
7e10: 3e 70 53 63 72 69 70 74 20 29 20 54 63 6c 5f 53  >pScript ) Tcl_S
7e20: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
7e30: 72 70 2c 20 70 2d 3e 70 53 63 72 69 70 74 29 3b  rp, p->pScript);
7e40: 0a 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ..      break;. 
7e50: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 0a 20 20 20     }..    /*.   
7e60: 20 2a 2a 20 54 45 53 54 56 46 53 20 69 6f 65 72   ** TESTVFS ioer
7e70: 72 20 3f 49 46 41 49 4c 20 50 45 52 53 49 53 54  r ?IFAIL PERSIST
7e80: 3f 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20  ?.    **.    ** 
7e90: 20 20 57 68 65 72 65 20 49 46 41 49 4c 20 69 73    Where IFAIL is
7ea0: 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20   an integer and 
7eb0: 50 45 52 53 49 53 54 20 69 73 20 62 6f 6f 6c 65  PERSIST is boole
7ec0: 61 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 63  an..    */.    c
7ed0: 61 73 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e  ase CMD_CANTOPEN
7ee0: 45 52 52 3a 0a 20 20 20 20 63 61 73 65 20 43 4d  ERR:.    case CM
7ef0: 44 5f 49 4f 45 52 52 3a 0a 20 20 20 20 63 61 73  D_IOERR:.    cas
7f00: 65 20 43 4d 44 5f 46 55 4c 4c 45 52 52 3a 20 7b  e CMD_FULLERR: {
7f10: 0a 20 20 20 20 20 20 54 65 73 74 46 61 75 6c 74  .      TestFault
7f20: 49 6e 6a 65 63 74 20 2a 70 54 65 73 74 3b 0a 20  Inject *pTest;. 
7f30: 20 20 20 20 20 69 6e 74 20 69 52 65 74 3b 0a 0a       int iRet;..
7f40: 20 20 20 20 20 20 73 77 69 74 63 68 28 20 61 53        switch( aS
7f50: 75 62 63 6d 64 5b 69 5d 2e 65 43 6d 64 20 29 7b  ubcmd[i].eCmd ){
7f60: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 43 4d  .        case CM
7f70: 44 5f 49 4f 45 52 52 3a 20 70 54 65 73 74 20 3d  D_IOERR: pTest =
7f80: 20 26 70 2d 3e 69 6f 65 72 72 5f 65 72 72 3b 20   &p->ioerr_err; 
7f90: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63  break;.        c
7fa0: 61 73 65 20 43 4d 44 5f 46 55 4c 4c 45 52 52 3a  ase CMD_FULLERR:
7fb0: 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 66 75 6c   pTest = &p->ful
7fc0: 6c 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20 20  l_err; break;.  
7fd0: 20 20 20 20 20 20 63 61 73 65 20 43 4d 44 5f 43        case CMD_C
7fe0: 41 4e 54 4f 50 45 4e 45 52 52 3a 20 70 54 65 73  ANTOPENERR: pTes
7ff0: 74 20 3d 20 26 70 2d 3e 63 61 6e 74 6f 70 65 6e  t = &p->cantopen
8000: 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20 20 20  _err; break;.   
8010: 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20 61 73       default: as
8020: 73 65 72 74 28 30 29 3b 0a 20 20 20 20 20 20 7d  sert(0);.      }
8030: 0a 20 20 20 20 20 20 69 52 65 74 20 3d 20 70 54  .      iRet = pT
8040: 65 73 74 2d 3e 6e 46 61 69 6c 3b 0a 20 20 20 20  est->nFail;.    
8050: 20 20 70 54 65 73 74 2d 3e 6e 46 61 69 6c 20 3d    pTest->nFail =
8060: 20 30 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d   0;.      pTest-
8070: 3e 65 46 61 75 6c 74 20 3d 20 30 3b 0a 20 20 20  >eFault = 0;.   
8080: 20 20 20 70 54 65 73 74 2d 3e 69 43 6e 74 20 3d     pTest->iCnt =
8090: 20 30 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 6f   0;..      if( o
80a0: 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20  bjc==4 ){.      
80b0: 20 20 69 6e 74 20 69 43 6e 74 2c 20 69 50 65 72    int iCnt, iPer
80c0: 73 69 73 74 3b 0a 20 20 20 20 20 20 20 20 69 66  sist;.        if
80d0: 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47 65  ( TCL_OK!=Tcl_Ge
80e0: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
80f0: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 43  rp, objv[2], &iC
8100: 6e 74 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20  nt).         || 
8110: 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47 65 74 42  TCL_OK!=Tcl_GetB
8120: 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e  ooleanFromObj(in
8130: 74 65 72 70 2c 20 6f 62 6a 76 5b 33 5d 2c 20 26  terp, objv[3], &
8140: 69 50 65 72 73 69 73 74 29 0a 20 20 20 20 20 20  iPersist).      
8150: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72    ){.          r
8160: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
8170: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
8180: 20 20 20 70 54 65 73 74 2d 3e 65 46 61 75 6c 74     pTest->eFault
8190: 20 3d 20 69 50 65 72 73 69 73 74 3f 46 41 55 4c   = iPersist?FAUL
81a0: 54 5f 49 4e 4a 45 43 54 5f 50 45 52 53 49 53 54  T_INJECT_PERSIST
81b0: 45 4e 54 3a 46 41 55 4c 54 5f 49 4e 4a 45 43 54  ENT:FAULT_INJECT
81c0: 5f 54 52 41 4e 53 49 45 4e 54 3b 0a 20 20 20 20  _TRANSIENT;.    
81d0: 20 20 20 20 70 54 65 73 74 2d 3e 69 43 6e 74 20      pTest->iCnt 
81e0: 3d 20 69 43 6e 74 3b 0a 20 20 20 20 20 20 7d 65  = iCnt;.      }e
81f0: 6c 73 65 20 69 66 28 20 6f 62 6a 63 21 3d 32 20  lse if( objc!=2 
8200: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57  ){.        Tcl_W
8210: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
8220: 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 43  rp, 2, objv, "?C
8230: 4e 54 20 50 45 52 53 49 53 54 3f 22 29 3b 0a 20  NT PERSIST?");. 
8240: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
8250: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
8260: 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62  .      Tcl_SetOb
8270: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
8280: 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 52  Tcl_NewIntObj(iR
8290: 65 74 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  et));.      brea
82a0: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61  k;.    }..    ca
82b0: 73 65 20 43 4d 44 5f 44 45 4c 45 54 45 3a 20 7b  se CMD_DELETE: {
82c0: 0a 20 20 20 20 20 20 54 63 6c 5f 44 65 6c 65 74  .      Tcl_Delet
82d0: 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  eCommand(interp,
82e0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
82f0: 62 6a 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20  bjv[0]));.      
8300: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
8310: 20 20 63 61 73 65 20 43 4d 44 5f 44 45 56 43 48    case CMD_DEVCH
8320: 41 52 3a 20 7b 0a 20 20 20 20 20 20 73 74 72 75  AR: {.      stru
8330: 63 74 20 44 65 76 69 63 65 46 6c 61 67 20 7b 0a  ct DeviceFlag {.
8340: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e          char *zN
8350: 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  ame;.        int
8360: 20 69 56 61 6c 75 65 3b 0a 20 20 20 20 20 20 7d   iValue;.      }
8370: 20 61 46 6c 61 67 5b 5d 20 3d 20 7b 0a 20 20 20   aFlag[] = {.   
8380: 20 20 20 20 20 7b 20 22 64 65 66 61 75 6c 74 22       { "default"
8390: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
83a0: 2d 31 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  -1 },.        { 
83b0: 22 61 74 6f 6d 69 63 22 2c 20 20 20 20 20 20 20  "atomic",       
83c0: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
83d0: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 20 20 20 20  IOCAP_ATOMIC    
83e0: 20 20 20 20 20 20 20 20 20 20 20 20 7d 2c 0a 20              },. 
83f0: 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63         { "atomic
8400: 35 31 32 22 2c 20 20 20 20 20 20 20 20 20 20 20  512",           
8410: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41    SQLITE_IOCAP_A
8420: 54 4f 4d 49 43 35 31 32 20 20 20 20 20 20 20 20  TOMIC512        
8430: 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20       },.        
8440: 7b 20 22 61 74 6f 6d 69 63 31 6b 22 2c 20 20 20  { "atomic1k",   
8450: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
8460: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 31 4b  E_IOCAP_ATOMIC1K
8470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 2c                },
8480: 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d  .        { "atom
8490: 69 63 32 6b 22 2c 20 20 20 20 20 20 20 20 20 20  ic2k",          
84a0: 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50      SQLITE_IOCAP
84b0: 5f 41 54 4f 4d 49 43 32 4b 20 20 20 20 20 20 20  _ATOMIC2K       
84c0: 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20         },.      
84d0: 20 20 7b 20 22 61 74 6f 6d 69 63 34 6b 22 2c 20    { "atomic4k", 
84e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
84f0: 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43  ITE_IOCAP_ATOMIC
8500: 34 4b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  4K              
8510: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74  },.        { "at
8520: 6f 6d 69 63 38 6b 22 2c 20 20 20 20 20 20 20 20  omic8k",        
8530: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
8540: 41 50 5f 41 54 4f 4d 49 43 38 4b 20 20 20 20 20  AP_ATOMIC8K     
8550: 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20           },.    
8560: 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 31 36 6b      { "atomic16k
8570: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 53  ",             S
8580: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d  QLITE_IOCAP_ATOM
8590: 49 43 31 36 4b 20 20 20 20 20 20 20 20 20 20 20  IC16K           
85a0: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22    },.        { "
85b0: 61 74 6f 6d 69 63 33 32 6b 22 2c 20 20 20 20 20  atomic32k",     
85c0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49          SQLITE_I
85d0: 4f 43 41 50 5f 41 54 4f 4d 49 43 33 32 4b 20 20  OCAP_ATOMIC32K  
85e0: 20 20 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20             },.  
85f0: 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 36        { "atomic6
8600: 34 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20 20  4k",            
8610: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54   SQLITE_IOCAP_AT
8620: 4f 4d 49 43 36 34 4b 20 20 20 20 20 20 20 20 20  OMIC64K         
8630: 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b      },.        {
8640: 20 22 73 65 71 75 65 6e 74 69 61 6c 22 2c 20 20   "sequential",  
8650: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8660: 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41  _IOCAP_SEQUENTIA
8670: 4c 20 20 20 20 20 20 20 20 20 20 20 20 7d 2c 0a  L            },.
8680: 20 20 20 20 20 20 20 20 7b 20 22 73 61 66 65 5f          { "safe_
8690: 61 70 70 65 6e 64 22 2c 20 20 20 20 20 20 20 20  append",        
86a0: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
86b0: 53 41 46 45 5f 41 50 50 45 4e 44 20 20 20 20 20  SAFE_APPEND     
86c0: 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20        },.       
86d0: 20 7b 20 22 75 6e 64 65 6c 65 74 61 62 6c 65 5f   { "undeletable_
86e0: 77 68 65 6e 5f 6f 70 65 6e 22 2c 20 53 51 4c 49  when_open", SQLI
86f0: 54 45 5f 49 4f 43 41 50 5f 55 4e 44 45 4c 45 54  TE_IOCAP_UNDELET
8700: 41 42 4c 45 5f 57 48 45 4e 5f 4f 50 45 4e 20 7d  ABLE_WHEN_OPEN }
8710: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 70 6f 77  ,.        { "pow
8720: 65 72 73 61 66 65 5f 6f 76 65 72 77 72 69 74 65  ersafe_overwrite
8730: 22 2c 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41  ",   SQLITE_IOCA
8740: 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52  P_POWERSAFE_OVER
8750: 57 52 49 54 45 20 20 20 7d 2c 0a 20 20 20 20 20  WRITE   },.     
8760: 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 20 20     { 0, 0 }.    
8770: 20 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4f    };.      Tcl_O
8780: 62 6a 20 2a 70 52 65 74 3b 0a 20 20 20 20 20 20  bj *pRet;.      
8790: 69 6e 74 20 69 46 6c 61 67 3b 0a 0a 20 20 20 20  int iFlag;..    
87a0: 20 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a    if( objc>3 ){.
87b0: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
87c0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
87d0: 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 41 54 54 52   2, objv, "?ATTR
87e0: 2d 4c 49 53 54 3f 22 29 3b 0a 20 20 20 20 20 20  -LIST?");.      
87f0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
8800: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
8810: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
8820: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b 0a  .        int j;.
8830: 20 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65 77          int iNew
8840: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 54 63   = 0;.        Tc
8850: 6c 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73 20 3d 20  l_Obj **flags = 
8860: 30 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  0;.        int n
8870: 46 6c 61 67 73 20 3d 20 30 3b 0a 0a 20 20 20 20  Flags = 0;..    
8880: 20 20 20 20 69 66 28 20 54 63 6c 5f 4c 69 73 74      if( Tcl_List
8890: 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69  ObjGetElements(i
88a0: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20  nterp, objv[2], 
88b0: 26 6e 46 6c 61 67 73 2c 20 26 66 6c 61 67 73 29  &nFlags, &flags)
88c0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65   ){.          re
88d0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
88e0: 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
88f0: 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 46     for(j=0; j<nF
8900: 6c 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20  lags; j++){.    
8910: 20 20 20 20 20 20 69 6e 74 20 69 64 78 20 3d 20        int idx = 
8920: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  0;.          if(
8930: 20 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f   Tcl_GetIndexFro
8940: 6d 4f 62 6a 53 74 72 75 63 74 28 69 6e 74 65 72  mObjStruct(inter
8950: 70 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20 61 46 6c  p, flags[j], aFl
8960: 61 67 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  ag, .           
8970: 20 20 20 20 20 73 69 7a 65 6f 66 28 61 46 6c 61       sizeof(aFla
8980: 67 5b 30 5d 29 2c 20 22 66 6c 61 67 22 2c 20 30  g[0]), "flag", 0
8990: 2c 20 26 69 64 78 29 20 0a 20 20 20 20 20 20 20  , &idx) .       
89a0: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
89b0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
89c0: 4f 52 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  OR;.          }.
89d0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61 46            if( aF
89e0: 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3c  lag[idx].iValue<
89f0: 30 20 26 26 20 6e 46 6c 61 67 73 3e 31 20 29 7b  0 && nFlags>1 ){
8a00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c  .            Tcl
8a10: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
8a20: 74 65 72 70 2c 20 22 62 61 64 20 66 6c 61 67 73  terp, "bad flags
8a30: 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  : ", Tcl_GetStri
8a40: 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b  ng(objv[2]), 0);
8a50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
8a60: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
8a70: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
8a80: 20 20 20 20 20 69 4e 65 77 20 7c 3d 20 61 46 6c       iNew |= aFl
8a90: 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3b 0a  ag[idx].iValue;.
8aa0: 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
8ab0: 20 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20 3d     p->iDevchar =
8ac0: 20 69 4e 65 77 7c 20 30 78 31 30 30 30 30 30 30   iNew| 0x1000000
8ad0: 30 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  0;.      }..    
8ae0: 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65 77    pRet = Tcl_New
8af0: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f 72  Obj();.      for
8b00: 28 69 46 6c 61 67 3d 30 3b 20 69 46 6c 61 67 3c  (iFlag=0; iFlag<
8b10: 73 69 7a 65 6f 66 28 61 46 6c 61 67 29 2f 73 69  sizeof(aFlag)/si
8b20: 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d 29 3b 20  zeof(aFlag[0]); 
8b30: 69 46 6c 61 67 2b 2b 29 7b 0a 20 20 20 20 20 20  iFlag++){.      
8b40: 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61    if( p->iDevcha
8b50: 72 20 26 20 61 46 6c 61 67 5b 69 46 6c 61 67 5d  r & aFlag[iFlag]
8b60: 2e 69 56 61 6c 75 65 20 29 7b 0a 20 20 20 20 20  .iValue ){.     
8b70: 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a       Tcl_ListObj
8b80: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 0a 20  AppendElement(. 
8b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
8ba0: 65 72 70 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e  erp, pRet, Tcl_N
8bb0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 46 6c 61  ewStringObj(aFla
8bc0: 67 5b 69 46 6c 61 67 5d 2e 7a 4e 61 6d 65 2c 20  g[iFlag].zName, 
8bd0: 2d 31 29 0a 20 20 20 20 20 20 20 20 20 20 29 3b  -1).          );
8be0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
8bf0: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74   }.      Tcl_Set
8c00: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
8c10: 2c 20 70 52 65 74 29 3b 0a 0a 20 20 20 20 20 20  , pRet);..      
8c20: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
8c30: 20 20 63 61 73 65 20 43 4d 44 5f 53 45 43 54 4f    case CMD_SECTO
8c40: 52 53 49 5a 45 3a 20 7b 0a 20 20 20 20 20 20 69  RSIZE: {.      i
8c50: 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20 20 20  f( objc>3 ){.   
8c60: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
8c70: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
8c80: 20 6f 62 6a 76 2c 20 22 3f 56 41 4c 55 45 3f 22   objv, "?VALUE?"
8c90: 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  );.        retur
8ca0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
8cb0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f     }.      if( o
8cc0: 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20  bjc==3 ){.      
8cd0: 20 20 69 6e 74 20 69 4e 65 77 20 3d 20 30 3b 0a    int iNew = 0;.
8ce0: 20 20 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f          if( Tcl_
8cf0: 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e  GetIntFromObj(in
8d00: 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26  terp, objv[2], &
8d10: 69 4e 65 77 29 20 29 7b 0a 20 20 20 20 20 20 20  iNew) ){.       
8d20: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
8d30: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ROR;.        }. 
8d40: 20 20 20 20 20 20 20 70 2d 3e 69 53 65 63 74 6f         p->iSecto
8d50: 72 73 69 7a 65 20 3d 20 69 4e 65 77 3b 0a 20 20  rsize = iNew;.  
8d60: 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f      }.      Tcl_
8d70: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
8d80: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f  erp, Tcl_NewIntO
8d90: 62 6a 28 70 2d 3e 69 53 65 63 74 6f 72 73 69 7a  bj(p->iSectorsiz
8da0: 65 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  e));.      break
8db0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
8dc0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
8dd0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 65 73  .static void tes
8de0: 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 28 43 6c 69  tvfs_obj_del(Cli
8df0: 65 6e 74 44 61 74 61 20 63 64 29 7b 0a 20 20 54  entData cd){.  T
8e00: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
8e10: 74 76 66 73 20 2a 29 63 64 3b 0a 20 20 69 66 28  tvfs *)cd;.  if(
8e20: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 20 54 63   p->pScript ) Tc
8e30: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
8e40: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 73 71  ->pScript);.  sq
8e50: 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72 65 67 69  lite3_vfs_unregi
8e60: 73 74 65 72 28 70 2d 3e 70 56 66 73 29 3b 0a 20  ster(p->pVfs);. 
8e70: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
8e80: 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63 6b 66 72  p->pVfs);.  ckfr
8e90: 65 65 28 28 63 68 61 72 20 2a 29 70 29 3b 0a 7d  ee((char *)p);.}
8ea0: 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 20  ../*.** Usage:  
8eb0: 74 65 73 74 76 66 73 20 56 46 53 4e 41 4d 45 20  testvfs VFSNAME 
8ec0: 3f 53 57 49 54 43 48 45 53 3f 0a 2a 2a 0a 2a 2a  ?SWITCHES?.**.**
8ed0: 20 53 77 69 74 63 68 65 73 20 61 72 65 3a 0a 2a   Switches are:.*
8ee0: 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d 20 20 20  *.**   -noshm   
8ef0: 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20 20 20  BOOLEAN         
8f00: 20 20 20 20 28 54 72 75 65 20 74 6f 20 6f 6d 69      (True to omi
8f10: 74 20 73 68 6d 20 6d 65 74 68 6f 64 73 2e 20 44  t shm methods. D
8f20: 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a  efault false).**
8f30: 20 20 20 2d 64 65 66 61 75 6c 74 20 42 4f 4f 4c     -default BOOL
8f40: 45 41 4e 20 20 20 20 20 20 20 20 20 20 20 20 20  EAN             
8f50: 28 54 72 75 65 20 74 6f 20 6d 61 6b 65 20 74 68  (True to make th
8f60: 65 20 76 66 73 20 64 65 66 61 75 6c 74 2e 20 44  e vfs default. D
8f70: 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a  efault false).**
8f80: 0a 2a 2a 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64  .** This command
8f90: 20 63 72 65 61 74 65 73 20 74 77 6f 20 74 68 69   creates two thi
8fa0: 6e 67 73 20 77 68 65 6e 20 69 74 20 69 73 20 69  ngs when it is i
8fb0: 6e 76 6f 6b 65 64 3a 20 61 6e 20 53 51 4c 69 74  nvoked: an SQLit
8fc0: 65 20 56 46 53 2c 20 61 6e 64 0a 2a 2a 20 61 20  e VFS, and.** a 
8fd0: 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20 42 6f 74  Tcl command. Bot
8fe0: 68 20 61 72 65 20 6e 61 6d 65 64 20 56 46 53 4e  h are named VFSN
8ff0: 41 4d 45 2e 20 54 68 65 20 56 46 53 20 69 73 20  AME. The VFS is 
9000: 69 6e 73 74 61 6c 6c 65 64 2e 20 49 74 20 69 73  installed. It is
9010: 20 6e 6f 74 0a 2a 2a 20 69 6e 73 74 61 6c 6c 65   not.** installe
9020: 64 20 61 73 20 74 68 65 20 64 65 66 61 75 6c 74  d as the default
9030: 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20   VFS..**.** The 
9040: 56 46 53 20 70 61 73 73 65 73 20 61 6c 6c 20 66  VFS passes all f
9050: 69 6c 65 20 49 2f 4f 20 63 61 6c 6c 73 20 74 68  ile I/O calls th
9060: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 75 6e 64  rough to the und
9070: 65 72 6c 79 69 6e 67 20 56 46 53 2e 0a 2a 2a 0a  erlying VFS..**.
9080: 2a 2a 20 57 68 65 6e 65 76 65 72 20 74 68 65 20  ** Whenever the 
9090: 78 53 68 6d 4d 61 70 20 6d 65 74 68 6f 64 20 6f  xShmMap method o
90a0: 66 20 74 68 65 20 56 46 53 0a 2a 2a 20 69 73 20  f the VFS.** is 
90b0: 69 6e 76 6f 6b 65 64 2c 20 74 68 65 20 53 43 52  invoked, the SCR
90c0: 49 50 54 20 69 73 20 65 78 65 63 75 74 65 64 20  IPT is executed 
90d0: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
90e0: 2a 20 20 20 53 43 52 49 50 54 20 78 53 68 6d 4d  *   SCRIPT xShmM
90f0: 61 70 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49  ap    FILENAME I
9100: 44 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75  D.**.** The valu
9110: 65 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68  e returned by th
9120: 65 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20  e invocation of 
9130: 53 43 52 49 50 54 20 61 62 6f 76 65 20 69 73 20  SCRIPT above is 
9140: 69 6e 74 65 72 70 72 65 74 65 64 20 61 73 0a 2a  interpreted as.*
9150: 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  * an SQLite erro
9160: 72 20 63 6f 64 65 20 61 6e 64 20 72 65 74 75 72  r code and retur
9170: 6e 65 64 20 74 6f 20 53 51 4c 69 74 65 2e 20 45  ned to SQLite. E
9180: 69 74 68 65 72 20 61 20 73 79 6d 62 6f 6c 69 63  ither a symbolic
9190: 20 0a 2a 2a 20 22 53 51 4c 49 54 45 5f 4f 4b 22   .** "SQLITE_OK"
91a0: 20 6f 72 20 6e 75 6d 65 72 69 63 20 22 30 22 20   or numeric "0" 
91b0: 76 61 6c 75 65 20 6d 61 79 20 62 65 20 72 65 74  value may be ret
91c0: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  urned..**.** The
91d0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
91e0: 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 62   shared-memory b
91f0: 75 66 66 65 72 20 61 73 73 6f 63 69 61 74 65 64  uffer associated
9200: 20 77 69 74 68 20 61 20 67 69 76 65 6e 20 66 69   with a given fi
9210: 6c 65 0a 2a 2a 20 6d 61 79 20 62 65 20 72 65 61  le.** may be rea
9220: 64 20 61 6e 64 20 73 65 74 20 75 73 69 6e 67 20  d and set using 
9230: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f  the following co
9240: 6d 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 56  mmand:.**.**   V
9250: 46 53 4e 41 4d 45 20 73 68 6d 20 46 49 4c 45 4e  FSNAME shm FILEN
9260: 41 4d 45 20 3f 4e 45 57 56 41 4c 55 45 3f 0a 2a  AME ?NEWVALUE?.*
9270: 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 78 53  *.** When the xS
9280: 68 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64 20 69 73  hmLock method is
9290: 20 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69   invoked by SQLi
92a0: 74 65 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  te, the followin
92b0: 67 20 73 63 72 69 70 74 20 69 73 0a 2a 2a 20 72  g script is.** r
92c0: 75 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49  un:.**.**   SCRI
92d0: 50 54 20 78 53 68 6d 4c 6f 63 6b 20 20 20 20 46  PT xShmLock    F
92e0: 49 4c 45 4e 41 4d 45 20 49 44 20 4c 4f 43 4b 0a  ILENAME ID LOCK.
92f0: 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 4c 4f 43 4b  **.** where LOCK
9300: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20   is of the form 
9310: 22 4f 46 46 53 45 54 20 4e 42 59 54 45 20 6c 6f  "OFFSET NBYTE lo
9320: 63 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61 72 65 64  ck/unlock shared
9330: 2f 65 78 63 6c 75 73 69 76 65 22 0a 2a 2f 0a 73  /exclusive".*/.s
9340: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 76 66  tatic int testvf
9350: 73 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44  s_cmd(.  ClientD
9360: 61 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e  ata cd,.  Tcl_In
9370: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
9380: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
9390: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
93a0: 5d 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71  ].){.  static sq
93b0: 6c 69 74 65 33 5f 76 66 73 20 74 76 66 73 5f 76  lite3_vfs tvfs_v
93c0: 66 73 20 3d 20 7b 0a 20 20 20 20 32 2c 20 20 20  fs = {.    2,   
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 2f 2a 20 69 56 65 72           /* iVer
93f0: 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20  sion */.    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 2f 2a 20 73 7a 4f            /* szO
9420: 73 46 69 6c 65 20 2a 2f 0a 20 20 20 20 30 2c 20  sFile */.    0, 
9430: 20 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 2f 2a 20 6d 78             /* mx
9450: 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 20 20  Pathname */.    
9460: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
9470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9480: 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20 30 2c   pNext */.    0,
9490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
94a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 7a              /* z
94b0: 4e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20  Name */.    0,  
94c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
94d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 70            /* pAp
94e0: 70 44 61 74 61 20 2a 2f 0a 20 20 20 20 74 76 66  pData */.    tvf
94f0: 73 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  sOpen,          
9500: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f             /* xO
9510: 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73 44  pen */.    tvfsD
9520: 65 6c 65 74 65 2c 20 20 20 20 20 20 20 20 20 20  elete,          
9530: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65 6c           /* xDel
9540: 65 74 65 20 2a 2f 0a 20 20 20 20 74 76 66 73 41  ete */.    tvfsA
9550: 63 63 65 73 73 2c 20 20 20 20 20 20 20 20 20 20  ccess,          
9560: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63 63           /* xAcc
9570: 65 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 46  ess */.    tvfsF
9580: 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20 20  ullPathname,    
9590: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 75 6c           /* xFul
95a0: 6c 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 23 69 66  lPathname */.#if
95b0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
95c0: 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a  _LOAD_EXTENSION.
95d0: 20 20 20 20 74 76 66 73 44 6c 4f 70 65 6e 2c 20      tvfsDlOpen, 
95e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
95f0: 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a    /* xDlOpen */.
9600: 20 20 20 20 74 76 66 73 44 6c 45 72 72 6f 72 2c      tvfsDlError,
9610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9620: 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f    /* xDlError */
9630: 0a 20 20 20 20 74 76 66 73 44 6c 53 79 6d 2c 20  .    tvfsDlSym, 
9640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9650: 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a     /* xDlSym */.
9660: 20 20 20 20 74 76 66 73 44 6c 43 6c 6f 73 65 2c      tvfsDlClose,
9670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9680: 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f    /* xDlClose */
9690: 0a 23 65 6c 73 65 0a 20 20 20 20 30 2c 20 20 20  .#else.    0,   
96a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 4f           /* xDlO
96c0: 70 65 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  pen */.    0,   
96d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 45           /* xDlE
96f0: 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30 2c 20 20  rror */.    0,  
9700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
9720: 53 79 6d 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  Sym */.    0,   
9730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9740: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 43           /* xDlC
9750: 6c 6f 73 65 20 2a 2f 0a 23 65 6e 64 69 66 20 2f  lose */.#endif /
9760: 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f  * SQLITE_OMIT_LO
9770: 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a  AD_EXTENSION */.
9780: 20 20 20 20 74 76 66 73 52 61 6e 64 6f 6d 6e 65      tvfsRandomne
9790: 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ss,             
97a0: 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e 65 73 73    /* xRandomness
97b0: 20 2a 2f 0a 20 20 20 20 74 76 66 73 53 6c 65 65   */.    tvfsSlee
97c0: 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
97d0: 20 20 20 20 20 20 2f 2a 20 78 53 6c 65 65 70 20        /* xSleep 
97e0: 2a 2f 0a 20 20 20 20 74 76 66 73 43 75 72 72 65  */.    tvfsCurre
97f0: 6e 74 54 69 6d 65 2c 20 20 20 20 20 20 20 20 20  ntTime,         
9800: 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e 74       /* xCurrent
9810: 54 69 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20  Time */.    0,  
9820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9830: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 47 65            /* xGe
9840: 74 4c 61 73 74 45 72 72 6f 72 20 2a 2f 0a 20 20  tLastError */.  
9850: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
9860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9870: 2f 2a 20 78 43 75 72 72 65 6e 74 54 69 6d 65 49  /* xCurrentTimeI
9880: 6e 74 36 34 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20  nt64 */.  };..  
9890: 54 65 73 74 76 66 73 20 2a 70 3b 20 20 20 20 20  Testvfs *p;     
98a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
98b0: 2f 2a 20 4e 65 77 20 6f 62 6a 65 63 74 20 2a 2f  /* New object */
98c0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
98d0: 70 56 66 73 3b 20 20 20 20 20 20 20 20 20 20 20  pVfs;           
98e0: 20 20 20 2f 2a 20 4e 65 77 20 56 46 53 20 2a 2f     /* New VFS */
98f0: 0a 20 20 63 68 61 72 20 2a 7a 56 66 73 3b 0a 20  .  char *zVfs;. 
9900: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
9910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9920: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61   /* Bytes of spa
9930: 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  ce to allocate a
9940: 74 20 70 20 2a 2f 0a 0a 20 20 69 6e 74 20 69 3b  t p */..  int i;
9950: 0a 20 20 69 6e 74 20 69 73 4e 6f 73 68 6d 20 3d  .  int isNoshm =
9960: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9970: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 2d 6e     /* True if -n
9980: 6f 73 68 6d 20 69 73 20 70 61 73 73 65 64 20 2a  oshm is passed *
9990: 2f 0a 20 20 69 6e 74 20 69 73 44 65 66 61 75 6c  /.  int isDefaul
99a0: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
99b0: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 2d      /* True if -
99c0: 64 65 66 61 75 6c 74 20 69 73 20 70 61 73 73 65  default is passe
99d0: 64 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4f 73 46  d */.  int szOsF
99e0: 69 6c 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ile = 0;        
99f0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
9a00: 70 61 73 73 65 64 20 74 6f 20 2d 73 7a 6f 73 66  passed to -szosf
9a10: 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50  ile */.  int mxP
9a20: 61 74 68 6e 61 6d 65 20 3d 20 2d 31 3b 20 20 20  athname = -1;   
9a30: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
9a40: 65 20 70 61 73 73 65 64 20 74 6f 20 2d 6d 78 70  e passed to -mxp
9a50: 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74  athname */.  int
9a60: 20 69 56 65 72 73 69 6f 6e 20 3d 20 32 3b 20 20   iVersion = 2;  
9a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9a80: 56 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f 20  Value passed to 
9a90: 2d 69 76 65 72 73 69 6f 6e 20 2a 2f 0a 0a 20 20  -iversion */..  
9aa0: 69 66 28 20 6f 62 6a 63 3c 32 20 7c 7c 20 30 21  if( objc<2 || 0!
9ab0: 3d 28 6f 62 6a 63 25 32 29 20 29 20 67 6f 74 6f  =(objc%2) ) goto
9ac0: 20 62 61 64 5f 61 72 67 73 3b 0a 20 20 66 6f 72   bad_args;.  for
9ad0: 28 69 3d 32 3b 20 69 3c 6f 62 6a 63 3b 20 69 20  (i=2; i<objc; i 
9ae0: 2b 3d 20 32 29 7b 0a 20 20 20 20 69 6e 74 20 6e  += 2){.    int n
9af0: 53 77 69 74 63 68 3b 0a 20 20 20 20 63 68 61 72  Switch;.    char
9b00: 20 2a 7a 53 77 69 74 63 68 3b 0a 20 20 20 20 7a   *zSwitch;.    z
9b10: 53 77 69 74 63 68 20 3d 20 54 63 6c 5f 47 65 74  Switch = Tcl_Get
9b20: 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62  StringFromObj(ob
9b30: 6a 76 5b 69 5d 2c 20 26 6e 53 77 69 74 63 68 29  jv[i], &nSwitch)
9b40: 3b 20 0a 0a 20 20 20 20 69 66 28 20 6e 53 77 69  ; ..    if( nSwi
9b50: 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e  tch>2 && 0==strn
9b60: 63 6d 70 28 22 2d 6e 6f 73 68 6d 22 2c 20 7a 53  cmp("-noshm", zS
9b70: 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20  witch, nSwitch) 
9b80: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c  ){.      if( Tcl
9b90: 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f  _GetBooleanFromO
9ba0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
9bb0: 69 2b 31 5d 2c 20 26 69 73 4e 6f 73 68 6d 29 20  i+1], &isNoshm) 
9bc0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
9bd0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
9be0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65     }.    }.    e
9bf0: 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e  lse if( nSwitch>
9c00: 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28  2 && 0==strncmp(
9c10: 22 2d 64 65 66 61 75 6c 74 22 2c 20 7a 53 77 69  "-default", zSwi
9c20: 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b  tch, nSwitch) ){
9c30: 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47  .      if( Tcl_G
9c40: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
9c50: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b  (interp, objv[i+
9c60: 31 5d 2c 20 26 69 73 44 65 66 61 75 6c 74 29 20  1], &isDefault) 
9c70: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
9c80: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
9c90: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65     }.    }.    e
9ca0: 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e  lse if( nSwitch>
9cb0: 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28  2 && 0==strncmp(
9cc0: 22 2d 73 7a 6f 73 66 69 6c 65 22 2c 20 7a 53 77  "-szosfile", zSw
9cd0: 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29  itch, nSwitch) )
9ce0: 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f  {.      if( Tcl_
9cf0: 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e  GetIntFromObj(in
9d00: 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c  terp, objv[i+1],
9d10: 20 26 73 7a 4f 73 46 69 6c 65 29 20 29 7b 0a 20   &szOsFile) ){. 
9d20: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
9d30: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
9d40: 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 20  .    }.    else 
9d50: 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26  if( nSwitch>2 &&
9d60: 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 6d 78   0==strncmp("-mx
9d70: 70 61 74 68 6e 61 6d 65 22 2c 20 7a 53 77 69 74  pathname", zSwit
9d80: 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a  ch, nSwitch) ){.
9d90: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
9da0: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
9db0: 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26  rp, objv[i+1], &
9dc0: 6d 78 50 61 74 68 6e 61 6d 65 29 20 29 7b 0a 20  mxPathname) ){. 
9dd0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
9de0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  L_ERROR;.      }
9df0: 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 20  .    }.    else 
9e00: 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26  if( nSwitch>2 &&
9e10: 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 69 76   0==strncmp("-iv
9e20: 65 72 73 69 6f 6e 22 2c 20 7a 53 77 69 74 63 68  ersion", zSwitch
9e30: 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20  , nSwitch) ){.  
9e40: 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49      if( Tcl_GetI
9e50: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  ntFromObj(interp
9e60: 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 56  , objv[i+1], &iV
9e70: 65 72 73 69 6f 6e 29 20 29 7b 0a 20 20 20 20 20  ersion) ){.     
9e80: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
9e90: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
9ea0: 20 7d 0a 20 20 20 20 65 6c 73 65 7b 0a 20 20 20   }.    else{.   
9eb0: 20 20 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73     goto bad_args
9ec0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
9ed0: 66 28 20 73 7a 4f 73 46 69 6c 65 3c 73 69 7a 65  f( szOsFile<size
9ee0: 6f 66 28 54 65 73 74 76 66 73 46 69 6c 65 29 20  of(TestvfsFile) 
9ef0: 29 7b 0a 20 20 20 20 73 7a 4f 73 46 69 6c 65 20  ){.    szOsFile 
9f00: 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  = sizeof(Testvfs
9f10: 46 69 6c 65 29 3b 0a 20 20 7d 0a 0a 20 20 7a 56  File);.  }..  zV
9f20: 66 73 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  fs = Tcl_GetStri
9f30: 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 6e  ng(objv[1]);.  n
9f40: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 54 65  Byte = sizeof(Te
9f50: 73 74 76 66 73 29 20 2b 20 73 74 72 6c 65 6e 28  stvfs) + strlen(
9f60: 7a 56 66 73 29 2b 31 3b 0a 20 20 70 20 3d 20 28  zVfs)+1;.  p = (
9f70: 54 65 73 74 76 66 73 20 2a 29 63 6b 61 6c 6c 6f  Testvfs *)ckallo
9f80: 63 28 6e 42 79 74 65 29 3b 0a 20 20 6d 65 6d 73  c(nByte);.  mems
9f90: 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b  et(p, 0, nByte);
9fa0: 0a 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20 3d  .  p->iDevchar =
9fb0: 20 2d 31 3b 0a 20 20 70 2d 3e 69 53 65 63 74 6f   -1;.  p->iSecto
9fc0: 72 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a 20 20 2f  rsize = -1;..  /
9fd0: 2a 20 43 72 65 61 74 65 20 74 68 65 20 6e 65 77  * Create the new
9fe0: 20 6f 62 6a 65 63 74 20 63 6f 6d 6d 61 6e 64 20   object command 
9ff0: 62 65 66 6f 72 65 20 71 75 65 72 79 69 6e 67 20  before querying 
a000: 53 51 4c 69 74 65 20 66 6f 72 20 61 20 64 65 66  SQLite for a def
a010: 61 75 6c 74 20 56 46 53 0a 20 20 2a 2a 20 74 6f  ault VFS.  ** to
a020: 20 75 73 65 20 66 6f 72 20 27 72 65 61 6c 27 20   use for 'real' 
a030: 49 4f 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20 54  IO operations. T
a040: 68 69 73 20 69 73 20 62 65 63 61 75 73 65 20 63  his is because c
a050: 72 65 61 74 69 6e 67 20 74 68 65 20 6e 65 77 20  reating the new 
a060: 56 46 53 0a 20 20 2a 2a 20 6d 61 79 20 64 65 6c  VFS.  ** may del
a070: 65 74 65 20 61 6e 20 65 78 69 73 74 69 6e 67 20  ete an existing 
a080: 5b 74 65 73 74 76 66 73 5d 20 56 46 53 20 6f 66  [testvfs] VFS of
a090: 20 74 68 65 20 73 61 6d 65 20 6e 61 6d 65 2e 20   the same name. 
a0a0: 49 66 20 73 75 63 68 20 61 20 56 46 53 0a 20 20  If such a VFS.  
a0b0: 2a 2a 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  ** is currently 
a0c0: 74 68 65 20 64 65 66 61 75 6c 74 2c 20 74 68 65  the default, the
a0d0: 20 6e 65 77 20 5b 74 65 73 74 76 66 73 5d 20 6d   new [testvfs] m
a0e0: 61 79 20 65 6e 64 20 75 70 20 63 61 6c 6c 69 6e  ay end up callin
a0f0: 67 20 74 68 65 20 0a 20 20 2a 2a 20 6d 65 74 68  g the .  ** meth
a100: 6f 64 73 20 6f 66 20 61 20 64 65 6c 65 74 65 64  ods of a deleted
a110: 20 6f 62 6a 65 63 74 2e 0a 20 20 2a 2f 0a 20 20   object..  */.  
a120: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
a130: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 7a 56 66  mand(interp, zVf
a140: 73 2c 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63  s, testvfs_obj_c
a150: 6d 64 2c 20 70 2c 20 74 65 73 74 76 66 73 5f 6f  md, p, testvfs_o
a160: 62 6a 5f 64 65 6c 29 3b 0a 20 20 70 2d 3e 70 50  bj_del);.  p->pP
a170: 61 72 65 6e 74 20 3d 20 73 71 6c 69 74 65 33 5f  arent = sqlite3_
a180: 76 66 73 5f 66 69 6e 64 28 30 29 3b 0a 20 20 70  vfs_find(0);.  p
a190: 2d 3e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72  ->interp = inter
a1a0: 70 3b 0a 0a 20 20 70 2d 3e 7a 4e 61 6d 65 20 3d  p;..  p->zName =
a1b0: 20 28 63 68 61 72 20 2a 29 26 70 5b 31 5d 3b 0a   (char *)&p[1];.
a1c0: 20 20 6d 65 6d 63 70 79 28 70 2d 3e 7a 4e 61 6d    memcpy(p->zNam
a1d0: 65 2c 20 7a 56 66 73 2c 20 73 74 72 6c 65 6e 28  e, zVfs, strlen(
a1e0: 7a 56 66 73 29 2b 31 29 3b 0a 0a 20 20 70 56 66  zVfs)+1);..  pVf
a1f0: 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73  s = (sqlite3_vfs
a200: 20 2a 29 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f   *)ckalloc(sizeo
a210: 66 28 73 71 6c 69 74 65 33 5f 76 66 73 29 29 3b  f(sqlite3_vfs));
a220: 0a 20 20 6d 65 6d 63 70 79 28 70 56 66 73 2c 20  .  memcpy(pVfs, 
a230: 26 74 76 66 73 5f 76 66 73 2c 20 73 69 7a 65 6f  &tvfs_vfs, sizeo
a240: 66 28 73 71 6c 69 74 65 33 5f 76 66 73 29 29 3b  f(sqlite3_vfs));
a250: 0a 20 20 70 56 66 73 2d 3e 70 41 70 70 44 61 74  .  pVfs->pAppDat
a260: 61 20 3d 20 28 76 6f 69 64 20 2a 29 70 3b 0a 20  a = (void *)p;. 
a270: 20 70 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 20   pVfs->iVersion 
a280: 3d 20 69 56 65 72 73 69 6f 6e 3b 0a 20 20 70 56  = iVersion;.  pV
a290: 66 73 2d 3e 7a 4e 61 6d 65 20 3d 20 70 2d 3e 7a  fs->zName = p->z
a2a0: 4e 61 6d 65 3b 0a 20 20 70 56 66 73 2d 3e 6d 78  Name;.  pVfs->mx
a2b0: 50 61 74 68 6e 61 6d 65 20 3d 20 70 2d 3e 70 50  Pathname = p->pP
a2c0: 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68 6e 61 6d  arent->mxPathnam
a2d0: 65 3b 0a 20 20 69 66 28 20 6d 78 50 61 74 68 6e  e;.  if( mxPathn
a2e0: 61 6d 65 3e 3d 30 20 26 26 20 6d 78 50 61 74 68  ame>=0 && mxPath
a2f0: 6e 61 6d 65 3c 70 56 66 73 2d 3e 6d 78 50 61 74  name<pVfs->mxPat
a300: 68 6e 61 6d 65 20 29 7b 0a 20 20 20 20 70 56 66  hname ){.    pVf
a310: 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20  s->mxPathname = 
a320: 6d 78 50 61 74 68 6e 61 6d 65 3b 0a 20 20 7d 0a  mxPathname;.  }.
a330: 20 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65    pVfs->szOsFile
a340: 20 3d 20 73 7a 4f 73 46 69 6c 65 3b 0a 20 20 70   = szOsFile;.  p
a350: 2d 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20  ->pVfs = pVfs;. 
a360: 20 70 2d 3e 69 73 4e 6f 73 68 6d 20 3d 20 69 73   p->isNoshm = is
a370: 4e 6f 73 68 6d 3b 0a 20 20 70 2d 3e 6d 61 73 6b  Noshm;.  p->mask
a380: 20 3d 20 54 45 53 54 56 46 53 5f 41 4c 4c 5f 4d   = TESTVFS_ALL_M
a390: 41 53 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f  ASK;..  sqlite3_
a3a0: 76 66 73 5f 72 65 67 69 73 74 65 72 28 70 56 66  vfs_register(pVf
a3b0: 73 2c 20 69 73 44 65 66 61 75 6c 74 29 3b 0a 0a  s, isDefault);..
a3c0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
a3d0: 0a 0a 20 62 61 64 5f 61 72 67 73 3a 0a 20 20 54  .. bad_args:.  T
a3e0: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
a3f0: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
a400: 20 22 56 46 53 4e 41 4d 45 20 3f 2d 6e 6f 73 68   "VFSNAME ?-nosh
a410: 6d 20 42 4f 4f 4c 3f 20 3f 2d 64 65 66 61 75 6c  m BOOL? ?-defaul
a420: 74 20 42 4f 4f 4c 3f 20 3f 2d 6d 78 70 61 74 68  t BOOL? ?-mxpath
a430: 6e 61 6d 65 20 49 4e 54 3f 20 3f 2d 73 7a 6f 73  name INT? ?-szos
a440: 66 69 6c 65 20 49 4e 54 3f 20 3f 2d 69 76 65 72  file INT? ?-iver
a450: 73 69 6f 6e 20 49 4e 54 3f 22 29 3b 0a 20 20 72  sion INT?");.  r
a460: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
a470: 0a 7d 0a 0a 69 6e 74 20 53 71 6c 69 74 65 74 65  .}..int Sqlitete
a480: 73 74 76 66 73 5f 49 6e 69 74 28 54 63 6c 5f 49  stvfs_Init(Tcl_I
a490: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a  nterp *interp){.
a4a0: 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43    Tcl_CreateObjC
a4b0: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
a4c0: 74 65 73 74 76 66 73 22 2c 20 74 65 73 74 76 66  testvfs", testvf
a4d0: 73 5f 63 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20  s_cmd, 0, 0);.  
a4e0: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
a4f0: 0a 0a 23 65 6e 64 69 66 0a                       ..#endif.