/ Hex Artifact Content
Login

Artifact 3b65d42e18b262805716bd96178c81da8f2d9283:


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 23 69 6e 63 6c 75 64 65  eInt.h".#include
0450: 20 3c 74 63 6c 2e 68 3e 0a 0a 74 79 70 65 64 65   <tcl.h>..typede
0460: 66 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73  f struct Testvfs
0470: 20 54 65 73 74 76 66 73 3b 0a 74 79 70 65 64 65   Testvfs;.typede
0480: 66 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73  f struct Testvfs
0490: 53 68 6d 20 54 65 73 74 76 66 73 53 68 6d 3b 0a  Shm TestvfsShm;.
04a0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54  typedef struct T
04b0: 65 73 74 76 66 73 42 75 66 66 65 72 20 54 65 73  estvfsBuffer Tes
04c0: 74 76 66 73 42 75 66 66 65 72 3b 0a 74 79 70 65  tvfsBuffer;.type
04d0: 64 65 66 20 73 74 72 75 63 74 20 54 65 73 74 76  def struct Testv
04e0: 66 73 46 69 6c 65 20 54 65 73 74 76 66 73 46 69  fsFile TestvfsFi
04f0: 6c 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  le;.typedef stru
0500: 63 74 20 54 65 73 74 76 66 73 46 64 20 54 65 73  ct TestvfsFd Tes
0510: 74 76 66 73 46 64 3b 0a 0a 2f 2a 0a 2a 2a 20 41  tvfsFd;../*.** A
0520: 6e 20 6f 70 65 6e 20 66 69 6c 65 20 68 61 6e 64  n open file hand
0530: 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65  le..*/.struct Te
0540: 73 74 76 66 73 46 69 6c 65 20 7b 0a 20 20 73 71  stvfsFile {.  sq
0550: 6c 69 74 65 33 5f 66 69 6c 65 20 62 61 73 65 3b  lite3_file base;
0560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0570: 20 42 61 73 65 20 63 6c 61 73 73 2e 20 20 4d 75   Base class.  Mu
0580: 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20  st be first */. 
0590: 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 3b   TestvfsFd *pFd;
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
05b0: 20 2f 2a 20 46 69 6c 65 20 64 61 74 61 20 2a 2f   /* File data */
05c0: 0a 7d 3b 0a 23 64 65 66 69 6e 65 20 74 76 66 73  .};.#define tvfs
05d0: 47 65 74 46 64 28 70 46 69 6c 65 29 20 28 28 28  GetFd(pFile) (((
05e0: 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46  TestvfsFile *)pF
05f0: 69 6c 65 29 2d 3e 70 46 64 29 0a 0a 73 74 72 75  ile)->pFd)..stru
0600: 63 74 20 54 65 73 74 76 66 73 46 64 20 7b 0a 20  ct TestvfsFd {. 
0610: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
0620: 66 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  fs;             
0630: 20 2f 2a 20 54 68 65 20 56 46 53 20 2a 2f 0a 20   /* The VFS */. 
0640: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69   const char *zFi
0650: 6c 65 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  lename;         
0660: 20 2f 2a 20 46 69 6c 65 6e 61 6d 65 20 61 73 20   /* Filename as 
0670: 70 61 73 73 65 64 20 74 6f 20 78 4f 70 65 6e 28  passed to xOpen(
0680: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  ) */.  sqlite3_f
0690: 69 6c 65 20 2a 70 52 65 61 6c 3b 20 20 20 20 20  ile *pReal;     
06a0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 72 65         /* The re
06b0: 61 6c 2c 20 75 6e 64 65 72 6c 79 69 6e 67 20 66  al, underlying f
06c0: 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 2a  ile descriptor *
06d0: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 68  /.  Tcl_Obj *pSh
06e0: 6d 49 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  mId;            
06f0: 20 20 20 20 2f 2a 20 53 68 61 72 65 64 20 6d 65      /* Shared me
0700: 6d 6f 72 79 20 69 64 20 66 6f 72 20 54 63 6c 20  mory id for Tcl 
0710: 63 61 6c 6c 62 61 63 6b 73 20 2a 2f 0a 0a 20 20  callbacks */..  
0720: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70  TestvfsBuffer *p
0730: 53 68 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20  Shm;            
0740: 2f 2a 20 53 68 61 72 65 64 20 6d 65 6d 6f 72 79  /* Shared memory
0750: 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 75 33 32   buffer */.  u32
0760: 20 65 78 63 6c 6c 6f 63 6b 3b 20 20 20 20 20 20   excllock;      
0770: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0780: 4d 61 73 6b 20 6f 66 20 65 78 63 6c 75 73 69 76  Mask of exclusiv
0790: 65 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20 75 33 32  e locks */.  u32
07a0: 20 73 68 61 72 65 64 6c 6f 63 6b 3b 20 20 20 20   sharedlock;    
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
07c0: 4d 61 73 6b 20 6f 66 20 73 68 61 72 65 64 20 6c  Mask of shared l
07d0: 6f 63 6b 73 20 2a 2f 0a 20 20 54 65 73 74 76 66  ocks */.  Testvf
07e0: 73 46 64 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  sFd *pNext;     
07f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
0800: 74 20 68 61 6e 64 6c 65 20 6f 70 65 6e 65 64 20  t handle opened 
0810: 6f 6e 20 74 68 65 20 73 61 6d 65 20 66 69 6c 65  on the same file
0820: 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69 6e 65   */.};...#define
0830: 20 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 4e 4f   FAULT_INJECT_NO
0840: 4e 45 20 20 20 20 20 20 20 30 0a 23 64 65 66 69  NE       0.#defi
0850: 6e 65 20 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f  ne FAULT_INJECT_
0860: 54 52 41 4e 53 49 45 4e 54 20 20 31 0a 23 64 65  TRANSIENT  1.#de
0870: 66 69 6e 65 20 46 41 55 4c 54 5f 49 4e 4a 45 43  fine FAULT_INJEC
0880: 54 5f 50 45 52 53 49 53 54 45 4e 54 20 32 0a 0a  T_PERSISTENT 2..
0890: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54  typedef struct T
08a0: 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 54  estFaultInject T
08b0: 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 3b 0a  estFaultInject;.
08c0: 73 74 72 75 63 74 20 54 65 73 74 46 61 75 6c 74  struct TestFault
08d0: 49 6e 6a 65 63 74 20 7b 0a 20 20 69 6e 74 20 69  Inject {.  int i
08e0: 43 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Cnt;            
08f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
0900: 6d 61 69 6e 69 6e 67 20 63 61 6c 6c 73 20 62 65  maining calls be
0910: 66 6f 72 65 20 66 61 75 6c 74 20 69 6e 6a 65 63  fore fault injec
0920: 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 65 46  tion */.  int eF
0930: 61 75 6c 74 3b 20 20 20 20 20 20 20 20 20 20 20  ault;           
0940: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 20 46            /* A F
0950: 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 2a 20 76 61  AULT_INJECT_* va
0960: 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 46 61  lue */.  int nFa
0970: 69 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  il;             
0980: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0990: 65 72 20 6f 66 20 66 61 75 6c 74 73 20 69 6e 6a  er of faults inj
09a0: 65 63 74 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  ected */.};../*.
09b0: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
09c0: 66 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  f this structure
09d0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f   is allocated fo
09e0: 72 20 65 61 63 68 20 56 46 53 20 63 72 65 61 74  r each VFS creat
09f0: 65 64 2e 20 54 68 65 0a 2a 2a 20 73 71 6c 69 74  ed. The.** sqlit
0a00: 65 33 5f 76 66 73 2e 70 41 70 70 44 61 74 61 20  e3_vfs.pAppData 
0a10: 66 69 65 6c 64 20 6f 66 20 74 68 65 20 56 46 53  field of the VFS
0a20: 20 73 74 72 75 63 74 75 72 65 20 72 65 67 69 73   structure regis
0a30: 74 65 72 65 64 20 77 69 74 68 20 53 51 4c 69 74  tered with SQLit
0a40: 65 0a 2a 2a 20 69 73 20 73 65 74 20 74 6f 20 70  e.** is set to p
0a50: 6f 69 6e 74 20 74 6f 20 69 74 2e 0a 2a 2f 0a 73  oint to it..*/.s
0a60: 74 72 75 63 74 20 54 65 73 74 76 66 73 20 7b 0a  truct Testvfs {.
0a70: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20    char *zName;  
0a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a90: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 69    /* Name of thi
0aa0: 73 20 56 46 53 20 2a 2f 0a 20 20 73 71 6c 69 74  s VFS */.  sqlit
0ab0: 65 33 5f 76 66 73 20 2a 70 50 61 72 65 6e 74 3b  e3_vfs *pParent;
0ac0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
0ad0: 65 20 56 46 53 20 74 6f 20 75 73 65 20 66 6f 72  e VFS to use for
0ae0: 20 66 69 6c 65 20 49 4f 20 2a 2f 0a 20 20 73 71   file IO */.  sq
0af0: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b  lite3_vfs *pVfs;
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0b10: 20 54 68 65 20 74 65 73 74 76 66 73 20 72 65 67   The testvfs reg
0b20: 69 73 74 65 72 65 64 20 77 69 74 68 20 53 51 4c  istered with SQL
0b30: 69 74 65 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74  ite */.  Tcl_Int
0b40: 65 72 70 20 2a 69 6e 74 65 72 70 3b 20 20 20 20  erp *interp;    
0b50: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 74 65           /* Inte
0b60: 72 70 72 65 74 65 72 20 74 6f 20 72 75 6e 20 73  rpreter to run s
0b70: 63 72 69 70 74 20 69 6e 20 2a 2f 0a 20 20 54 63  cript in */.  Tc
0b80: 6c 5f 4f 62 6a 20 2a 70 53 63 72 69 70 74 3b 20  l_Obj *pScript; 
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ba0: 20 53 63 72 69 70 74 20 74 6f 20 65 78 65 63 75   Script to execu
0bb0: 74 65 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 42  te */.  TestvfsB
0bc0: 75 66 66 65 72 20 2a 70 42 75 66 66 65 72 3b 20  uffer *pBuffer; 
0bd0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20          /* List 
0be0: 6f 66 20 73 68 61 72 65 64 20 62 75 66 66 65 72  of shared buffer
0bf0: 73 20 2a 2f 0a 20 20 69 6e 74 20 69 73 4e 6f 73  s */.  int isNos
0c00: 68 6d 3b 0a 20 20 69 6e 74 20 69 73 46 75 6c 6c  hm;.  int isFull
0c10: 73 68 6d 3b 0a 0a 20 20 69 6e 74 20 6d 61 73 6b  shm;..  int mask
0c20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0c30: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b 20          /* Mask 
0c40: 63 6f 6e 74 72 6f 6c 6c 69 6e 67 20 5b 73 63 72  controlling [scr
0c50: 69 70 74 5d 20 61 6e 64 20 5b 69 6f 65 72 72 5d  ipt] and [ioerr]
0c60: 20 2a 2f 0a 0a 20 20 54 65 73 74 46 61 75 6c 74   */..  TestFault
0c70: 49 6e 6a 65 63 74 20 69 6f 65 72 72 5f 65 72 72  Inject ioerr_err
0c80: 3b 0a 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a  ;.  TestFaultInj
0c90: 65 63 74 20 66 75 6c 6c 5f 65 72 72 3b 0a 20 20  ect full_err;.  
0ca0: 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74 20  TestFaultInject 
0cb0: 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 0a 0a 23  cantopen_err;..#
0cc0: 69 66 20 30 0a 20 20 69 6e 74 20 69 49 6f 65 72  if 0.  int iIoer
0cd0: 72 43 6e 74 3b 0a 20 20 69 6e 74 20 69 6f 65 72  rCnt;.  int ioer
0ce0: 72 3b 0a 20 20 69 6e 74 20 6e 49 6f 65 72 72 46  r;.  int nIoerrF
0cf0: 61 69 6c 3b 0a 20 20 69 6e 74 20 69 46 75 6c 6c  ail;.  int iFull
0d00: 43 6e 74 3b 0a 20 20 69 6e 74 20 66 75 6c 6c 65  Cnt;.  int fulle
0d10: 72 72 3b 0a 20 20 69 6e 74 20 6e 46 75 6c 6c 46  rr;.  int nFullF
0d20: 61 69 6c 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 69  ail;.#endif..  i
0d30: 6e 74 20 69 44 65 76 63 68 61 72 3b 0a 20 20 69  nt iDevchar;.  i
0d40: 6e 74 20 69 53 65 63 74 6f 72 73 69 7a 65 3b 0a  nt iSectorsize;.
0d50: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 54 65  };../*.** The Te
0d60: 73 74 76 66 73 2e 6d 61 73 6b 20 76 61 72 69 61  stvfs.mask varia
0d70: 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20 61 20  ble is set to a 
0d80: 63 6f 6d 62 69 6e 61 74 69 6f 6e 20 6f 66 20 74  combination of t
0d90: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 2e 0a 2a 2a  he following..**
0da0: 20 49 66 20 61 20 62 69 74 20 69 73 20 63 6c 65   If a bit is cle
0db0: 61 72 20 69 6e 20 54 65 73 74 76 66 73 2e 6d 61  ar in Testvfs.ma
0dc0: 73 6b 2c 20 74 68 65 6e 20 63 61 6c 6c 73 20 6d  sk, then calls m
0dd0: 61 64 65 20 62 79 20 53 51 4c 69 74 65 20 74 6f  ade by SQLite to
0de0: 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72 65 73 70   the .** corresp
0df0: 6f 6e 64 69 6e 67 20 56 46 53 20 6d 65 74 68 6f  onding VFS metho
0e00: 64 20 69 73 20 69 67 6e 6f 72 65 64 20 66 6f 72  d is ignored for
0e10: 20 70 75 72 70 6f 73 65 73 20 6f 66 3a 0a 2a 2a   purposes of:.**
0e20: 0a 2a 2a 20 20 20 2b 20 53 69 6d 75 6c 61 74 69  .**   + Simulati
0e30: 6e 67 20 49 4f 20 65 72 72 6f 72 73 2c 20 61 6e  ng IO errors, an
0e40: 64 0a 2a 2a 20 20 20 2b 20 49 6e 76 6f 6b 69 6e  d.**   + Invokin
0e50: 67 20 74 68 65 20 54 63 6c 20 63 61 6c 6c 62 61  g the Tcl callba
0e60: 63 6b 20 73 63 72 69 70 74 2e 0a 2a 2f 0a 23 64  ck script..*/.#d
0e70: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48  efine TESTVFS_SH
0e80: 4d 4f 50 45 4e 5f 4d 41 53 4b 20 20 20 20 20 20  MOPEN_MASK      
0e90: 30 78 30 30 30 30 30 30 30 31 0a 23 64 65 66 69  0x00000001.#defi
0ea0: 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f  ne TESTVFS_SHMLO
0eb0: 43 4b 5f 4d 41 53 4b 20 20 20 20 20 20 30 78 30  CK_MASK      0x0
0ec0: 30 30 30 30 30 31 30 0a 23 64 65 66 69 6e 65 20  0000010.#define 
0ed0: 54 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d  TESTVFS_SHMMAP_M
0ee0: 41 53 4b 20 20 20 20 20 20 20 30 78 30 30 30 30  ASK       0x0000
0ef0: 30 30 32 30 0a 23 64 65 66 69 6e 65 20 54 45 53  0020.#define TES
0f00: 54 56 46 53 5f 53 48 4d 42 41 52 52 49 45 52 5f  TVFS_SHMBARRIER_
0f10: 4d 41 53 4b 20 20 20 30 78 30 30 30 30 30 30 34  MASK   0x0000004
0f20: 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  0.#define TESTVF
0f30: 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20  S_SHMCLOSE_MASK 
0f40: 20 20 20 20 30 78 30 30 30 30 30 30 38 30 0a 0a      0x00000080..
0f50: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
0f60: 4f 50 45 4e 5f 4d 41 53 4b 20 20 20 20 20 20 20  OPEN_MASK       
0f70: 20 20 30 78 30 30 30 30 30 31 30 30 0a 23 64 65    0x00000100.#de
0f80: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 59 4e  fine TESTVFS_SYN
0f90: 43 5f 4d 41 53 4b 20 20 20 20 20 20 20 20 20 30  C_MASK         0
0fa0: 78 30 30 30 30 30 32 30 30 0a 23 64 65 66 69 6e  x00000200.#defin
0fb0: 65 20 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45  e TESTVFS_DELETE
0fc0: 5f 4d 41 53 4b 20 20 20 20 20 20 20 30 78 30 30  _MASK       0x00
0fd0: 30 30 30 34 30 30 0a 23 64 65 66 69 6e 65 20 54  000400.#define T
0fe0: 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d 41 53  ESTVFS_CLOSE_MAS
0ff0: 4b 20 20 20 20 20 20 20 20 30 78 30 30 30 30 30  K        0x00000
1000: 38 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  800.#define TEST
1010: 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 20  VFS_WRITE_MASK  
1020: 20 20 20 20 20 20 30 78 30 30 30 30 31 30 30 30        0x00001000
1030: 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53  .#define TESTVFS
1040: 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 20  _TRUNCATE_MASK  
1050: 20 20 20 30 78 30 30 30 30 32 30 30 30 0a 23 64     0x00002000.#d
1060: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 41 43  efine TESTVFS_AC
1070: 43 45 53 53 5f 4d 41 53 4b 20 20 20 20 20 20 20  CESS_MASK       
1080: 30 78 30 30 30 30 34 30 30 30 0a 23 64 65 66 69  0x00004000.#defi
1090: 6e 65 20 54 45 53 54 56 46 53 5f 46 55 4c 4c 50  ne TESTVFS_FULLP
10a0: 41 54 48 4e 41 4d 45 5f 4d 41 53 4b 20 30 78 30  ATHNAME_MASK 0x0
10b0: 30 30 30 38 30 30 30 0a 23 64 65 66 69 6e 65 20  0008000.#define 
10c0: 54 45 53 54 56 46 53 5f 52 45 41 44 5f 4d 41 53  TESTVFS_READ_MAS
10d0: 4b 20 20 20 20 20 20 20 20 20 30 78 30 30 30 31  K         0x0001
10e0: 30 30 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53  0000.#define TES
10f0: 54 56 46 53 5f 55 4e 4c 4f 43 4b 5f 4d 41 53 4b  TVFS_UNLOCK_MASK
1100: 20 20 20 20 20 20 20 30 78 30 30 30 32 30 30 30         0x0002000
1110: 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  0.#define TESTVF
1120: 53 5f 4c 4f 43 4b 5f 4d 41 53 4b 20 20 20 20 20  S_LOCK_MASK     
1130: 20 20 20 20 30 78 30 30 30 34 30 30 30 30 0a 23      0x00040000.#
1140: 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 43  define TESTVFS_C
1150: 4b 4c 4f 43 4b 5f 4d 41 53 4b 20 20 20 20 20 20  KLOCK_MASK      
1160: 20 30 78 30 30 30 38 30 30 30 30 0a 0a 23 64 65   0x00080000..#de
1170: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 41 4c 4c  fine TESTVFS_ALL
1180: 5f 4d 41 53 4b 20 20 20 20 20 20 20 20 20 20 30  _MASK          0
1190: 78 30 30 30 46 46 46 46 46 0a 0a 0a 23 64 65 66  x000FFFFF...#def
11a0: 69 6e 65 20 54 45 53 54 56 46 53 5f 4d 41 58 5f  ine TESTVFS_MAX_
11b0: 50 41 47 45 53 20 31 30 32 34 0a 0a 2f 2a 0a 2a  PAGES 1024../*.*
11c0: 2a 20 41 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72  * A shared-memor
11d0: 79 20 62 75 66 66 65 72 2e 20 54 68 65 72 65 20  y buffer. There 
11e0: 69 73 20 6f 6e 65 20 6f 66 20 74 68 65 73 65 20  is one of these 
11f0: 6f 62 6a 65 63 74 73 20 66 6f 72 20 65 61 63 68  objects for each
1200: 20 73 68 61 72 65 64 0a 2a 2a 20 6d 65 6d 6f 72   shared.** memor
1210: 79 20 72 65 67 69 6f 6e 20 6f 70 65 6e 65 64 20  y region opened 
1220: 62 79 20 63 6c 69 65 6e 74 73 2e 20 49 66 20 74  by clients. If t
1230: 77 6f 20 63 6c 69 65 6e 74 73 20 6f 70 65 6e 20  wo clients open 
1240: 74 68 65 20 73 61 6d 65 20 66 69 6c 65 2c 0a 2a  the same file,.*
1250: 2a 20 74 68 65 72 65 20 61 72 65 20 74 77 6f 20  * there are two 
1260: 54 65 73 74 76 66 73 46 69 6c 65 20 73 74 72 75  TestvfsFile stru
1270: 63 74 75 72 65 73 20 62 75 74 20 6f 6e 6c 79 20  ctures but only 
1280: 6f 6e 65 20 54 65 73 74 76 66 73 42 75 66 66 65  one TestvfsBuffe
1290: 72 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a  r structure..*/.
12a0: 73 74 72 75 63 74 20 54 65 73 74 76 66 73 42 75  struct TestvfsBu
12b0: 66 66 65 72 20 7b 0a 20 20 63 68 61 72 20 2a 7a  ffer {.  char *z
12c0: 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20  File;           
12d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 73 73 6f           /* Asso
12e0: 63 69 61 74 65 64 20 66 69 6c 65 20 6e 61 6d 65  ciated file name
12f0: 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 3b 20   */.  int pgsz; 
1300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1310: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
1320: 7a 65 20 2a 2f 0a 20 20 75 38 20 2a 61 50 61 67  ze */.  u8 *aPag
1330: 65 5b 54 45 53 54 56 46 53 5f 4d 41 58 5f 50 41  e[TESTVFS_MAX_PA
1340: 47 45 53 5d 3b 20 20 20 2f 2a 20 41 72 72 61 79  GES];   /* Array
1350: 20 6f 66 20 63 6b 61 6c 6c 6f 63 27 64 20 70 61   of ckalloc'd pa
1360: 67 65 73 20 2a 2f 0a 20 20 54 65 73 74 76 66 73  ges */.  Testvfs
1370: 46 64 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20  Fd *pFile;      
1380: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74           /* List
1390: 20 6f 66 20 6f 70 65 6e 20 68 61 6e 64 6c 65 73   of open handles
13a0: 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 42 75 66   */.  TestvfsBuf
13b0: 66 65 72 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  fer *pNext;     
13c0: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69 6e        /* Next in
13d0: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
13e0: 61 6c 6c 20 62 75 66 66 65 72 73 20 2a 2f 0a 7d  all buffers */.}
13f0: 3b 0a 0a 0a 23 64 65 66 69 6e 65 20 50 41 52 45  ;...#define PARE
1400: 4e 54 56 46 53 28 78 29 20 28 28 28 54 65 73 74  NTVFS(x) (((Test
1410: 76 66 73 20 2a 29 28 28 78 29 2d 3e 70 41 70 70  vfs *)((x)->pApp
1420: 44 61 74 61 29 29 2d 3e 70 50 61 72 65 6e 74 29  Data))->pParent)
1430: 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  ..#define TESTVF
1440: 53 5f 4d 41 58 5f 41 52 47 53 20 31 32 0a 0a 0a  S_MAX_ARGS 12...
1450: 2f 2a 0a 2a 2a 20 4d 65 74 68 6f 64 20 64 65 63  /*.** Method dec
1460: 6c 61 72 61 74 69 6f 6e 73 20 66 6f 72 20 54 65  larations for Te
1470: 73 74 76 66 73 46 69 6c 65 2e 0a 2a 2f 0a 73 74  stvfsFile..*/.st
1480: 61 74 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f  atic int tvfsClo
1490: 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  se(sqlite3_file*
14a0: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
14b0: 66 73 52 65 61 64 28 73 71 6c 69 74 65 33 5f 66  fsRead(sqlite3_f
14c0: 69 6c 65 2a 2c 20 76 6f 69 64 2a 2c 20 69 6e 74  ile*, void*, int
14d0: 20 69 41 6d 74 2c 20 73 71 6c 69 74 65 33 5f 69   iAmt, sqlite3_i
14e0: 6e 74 36 34 20 69 4f 66 73 74 29 3b 0a 73 74 61  nt64 iOfst);.sta
14f0: 74 69 63 20 69 6e 74 20 74 76 66 73 57 72 69 74  tic int tvfsWrit
1500: 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  e(sqlite3_file*,
1510: 63 6f 6e 73 74 20 76 6f 69 64 2a 2c 69 6e 74 20  const void*,int 
1520: 69 41 6d 74 2c 20 73 71 6c 69 74 65 33 5f 69 6e  iAmt, sqlite3_in
1530: 74 36 34 20 69 4f 66 73 74 29 3b 0a 73 74 61 74  t64 iOfst);.stat
1540: 69 63 20 69 6e 74 20 74 76 66 73 54 72 75 6e 63  ic int tvfsTrunc
1550: 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ate(sqlite3_file
1560: 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  *, sqlite3_int64
1570: 20 73 69 7a 65 29 3b 0a 73 74 61 74 69 63 20 69   size);.static i
1580: 6e 74 20 74 76 66 73 53 79 6e 63 28 73 71 6c 69  nt tvfsSync(sqli
1590: 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 20 66  te3_file*, int f
15a0: 6c 61 67 73 29 3b 0a 73 74 61 74 69 63 20 69 6e  lags);.static in
15b0: 74 20 74 76 66 73 46 69 6c 65 53 69 7a 65 28 73  t tvfsFileSize(s
15c0: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 73 71  qlite3_file*, sq
15d0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 53 69  lite3_int64 *pSi
15e0: 7a 65 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  ze);.static int 
15f0: 74 76 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33  tvfsLock(sqlite3
1600: 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a 73 74  _file*, int);.st
1610: 61 74 69 63 20 69 6e 74 20 74 76 66 73 55 6e 6c  atic int tvfsUnl
1620: 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ock(sqlite3_file
1630: 2a 2c 20 69 6e 74 29 3b 0a 73 74 61 74 69 63 20  *, int);.static 
1640: 69 6e 74 20 74 76 66 73 43 68 65 63 6b 52 65 73  int tvfsCheckRes
1650: 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65  ervedLock(sqlite
1660: 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 20 2a 29 3b  3_file*, int *);
1670: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
1680: 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c 69  FileControl(sqli
1690: 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 20 6f  te3_file*, int o
16a0: 70 2c 20 76 6f 69 64 20 2a 70 41 72 67 29 3b 0a  p, void *pArg);.
16b0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
16c0: 65 63 74 6f 72 53 69 7a 65 28 73 71 6c 69 74 65  ectorSize(sqlite
16d0: 33 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63  3_file*);.static
16e0: 20 69 6e 74 20 74 76 66 73 44 65 76 69 63 65 43   int tvfsDeviceC
16f0: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28 73  haracteristics(s
1700: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 0a  qlite3_file*);..
1710: 2f 2a 0a 2a 2a 20 4d 65 74 68 6f 64 20 64 65 63  /*.** Method dec
1720: 6c 61 72 61 74 69 6f 6e 73 20 66 6f 72 20 74 76  larations for tv
1730: 66 73 5f 76 66 73 2e 0a 2a 2f 0a 73 74 61 74 69  fs_vfs..*/.stati
1740: 63 20 69 6e 74 20 74 76 66 73 4f 70 65 6e 28 73  c int tvfsOpen(s
1750: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 63 6f 6e  qlite3_vfs*, con
1760: 73 74 20 63 68 61 72 20 2a 2c 20 73 71 6c 69 74  st char *, sqlit
1770: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 20 2c 20  e3_file*, int , 
1780: 69 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69  int *);.static i
1790: 6e 74 20 74 76 66 73 44 65 6c 65 74 65 28 73 71  nt tvfsDelete(sq
17a0: 6c 69 74 65 33 5f 76 66 73 2a 2c 20 63 6f 6e 73  lite3_vfs*, cons
17b0: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 69  t char *zName, i
17c0: 6e 74 20 73 79 6e 63 44 69 72 29 3b 0a 73 74 61  nt syncDir);.sta
17d0: 74 69 63 20 69 6e 74 20 74 76 66 73 41 63 63 65  tic int tvfsAcce
17e0: 73 73 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  ss(sqlite3_vfs*,
17f0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
1800: 6d 65 2c 20 69 6e 74 20 66 6c 61 67 73 2c 20 69  me, int flags, i
1810: 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  nt *);.static in
1820: 74 20 74 76 66 73 46 75 6c 6c 50 61 74 68 6e 61  t tvfsFullPathna
1830: 6d 65 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  me(sqlite3_vfs*,
1840: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
1850: 6d 65 2c 20 69 6e 74 2c 20 63 68 61 72 20 2a 7a  me, int, char *z
1860: 4f 75 74 29 3b 0a 23 69 66 6e 64 65 66 20 53 51  Out);.#ifndef SQ
1870: 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45  LITE_OMIT_LOAD_E
1880: 58 54 45 4e 53 49 4f 4e 0a 73 74 61 74 69 63 20  XTENSION.static 
1890: 76 6f 69 64 20 2a 74 76 66 73 44 6c 4f 70 65 6e  void *tvfsDlOpen
18a0: 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 63  (sqlite3_vfs*, c
18b0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65  onst char *zFile
18c0: 6e 61 6d 65 29 3b 0a 73 74 61 74 69 63 20 76 6f  name);.static vo
18d0: 69 64 20 74 76 66 73 44 6c 45 72 72 6f 72 28 73  id tvfsDlError(s
18e0: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 69 6e 74  qlite3_vfs*, int
18f0: 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a 7a 45   nByte, char *zE
1900: 72 72 4d 73 67 29 3b 0a 73 74 61 74 69 63 20 76  rrMsg);.static v
1910: 6f 69 64 20 28 2a 74 76 66 73 44 6c 53 79 6d 28  oid (*tvfsDlSym(
1920: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 76 6f 69  sqlite3_vfs*,voi
1930: 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  d*, const char *
1940: 7a 53 79 6d 62 6f 6c 29 29 28 76 6f 69 64 29 3b  zSymbol))(void);
1950: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66  .static void tvf
1960: 73 44 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  sDlClose(sqlite3
1970: 5f 76 66 73 2a 2c 20 76 6f 69 64 2a 29 3b 0a 23  _vfs*, void*);.#
1980: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
1990: 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53  OMIT_LOAD_EXTENS
19a0: 49 4f 4e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ION */.static in
19b0: 74 20 74 76 66 73 52 61 6e 64 6f 6d 6e 65 73 73  t tvfsRandomness
19c0: 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 69  (sqlite3_vfs*, i
19d0: 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a  nt nByte, char *
19e0: 7a 4f 75 74 29 3b 0a 73 74 61 74 69 63 20 69 6e  zOut);.static in
19f0: 74 20 74 76 66 73 53 6c 65 65 70 28 73 71 6c 69  t tvfsSleep(sqli
1a00: 74 65 33 5f 76 66 73 2a 2c 20 69 6e 74 20 6d 69  te3_vfs*, int mi
1a10: 63 72 6f 73 65 63 6f 6e 64 73 29 3b 0a 73 74 61  croseconds);.sta
1a20: 74 69 63 20 69 6e 74 20 74 76 66 73 43 75 72 72  tic int tvfsCurr
1a30: 65 6e 74 54 69 6d 65 28 73 71 6c 69 74 65 33 5f  entTime(sqlite3_
1a40: 76 66 73 2a 2c 20 64 6f 75 62 6c 65 2a 29 3b 0a  vfs*, double*);.
1a50: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
1a60: 53 68 6d 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  ShmOpen(sqlite3_
1a70: 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20 69  file*);.static i
1a80: 6e 74 20 74 76 66 73 53 68 6d 4c 6f 63 6b 28 73  nt tvfsShmLock(s
1a90: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e  qlite3_file*, in
1aa0: 74 20 2c 20 69 6e 74 2c 20 69 6e 74 29 3b 0a 73  t , int, int);.s
1ab0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68  tatic int tvfsSh
1ac0: 6d 4d 61 70 28 73 71 6c 69 74 65 33 5f 66 69 6c  mMap(sqlite3_fil
1ad0: 65 2a 2c 69 6e 74 2c 69 6e 74 2c 69 6e 74 2c 20  e*,int,int,int, 
1ae0: 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a  void volatile **
1af0: 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74  );.static void t
1b00: 76 66 73 53 68 6d 42 61 72 72 69 65 72 28 73 71  vfsShmBarrier(sq
1b10: 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73 74  lite3_file*);.st
1b20: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
1b30: 55 6e 6d 61 70 28 73 71 6c 69 74 65 33 5f 66 69  Unmap(sqlite3_fi
1b40: 6c 65 2a 2c 20 69 6e 74 29 3b 0a 0a 73 74 61 74  le*, int);..stat
1b50: 69 63 20 69 6e 74 20 74 76 66 73 46 65 74 63 68  ic int tvfsFetch
1b60: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
1b70: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 2c 20 69  sqlite3_int64, i
1b80: 6e 74 2c 20 76 6f 69 64 2a 2a 29 3b 0a 73 74 61  nt, void**);.sta
1b90: 74 69 63 20 69 6e 74 20 74 76 66 73 55 6e 66 65  tic int tvfsUnfe
1ba0: 74 63 68 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  tch(sqlite3_file
1bb0: 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  *, sqlite3_int64
1bc0: 2c 20 76 6f 69 64 2a 29 3b 0a 0a 73 74 61 74 69  , void*);..stati
1bd0: 63 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74  c sqlite3_io_met
1be0: 68 6f 64 73 20 74 76 66 73 5f 69 6f 5f 6d 65 74  hods tvfs_io_met
1bf0: 68 6f 64 73 20 3d 20 7b 0a 20 20 33 2c 20 20 20  hods = {.  3,   
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
1c20: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 74 76 66 73  ersion */.  tvfs
1c30: 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20  Close,          
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1c50: 43 6c 6f 73 65 20 2a 2f 0a 20 20 74 76 66 73 52  Close */.  tvfsR
1c60: 65 61 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  ead,            
1c70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
1c80: 65 61 64 20 2a 2f 0a 20 20 74 76 66 73 57 72 69  ead */.  tvfsWri
1c90: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
1ca0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 57 72 69           /* xWri
1cb0: 74 65 20 2a 2f 0a 20 20 74 76 66 73 54 72 75 6e  te */.  tvfsTrun
1cc0: 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  cate,           
1cd0: 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72 75 6e          /* xTrun
1ce0: 63 61 74 65 20 2a 2f 0a 20 20 74 76 66 73 53 79  cate */.  tvfsSy
1cf0: 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  nc,             
1d00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79            /* xSy
1d10: 6e 63 20 2a 2f 0a 20 20 74 76 66 73 46 69 6c 65  nc */.  tvfsFile
1d20: 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20  Size,           
1d30: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 65          /* xFile
1d40: 53 69 7a 65 20 2a 2f 0a 20 20 74 76 66 73 4c 6f  Size */.  tvfsLo
1d50: 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ck,             
1d60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4c 6f            /* xLo
1d70: 63 6b 20 2a 2f 0a 20 20 74 76 66 73 55 6e 6c 6f  ck */.  tvfsUnlo
1d80: 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ck,             
1d90: 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 6c 6f          /* xUnlo
1da0: 63 6b 20 2a 2f 0a 20 20 74 76 66 73 43 68 65 63  ck */.  tvfsChec
1db0: 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 2c 20 20  kReservedLock,  
1dc0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 68 65 63          /* xChec
1dd0: 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 20 2a 2f  kReservedLock */
1de0: 0a 20 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72  .  tvfsFileContr
1df0: 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ol,             
1e00: 20 20 20 2f 2a 20 78 46 69 6c 65 43 6f 6e 74 72     /* xFileContr
1e10: 6f 6c 20 2a 2f 0a 20 20 74 76 66 73 53 65 63 74  ol */.  tvfsSect
1e20: 6f 72 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20  orSize,         
1e30: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 65 63 74          /* xSect
1e40: 6f 72 53 69 7a 65 20 2a 2f 0a 20 20 74 76 66 73  orSize */.  tvfs
1e50: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
1e60: 73 74 69 63 73 2c 20 20 20 20 20 20 2f 2a 20 78  stics,      /* x
1e70: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
1e80: 73 74 69 63 73 20 2a 2f 0a 20 20 74 76 66 73 53  stics */.  tvfsS
1e90: 68 6d 4d 61 70 2c 20 20 20 20 20 20 20 20 20 20  hmMap,          
1ea0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
1eb0: 68 6d 4d 61 70 20 2a 2f 0a 20 20 74 76 66 73 53  hmMap */.  tvfsS
1ec0: 68 6d 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20  hmLock,         
1ed0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
1ee0: 68 6d 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73  hmLock */.  tvfs
1ef0: 53 68 6d 42 61 72 72 69 65 72 2c 20 20 20 20 20  ShmBarrier,     
1f00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1f10: 53 68 6d 42 61 72 72 69 65 72 20 2a 2f 0a 20 20  ShmBarrier */.  
1f20: 74 76 66 73 53 68 6d 55 6e 6d 61 70 2c 20 20 20  tvfsShmUnmap,   
1f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f40: 2f 2a 20 78 53 68 6d 55 6e 6d 61 70 20 2a 2f 0a  /* xShmUnmap */.
1f50: 20 20 74 76 66 73 46 65 74 63 68 2c 0a 20 20 74    tvfsFetch,.  t
1f60: 76 66 73 55 6e 66 65 74 63 68 0a 7d 3b 0a 0a 73  vfsUnfetch.};..s
1f70: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 65  tatic int tvfsRe
1f80: 73 75 6c 74 43 6f 64 65 28 54 65 73 74 76 66 73  sultCode(Testvfs
1f90: 20 2a 70 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a   *p, int *pRc){.
1fa0: 20 20 73 74 72 75 63 74 20 65 72 72 63 6f 64 65    struct errcode
1fb0: 20 7b 0a 20 20 20 20 69 6e 74 20 65 43 6f 64 65   {.    int eCode
1fc0: 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  ;.    const char
1fd0: 20 2a 7a 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f   *zCode;.  } aCo
1fe0: 64 65 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53  de[] = {.    { S
1ff0: 51 4c 49 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53  QLITE_OK,     "S
2000: 51 4c 49 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c  QLITE_OK"     },
2010: 0a 20 20 20 20 7b 20 53 51 4c 49 54 45 5f 45 52  .    { SQLITE_ER
2020: 52 4f 52 2c 20 20 22 53 51 4c 49 54 45 5f 45 52  ROR,  "SQLITE_ER
2030: 52 4f 52 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53  ROR"  },.    { S
2040: 51 4c 49 54 45 5f 49 4f 45 52 52 2c 20 20 22 53  QLITE_IOERR,  "S
2050: 51 4c 49 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c  QLITE_IOERR"  },
2060: 0a 20 20 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f  .    { SQLITE_LO
2070: 43 4b 45 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f  CKED, "SQLITE_LO
2080: 43 4b 45 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53  CKED" },.    { S
2090: 51 4c 49 54 45 5f 42 55 53 59 2c 20 20 20 22 53  QLITE_BUSY,   "S
20a0: 51 4c 49 54 45 5f 42 55 53 59 22 20 20 20 7d 2c  QLITE_BUSY"   },
20b0: 0a 20 20 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63  .  };..  const c
20c0: 68 61 72 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b  har *z;.  int i;
20d0: 0a 0a 20 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53  ..  z = Tcl_GetS
20e0: 74 72 69 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69  tringResult(p->i
20f0: 6e 74 65 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d  nterp);.  for(i=
2100: 30 3b 20 69 3c 41 72 72 61 79 53 69 7a 65 28 61  0; i<ArraySize(a
2110: 43 6f 64 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  Code); i++){.   
2120: 20 69 66 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a   if( 0==strcmp(z
2130: 2c 20 61 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65  , aCode[i].zCode
2140: 29 20 29 7b 0a 20 20 20 20 20 20 2a 70 52 63 20  ) ){.      *pRc 
2150: 3d 20 61 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65  = aCode[i].eCode
2160: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 31  ;.      return 1
2170: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
2180: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74  eturn 0;.}..stat
2190: 69 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63  ic int tvfsInjec
21a0: 74 46 61 75 6c 74 28 54 65 73 74 46 61 75 6c 74  tFault(TestFault
21b0: 49 6e 6a 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e  Inject *p){.  in
21c0: 74 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66 28  t ret = 0;.  if(
21d0: 20 70 2d 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20   p->eFault ){.  
21e0: 20 20 70 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20    p->iCnt--;.   
21f0: 20 69 66 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20   if( p->iCnt==0 
2200: 7c 7c 20 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26  || (p->iCnt<0 &&
2210: 20 70 2d 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c   p->eFault==FAUL
2220: 54 5f 49 4e 4a 45 43 54 5f 50 45 52 53 49 53 54  T_INJECT_PERSIST
2230: 45 4e 54 20 29 20 29 7b 0a 20 20 20 20 20 20 72  ENT ) ){.      r
2240: 65 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d  et = 1;.      p-
2250: 3e 6e 46 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a  >nFail++;.    }.
2260: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65 74    }.  return ret
2270: 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74  ;.}...static int
2280: 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72   tvfsInjectIoerr
2290: 28 54 65 73 74 76 66 73 20 2a 70 29 7b 0a 20 20  (Testvfs *p){.  
22a0: 72 65 74 75 72 6e 20 74 76 66 73 49 6e 6a 65 63  return tvfsInjec
22b0: 74 46 61 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72  tFault(&p->ioerr
22c0: 5f 65 72 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  _err);.}..static
22d0: 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46   int tvfsInjectF
22e0: 75 6c 6c 65 72 72 28 54 65 73 74 76 66 73 20 2a  ullerr(Testvfs *
22f0: 70 29 7b 0a 20 20 72 65 74 75 72 6e 20 74 76 66  p){.  return tvf
2300: 73 49 6e 6a 65 63 74 46 61 75 6c 74 28 26 70 2d  sInjectFault(&p-
2310: 3e 66 75 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74  >full_err);.}.st
2320: 61 74 69 63 20 69 6e 74 20 74 76 66 73 49 6e 6a  atic int tvfsInj
2330: 65 63 74 43 61 6e 74 6f 70 65 6e 65 72 72 28 54  ectCantopenerr(T
2340: 65 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65  estvfs *p){.  re
2350: 74 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46  turn tvfsInjectF
2360: 61 75 6c 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65  ault(&p->cantope
2370: 6e 5f 65 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74  n_err);.}...stat
2380: 69 63 20 76 6f 69 64 20 74 76 66 73 45 78 65 63  ic void tvfsExec
2390: 54 63 6c 28 0a 20 20 54 65 73 74 76 66 73 20 2a  Tcl(.  Testvfs *
23a0: 70 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  p, .  const char
23b0: 20 2a 7a 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c   *zMethod,.  Tcl
23c0: 5f 4f 62 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63  _Obj *arg1,.  Tc
23d0: 6c 5f 4f 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54  l_Obj *arg2,.  T
23e0: 63 6c 5f 4f 62 6a 20 2a 61 72 67 33 2c 0a 20 20  cl_Obj *arg3,.  
23f0: 54 63 6c 5f 4f 62 6a 20 2a 61 72 67 34 0a 29 7b  Tcl_Obj *arg4.){
2400: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
2410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2420: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
2430: 65 20 66 72 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f  e from Tcl_EvalO
2440: 62 6a 28 29 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  bj() */.  Tcl_Ob
2450: 6a 20 2a 70 45 76 61 6c 3b 0a 20 20 61 73 73 65  j *pEval;.  asse
2460: 72 74 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29  rt( p->pScript )
2470: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 7a 4d 65  ;..  assert( zMe
2480: 74 68 6f 64 20 29 3b 0a 20 20 61 73 73 65 72 74  thod );.  assert
2490: 28 20 70 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ( p );.  assert(
24a0: 20 61 72 67 32 3d 3d 30 20 7c 7c 20 61 72 67 31   arg2==0 || arg1
24b0: 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  !=0 );.  assert(
24c0: 20 61 72 67 33 3d 3d 30 20 7c 7c 20 61 72 67 32   arg3==0 || arg2
24d0: 21 3d 30 20 29 3b 0a 0a 20 20 70 45 76 61 6c 20  !=0 );..  pEval 
24e0: 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65 4f  = Tcl_DuplicateO
24f0: 62 6a 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a  bj(p->pScript);.
2500: 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75    Tcl_IncrRefCou
2510: 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a  nt(p->pScript);.
2520: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
2530: 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e  endElement(p->in
2540: 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 54 63 6c  terp, pEval, Tcl
2550: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 4d  _NewStringObj(zM
2560: 65 74 68 6f 64 2c 20 2d 31 29 29 3b 0a 20 20 69  ethod, -1));.  i
2570: 66 28 20 61 72 67 31 20 29 20 54 63 6c 5f 4c 69  f( arg1 ) Tcl_Li
2580: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
2590: 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45  nt(p->interp, pE
25a0: 76 61 6c 2c 20 61 72 67 31 29 3b 0a 20 20 69 66  val, arg1);.  if
25b0: 28 20 61 72 67 32 20 29 20 54 63 6c 5f 4c 69 73  ( arg2 ) Tcl_Lis
25c0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
25d0: 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76  t(p->interp, pEv
25e0: 61 6c 2c 20 61 72 67 32 29 3b 0a 20 20 69 66 28  al, arg2);.  if(
25f0: 20 61 72 67 33 20 29 20 54 63 6c 5f 4c 69 73 74   arg3 ) Tcl_List
2600: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
2610: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61  (p->interp, pEva
2620: 6c 2c 20 61 72 67 33 29 3b 0a 20 20 69 66 28 20  l, arg3);.  if( 
2630: 61 72 67 34 20 29 20 54 63 6c 5f 4c 69 73 74 4f  arg4 ) Tcl_ListO
2640: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2650: 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c  p->interp, pEval
2660: 2c 20 61 72 67 34 29 3b 0a 0a 20 20 72 63 20 3d  , arg4);..  rc =
2670: 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 70   Tcl_EvalObjEx(p
2680: 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  ->interp, pEval,
2690: 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c   TCL_EVAL_GLOBAL
26a0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c  );.  if( rc!=TCL
26b0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42  _OK ){.    Tcl_B
26c0: 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70  ackgroundError(p
26d0: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54  ->interp);.    T
26e0: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70  cl_ResetResult(p
26f0: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 7d  ->interp);.  }.}
2700: 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  .../*.** Close a
2710: 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a  n tvfs-file..*/.
2720: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43  static int tvfsC
2730: 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  lose(sqlite3_fil
2740: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74  e *pFile){.  int
2750: 20 72 63 3b 0a 20 20 54 65 73 74 76 66 73 46 69   rc;.  TestvfsFi
2760: 6c 65 20 2a 70 54 65 73 74 66 69 6c 65 20 3d 20  le *pTestfile = 
2770: 28 54 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70  (TestvfsFile *)p
2780: 46 69 6c 65 3b 0a 20 20 54 65 73 74 76 66 73 46  File;.  TestvfsF
2790: 64 20 2a 70 46 64 20 3d 20 70 54 65 73 74 66 69  d *pFd = pTestfi
27a0: 6c 65 2d 3e 70 46 64 3b 0a 20 20 54 65 73 74 76  le->pFd;.  Testv
27b0: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
27c0: 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41   *)pFd->pVfs->pA
27d0: 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70  ppData;..  if( p
27e0: 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e  ->pScript && p->
27f0: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 43 4c 4f  mask&TESTVFS_CLO
2800: 53 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74  SE_MASK ){.    t
2810: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
2820: 43 6c 6f 73 65 22 2c 20 0a 20 20 20 20 20 20 20  Close", .       
2830: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
2840: 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65  j(pFd->zFilename
2850: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
2860: 49 64 2c 20 30 2c 20 30 0a 20 20 20 20 29 3b 0a  Id, 0, 0.    );.
2870: 20 20 7d 0a 0a 20 20 69 66 28 20 70 46 64 2d 3e    }..  if( pFd->
2880: 70 53 68 6d 49 64 20 29 7b 0a 20 20 20 20 54 63  pShmId ){.    Tc
2890: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
28a0: 46 64 2d 3e 70 53 68 6d 49 64 29 3b 0a 20 20 20  Fd->pShmId);.   
28b0: 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d 20 30   pFd->pShmId = 0
28c0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 46 69 6c  ;.  }.  if( pFil
28d0: 65 2d 3e 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20  e->pMethods ){. 
28e0: 20 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20     ckfree((char 
28f0: 2a 29 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64  *)pFile->pMethod
2900: 73 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73  s);.  }.  rc = s
2910: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70 46  qlite3OsClose(pF
2920: 64 2d 3e 70 52 65 61 6c 29 3b 0a 20 20 63 6b 66  d->pReal);.  ckf
2930: 72 65 65 28 28 63 68 61 72 20 2a 29 70 46 64 29  ree((char *)pFd)
2940: 3b 0a 20 20 70 54 65 73 74 66 69 6c 65 2d 3e 70  ;.  pTestfile->p
2950: 46 64 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  Fd = 0;.  return
2960: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
2970: 61 64 20 64 61 74 61 20 66 72 6f 6d 20 61 6e 20  ad data from an 
2980: 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74  tvfs-file..*/.st
2990: 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 65 61  atic int tvfsRea
29a0: 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  d(.  sqlite3_fil
29b0: 65 20 2a 70 46 69 6c 65 2c 20 0a 20 20 76 6f 69  e *pFile, .  voi
29c0: 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74 20  d *zBuf, .  int 
29d0: 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65 5f  iAmt, .  sqlite_
29e0: 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a 20  int64 iOfst.){. 
29f0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2a00: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
2a10: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
2a20: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
2a30: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
2a40: 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70  s *)pFd->pVfs->p
2a50: 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20 70  AppData;.  if( p
2a60: 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e  ->pScript && p->
2a70: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 52 45 41  mask&TESTVFS_REA
2a80: 44 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76  D_MASK ){.    tv
2a90: 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 52  fsExecTcl(p, "xR
2aa0: 65 61 64 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ead", .        T
2ab0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2ac0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
2ad0: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
2ae0: 2c 20 30 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20  , 0, 0.    );.  
2af0: 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65    tvfsResultCode
2b00: 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20  (p, &rc);.  }.  
2b10: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2b20: 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  K && p->mask&TES
2b30: 54 56 46 53 5f 52 45 41 44 5f 4d 41 53 4b 20 26  TVFS_READ_MASK &
2b40: 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72  & tvfsInjectIoer
2b50: 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d  r(p) ){.    rc =
2b60: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20   SQLITE_IOERR;. 
2b70: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
2b80: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
2b90: 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64   = sqlite3OsRead
2ba0: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a 42 75  (pFd->pReal, zBu
2bb0: 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b  f, iAmt, iOfst);
2bc0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
2bd0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  ;.}../*.** Write
2be0: 20 64 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73   data to an tvfs
2bf0: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
2c00: 20 69 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a   int tvfsWrite(.
2c10: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
2c20: 70 46 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20  pFile, .  const 
2c30: 76 6f 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69  void *zBuf, .  i
2c40: 6e 74 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69  nt iAmt, .  sqli
2c50: 74 65 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29  te_int64 iOfst.)
2c60: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
2c70: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
2c80: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
2c90: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
2ca0: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
2cb0: 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73  tvfs *)pFd->pVfs
2cc0: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69  ->pAppData;..  i
2cd0: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
2ce0: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
2cf0: 5f 57 52 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20  _WRITE_MASK ){. 
2d00: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
2d10: 2c 20 22 78 57 72 69 74 65 22 2c 20 0a 20 20 20  , "xWrite", .   
2d20: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
2d30: 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65  ngObj(pFd->zFile
2d40: 6e 61 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e  name, -1), pFd->
2d50: 70 53 68 6d 49 64 2c 20 0a 20 20 20 20 20 20 20  pShmId, .       
2d60: 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f   Tcl_NewWideIntO
2d70: 62 6a 28 69 4f 66 73 74 29 2c 20 54 63 6c 5f 4e  bj(iOfst), Tcl_N
2d80: 65 77 49 6e 74 4f 62 6a 28 69 41 6d 74 29 0a 20  ewIntObj(iAmt). 
2d90: 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65     );.    tvfsRe
2da0: 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29  sultCode(p, &rc)
2db0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
2dc0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 74 76  =SQLITE_OK && tv
2dd0: 66 73 49 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28  fsInjectFullerr(
2de0: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  p) ){.    rc = S
2df0: 51 4c 49 54 45 5f 46 55 4c 4c 3b 0a 20 20 7d 0a  QLITE_FULL;.  }.
2e00: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2e10: 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  _OK && p->mask&T
2e20: 45 53 54 56 46 53 5f 57 52 49 54 45 5f 4d 41 53  ESTVFS_WRITE_MAS
2e30: 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49  K && tvfsInjectI
2e40: 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72  oerr(p) ){.    r
2e50: 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52  c = SQLITE_IOERR
2e60: 3b 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 72  ;.  }.  .  if( r
2e70: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
2e80: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
2e90: 4f 73 57 72 69 74 65 28 70 46 64 2d 3e 70 52 65  OsWrite(pFd->pRe
2ea0: 61 6c 2c 20 7a 42 75 66 2c 20 69 41 6d 74 2c 20  al, zBuf, iAmt, 
2eb0: 69 4f 66 73 74 29 3b 0a 20 20 7d 0a 20 20 72 65  iOfst);.  }.  re
2ec0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
2ed0: 2a 20 54 72 75 6e 63 61 74 65 20 61 6e 20 74 76  * Truncate an tv
2ee0: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
2ef0: 69 63 20 69 6e 74 20 74 76 66 73 54 72 75 6e 63  ic int tvfsTrunc
2f00: 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ate(sqlite3_file
2f10: 20 2a 70 46 69 6c 65 2c 20 73 71 6c 69 74 65 5f   *pFile, sqlite_
2f20: 69 6e 74 36 34 20 73 69 7a 65 29 7b 0a 20 20 69  int64 size){.  i
2f30: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2f40: 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  K;.  TestvfsFd *
2f50: 70 46 64 20 3d 20 74 76 66 73 47 65 74 46 64 28  pFd = tvfsGetFd(
2f60: 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66  pFile);.  Testvf
2f70: 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20  s *p = (Testvfs 
2f80: 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70  *)pFd->pVfs->pAp
2f90: 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d  pData;..  if( p-
2fa0: 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d  >pScript && p->m
2fb0: 61 73 6b 26 54 45 53 54 56 46 53 5f 54 52 55 4e  ask&TESTVFS_TRUN
2fc0: 43 41 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  CATE_MASK ){.   
2fd0: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
2fe0: 22 78 54 72 75 6e 63 61 74 65 22 2c 20 0a 20 20  "xTruncate", .  
2ff0: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
3000: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c  ingObj(pFd->zFil
3010: 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d  ename, -1), pFd-
3020: 3e 70 53 68 6d 49 64 2c 20 30 2c 20 30 0a 20 20  >pShmId, 0, 0.  
3030: 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73    );.    tvfsRes
3040: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b  ultCode(p, &rc);
3050: 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 72 63  .  }.  .  if( rc
3060: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
3070: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
3080: 73 54 72 75 6e 63 61 74 65 28 70 46 64 2d 3e 70  sTruncate(pFd->p
3090: 52 65 61 6c 2c 20 73 69 7a 65 29 3b 0a 20 20 7d  Real, size);.  }
30a0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
30b0: 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 61 6e 20 74  ./*.** Sync an t
30c0: 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  vfs-file..*/.sta
30d0: 74 69 63 20 69 6e 74 20 74 76 66 73 53 79 6e 63  tic int tvfsSync
30e0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
30f0: 46 69 6c 65 2c 20 69 6e 74 20 66 6c 61 67 73 29  File, int flags)
3100: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
3110: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
3120: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
3130: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
3140: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
3150: 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73  tvfs *)pFd->pVfs
3160: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69  ->pAppData;..  i
3170: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
3180: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
3190: 5f 53 59 4e 43 5f 4d 41 53 4b 20 29 7b 0a 20 20  _SYNC_MASK ){.  
31a0: 20 20 63 68 61 72 20 2a 7a 46 6c 61 67 73 20 3d    char *zFlags =
31b0: 20 30 3b 0a 0a 20 20 20 20 73 77 69 74 63 68 28   0;..    switch(
31c0: 20 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20 20   flags ){.      
31d0: 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43  case SQLITE_SYNC
31e0: 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20 20 20 20 20  _NORMAL:.       
31f0: 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72 6d 61   zFlags = "norma
3200: 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  l";.        brea
3210: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  k;.      case SQ
3220: 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 3a 0a  LITE_SYNC_FULL:.
3230: 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d          zFlags =
3240: 20 22 66 75 6c 6c 22 3b 0a 20 20 20 20 20 20 20   "full";.       
3250: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61   break;.      ca
3260: 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4e  se SQLITE_SYNC_N
3270: 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53 59 4e  ORMAL|SQLITE_SYN
3280: 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20 20 20  C_DATAONLY:.    
3290: 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f      zFlags = "no
32a0: 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c 79 22 3b 0a  rmal|dataonly";.
32b0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
32c0: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
32d0: 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53 51 4c 49 54  _SYNC_FULL|SQLIT
32e0: 45 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a  E_SYNC_DATAONLY:
32f0: 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73 20  .        zFlags 
3300: 3d 20 22 66 75 6c 6c 7c 64 61 74 61 6f 6e 6c 79  = "full|dataonly
3310: 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  ";.        break
3320: 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a  ;.      default:
3330: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
3340: 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 74  0);.    }..    t
3350: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
3360: 53 79 6e 63 22 2c 20 0a 20 20 20 20 20 20 20 20  Sync", .        
3370: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
3380: 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c  (pFd->zFilename,
3390: 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49   -1), pFd->pShmI
33a0: 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e  d,.        Tcl_N
33b0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 46 6c 61  ewStringObj(zFla
33c0: 67 73 2c 20 2d 31 29 2c 20 30 0a 20 20 20 20 29  gs, -1), 0.    )
33d0: 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74  ;.    tvfsResult
33e0: 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20  Code(p, &rc);.  
33f0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
3400: 49 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e  ITE_OK && tvfsIn
3410: 6a 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29  jectFullerr(p) )
3420: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c   rc = SQLITE_FUL
3430: 4c 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  L;..  if( rc==SQ
3440: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
3450: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e  c = sqlite3OsSyn
3460: 63 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c  c(pFd->pReal, fl
3470: 61 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  ags);.  }..  ret
3480: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3490: 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 72   Return the curr
34a0: 65 6e 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f 66  ent file-size of
34b0: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
34c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
34d0: 73 46 69 6c 65 53 69 7a 65 28 73 71 6c 69 74 65  sFileSize(sqlite
34e0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73  3_file *pFile, s
34f0: 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53 69  qlite_int64 *pSi
3500: 7a 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  ze){.  TestvfsFd
3510: 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64 28   *p = tvfsGetFd(
3520: 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e  pFile);.  return
3530: 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69   sqlite3OsFileSi
3540: 7a 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69  ze(p->pReal, pSi
3550: 7a 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f  ze);.}../*.** Lo
3560: 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  ck an tvfs-file.
3570: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
3580: 76 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f  vfsLock(sqlite3_
3590: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74  file *pFile, int
35a0: 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76   eLock){.  Testv
35b0: 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73  fsFd *pFd = tvfs
35c0: 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20  GetFd(pFile);.  
35d0: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
35e0: 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66  stvfs *)pFd->pVf
35f0: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 69  s->pAppData;.  i
3600: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
3610: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
3620: 5f 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b 0a 20 20  _LOCK_MASK ){.  
3630: 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 33 30 5d    char zLock[30]
3640: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e  ;.    sqlite3_sn
3650: 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4c  printf(sizeof(zL
3660: 6f 63 6b 29 2c 7a 4c 6f 63 6b 2c 22 25 64 22 2c  ock),zLock,"%d",
3670: 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 74 76 66 73  eLock);.    tvfs
3680: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 4c 6f 63  ExecTcl(p, "xLoc
3690: 6b 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  k", Tcl_NewStrin
36a0: 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e  gObj(pFd->zFilen
36b0: 61 6d 65 2c 20 2d 31 29 2c 20 0a 20 20 20 20 20  ame, -1), .     
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
36d0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a  l_NewStringObj(z
36e0: 4c 6f 63 6b 2c 20 2d 31 29 2c 20 30 2c 20 30 29  Lock, -1), 0, 0)
36f0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
3700: 71 6c 69 74 65 33 4f 73 4c 6f 63 6b 28 70 46 64  qlite3OsLock(pFd
3710: 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63 6b 29 3b  ->pReal, eLock);
3720: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e 6c 6f 63 6b  .}../*.** Unlock
3730: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
3740: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
3750: 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f  sUnlock(sqlite3_
3760: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74  file *pFile, int
3770: 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76   eLock){.  Testv
3780: 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73  fsFd *pFd = tvfs
3790: 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20  GetFd(pFile);.  
37a0: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
37b0: 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66  stvfs *)pFd->pVf
37c0: 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 69  s->pAppData;.  i
37d0: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
37e0: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
37f0: 5f 55 4e 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b 0a  _UNLOCK_MASK ){.
3800: 20 20 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 33      char zLock[3
3810: 30 5d 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0];.    sqlite3_
3820: 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28  snprintf(sizeof(
3830: 7a 4c 6f 63 6b 29 2c 7a 4c 6f 63 6b 2c 22 25 64  zLock),zLock,"%d
3840: 22 2c 65 4c 6f 63 6b 29 3b 0a 20 20 20 20 74 76  ",eLock);.    tv
3850: 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 55  fsExecTcl(p, "xU
3860: 6e 6c 6f 63 6b 22 2c 20 54 63 6c 5f 4e 65 77 53  nlock", Tcl_NewS
3870: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46  tringObj(pFd->zF
3880: 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 0a 20  ilename, -1), . 
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
38b0: 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31 29 2c 20 30  bj(zLock, -1), 0
38c0: 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  , 0);.  }.  if( 
38d0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
38e0: 57 52 49 54 45 5f 4d 41 53 4b 20 26 26 20 74 76  WRITE_MASK && tv
38f0: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29  fsInjectIoerr(p)
3900: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
3910: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 55 4e 4c 4f  QLITE_IOERR_UNLO
3920: 43 4b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  CK;.  }.  return
3930: 20 73 71 6c 69 74 65 33 4f 73 55 6e 6c 6f 63 6b   sqlite3OsUnlock
3940: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f  (pFd->pReal, eLo
3950: 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68  ck);.}../*.** Ch
3960: 65 63 6b 20 69 66 20 61 6e 6f 74 68 65 72 20 66  eck if another f
3970: 69 6c 65 2d 68 61 6e 64 6c 65 20 68 6f 6c 64 73  ile-handle holds
3980: 20 61 20 52 45 53 45 52 56 45 44 20 6c 6f 63 6b   a RESERVED lock
3990: 20 6f 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c 65   on an tvfs-file
39a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
39b0: 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76 65  tvfsCheckReserve
39c0: 64 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  dLock(sqlite3_fi
39d0: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 2a  le *pFile, int *
39e0: 70 52 65 73 4f 75 74 29 7b 0a 20 20 54 65 73 74  pResOut){.  Test
39f0: 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66  vfsFd *pFd = tvf
3a00: 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20  sGetFd(pFile);. 
3a10: 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54   Testvfs *p = (T
3a20: 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56  estvfs *)pFd->pV
3a30: 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20  fs->pAppData;.  
3a40: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
3a50: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
3a60: 53 5f 43 4b 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b  S_CKLOCK_MASK ){
3a70: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
3a80: 28 70 2c 20 22 78 43 68 65 63 6b 52 65 73 65 72  (p, "xCheckReser
3a90: 76 65 64 4c 6f 63 6b 22 2c 20 54 63 6c 5f 4e 65  vedLock", Tcl_Ne
3aa0: 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e  wStringObj(pFd->
3ab0: 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 0a  zFilename, -1),.
3ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ad0: 20 20 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 7d     0, 0, 0);.  }
3ae0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
3af0: 33 4f 73 43 68 65 63 6b 52 65 73 65 72 76 65 64  3OsCheckReserved
3b00: 4c 6f 63 6b 28 70 46 64 2d 3e 70 52 65 61 6c 2c  Lock(pFd->pReal,
3b10: 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a   pResOut);.}../*
3b20: 0a 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f 6c  .** File control
3b30: 20 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75 73   method. For cus
3b40: 74 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f  tom operations o
3b50: 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  n an tvfs-file..
3b60: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3b70: 66 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71  fsFileControl(sq
3b80: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
3b90: 65 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20  e, int op, void 
3ba0: 2a 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76 66  *pArg){.  Testvf
3bb0: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
3bc0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 69 66 28  Fd(pFile);.  if(
3bd0: 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 46 43 4e 54   op==SQLITE_FCNT
3be0: 4c 5f 50 52 41 47 4d 41 20 29 7b 0a 20 20 20 20  L_PRAGMA ){.    
3bf0: 63 68 61 72 20 2a 2a 61 72 67 76 20 3d 20 28 63  char **argv = (c
3c00: 68 61 72 2a 2a 29 70 41 72 67 3b 0a 20 20 20 20  har**)pArg;.    
3c10: 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69  if( sqlite3_stri
3c20: 63 6d 70 28 61 72 67 76 5b 31 5d 2c 22 65 72 72  cmp(argv[1],"err
3c30: 6f 72 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  or")==0 ){.     
3c40: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
3c50: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 69 66  _ERROR;.      if
3c60: 28 20 61 72 67 76 5b 32 5d 20 29 7b 0a 20 20 20  ( argv[2] ){.   
3c70: 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20       const char 
3c80: 2a 7a 20 3d 20 61 72 67 76 5b 32 5d 3b 0a 20 20  *z = argv[2];.  
3c90: 20 20 20 20 20 20 69 6e 74 20 78 20 3d 20 61 74        int x = at
3ca0: 6f 69 28 7a 29 3b 0a 20 20 20 20 20 20 20 20 69  oi(z);.        i
3cb0: 66 28 20 78 20 29 7b 0a 20 20 20 20 20 20 20 20  f( x ){.        
3cc0: 20 20 72 63 20 3d 20 78 3b 0a 20 20 20 20 20 20    rc = x;.      
3cd0: 20 20 20 20 77 68 69 6c 65 28 20 73 71 6c 69 74      while( sqlit
3ce0: 65 33 49 73 64 69 67 69 74 28 7a 5b 30 5d 29 20  e3Isdigit(z[0]) 
3cf0: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20  ){ z++; }.      
3d00: 20 20 20 20 77 68 69 6c 65 28 20 73 71 6c 69 74      while( sqlit
3d10: 65 33 49 73 73 70 61 63 65 28 7a 5b 30 5d 29 20  e3Isspace(z[0]) 
3d20: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20  ){ z++; }.      
3d30: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20    }.        if( 
3d40: 7a 5b 30 5d 20 29 20 61 72 67 76 5b 30 5d 20 3d  z[0] ) argv[0] =
3d50: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
3d60: 28 22 25 73 22 2c 20 7a 29 3b 0a 20 20 20 20 20  ("%s", z);.     
3d70: 20 7d 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20   }.      return 
3d80: 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  rc;.    }.    if
3d90: 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ( sqlite3_stricm
3da0: 70 28 61 72 67 76 5b 31 5d 2c 20 22 66 69 6c 65  p(argv[1], "file
3db0: 6e 61 6d 65 22 29 3d 3d 30 20 29 7b 0a 20 20 20  name")==0 ){.   
3dc0: 20 20 20 61 72 67 76 5b 30 5d 20 3d 20 73 71 6c     argv[0] = sql
3dd0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
3de0: 22 2c 20 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29  ", p->zFilename)
3df0: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
3e00: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a  QLITE_OK;.    }.
3e10: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c    }.  return sql
3e20: 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f  ite3OsFileContro
3e30: 6c 28 70 2d 3e 70 52 65 61 6c 2c 20 6f 70 2c 20  l(p->pReal, op, 
3e40: 70 41 72 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  pArg);.}../*.** 
3e50: 52 65 74 75 72 6e 20 74 68 65 20 73 65 63 74 6f  Return the secto
3e60: 72 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20  r-size in bytes 
3e70: 66 6f 72 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  for an tvfs-file
3e80: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3e90: 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 28 73  tvfsSectorSize(s
3ea0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
3eb0: 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  le){.  TestvfsFd
3ec0: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
3ed0: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
3ee0: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
3ef0: 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70  s *)pFd->pVfs->p
3f00: 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20 70  AppData;.  if( p
3f10: 2d 3e 69 53 65 63 74 6f 72 73 69 7a 65 3e 3d 30  ->iSectorsize>=0
3f20: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
3f30: 2d 3e 69 53 65 63 74 6f 72 73 69 7a 65 3b 0a 20  ->iSectorsize;. 
3f40: 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69   }.  return sqli
3f50: 74 65 33 4f 73 53 65 63 74 6f 72 53 69 7a 65 28  te3OsSectorSize(
3f60: 70 46 64 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a  pFd->pReal);.}..
3f70: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3f80: 20 64 65 76 69 63 65 20 63 68 61 72 61 63 74 65   device characte
3f90: 72 69 73 74 69 63 20 66 6c 61 67 73 20 73 75 70  ristic flags sup
3fa0: 70 6f 72 74 65 64 20 62 79 20 61 6e 20 74 76 66  ported by an tvf
3fb0: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
3fc0: 63 20 69 6e 74 20 74 76 66 73 44 65 76 69 63 65  c int tvfsDevice
3fd0: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28  Characteristics(
3fe0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
3ff0: 69 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46  ile){.  TestvfsF
4000: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
4010: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
4020: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
4030: 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e  fs *)pFd->pVfs->
4040: 70 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28 20  pAppData;.  if( 
4050: 70 2d 3e 69 44 65 76 63 68 61 72 3e 3d 30 20 29  p->iDevchar>=0 )
4060: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 2d 3e  {.    return p->
4070: 69 44 65 76 63 68 61 72 3b 0a 20 20 7d 0a 20 20  iDevchar;.  }.  
4080: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
4090: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
40a0: 73 74 69 63 73 28 70 46 64 2d 3e 70 52 65 61 6c  stics(pFd->pReal
40b0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e  );.}../*.** Open
40c0: 20 61 6e 20 74 76 66 73 20 66 69 6c 65 20 68 61   an tvfs file ha
40d0: 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ndle..*/.static 
40e0: 69 6e 74 20 74 76 66 73 4f 70 65 6e 28 0a 20 20  int tvfsOpen(.  
40f0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4100: 73 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  s,.  const char 
4110: 2a 7a 4e 61 6d 65 2c 0a 20 20 73 71 6c 69 74 65  *zName,.  sqlite
4120: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20  3_file *pFile,. 
4130: 20 69 6e 74 20 66 6c 61 67 73 2c 0a 20 20 69 6e   int flags,.  in
4140: 74 20 2a 70 4f 75 74 46 6c 61 67 73 0a 29 7b 0a  t *pOutFlags.){.
4150: 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 65 73 74    int rc;.  Test
4160: 76 66 73 46 69 6c 65 20 2a 70 54 65 73 74 66 69  vfsFile *pTestfi
4170: 6c 65 20 3d 20 28 54 65 73 74 76 66 73 46 69 6c  le = (TestvfsFil
4180: 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20 54 65 73  e *)pFile;.  Tes
4190: 74 76 66 73 46 64 20 2a 70 46 64 3b 0a 20 20 54  tvfsFd *pFd;.  T
41a0: 63 6c 5f 4f 62 6a 20 2a 70 49 64 20 3d 20 30 3b  cl_Obj *pId = 0;
41b0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
41c0: 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d  (Testvfs *)pVfs-
41d0: 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 70 46  >pAppData;..  pF
41e0: 64 20 3d 20 28 54 65 73 74 76 66 73 46 64 20 2a  d = (TestvfsFd *
41f0: 29 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  )ckalloc(sizeof(
4200: 54 65 73 74 76 66 73 46 64 29 20 2b 20 50 41 52  TestvfsFd) + PAR
4210: 45 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 73 7a  ENTVFS(pVfs)->sz
4220: 4f 73 46 69 6c 65 29 3b 0a 20 20 6d 65 6d 73 65  OsFile);.  memse
4230: 74 28 70 46 64 2c 20 30 2c 20 73 69 7a 65 6f 66  t(pFd, 0, sizeof
4240: 28 54 65 73 74 76 66 73 46 64 29 20 2b 20 50 41  (TestvfsFd) + PA
4250: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 73  RENTVFS(pVfs)->s
4260: 7a 4f 73 46 69 6c 65 29 3b 0a 20 20 70 46 64 2d  zOsFile);.  pFd-
4270: 3e 70 53 68 6d 20 3d 20 30 3b 0a 20 20 70 46 64  >pShm = 0;.  pFd
4280: 2d 3e 70 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20  ->pShmId = 0;.  
4290: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d  pFd->zFilename =
42a0: 20 7a 4e 61 6d 65 3b 0a 20 20 70 46 64 2d 3e 70   zName;.  pFd->p
42b0: 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 46  Vfs = pVfs;.  pF
42c0: 64 2d 3e 70 52 65 61 6c 20 3d 20 28 73 71 6c 69  d->pReal = (sqli
42d0: 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 46 64 5b  te3_file *)&pFd[
42e0: 31 5d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 54 65  1];.  memset(pTe
42f0: 73 74 66 69 6c 65 2c 20 30 2c 20 73 69 7a 65 6f  stfile, 0, sizeo
4300: 66 28 54 65 73 74 76 66 73 46 69 6c 65 29 29 3b  f(TestvfsFile));
4310: 0a 20 20 70 54 65 73 74 66 69 6c 65 2d 3e 70 46  .  pTestfile->pF
4320: 64 20 3d 20 70 46 64 3b 0a 0a 20 20 2f 2a 20 45  d = pFd;..  /* E
4330: 76 61 6c 75 61 74 65 20 74 68 65 20 54 63 6c 20  valuate the Tcl 
4340: 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a 20 20  script: .  **.  
4350: 2a 2a 20 20 20 53 43 52 49 50 54 20 78 4f 70 65  **   SCRIPT xOpe
4360: 6e 20 46 49 4c 45 4e 41 4d 45 20 4b 45 59 2d 56  n FILENAME KEY-V
4370: 41 4c 55 45 2d 41 52 47 53 0a 20 20 2a 2a 0a 20  ALUE-ARGS.  **. 
4380: 20 2a 2a 20 49 66 20 74 68 65 20 73 63 72 69 70   ** If the scrip
4390: 74 20 72 65 74 75 72 6e 73 20 61 6e 20 53 51 4c  t returns an SQL
43a0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f  ite error code o
43b0: 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
43c0: 5f 4f 4b 2c 20 61 6e 0a 20 20 2a 2a 20 65 72 72  _OK, an.  ** err
43d0: 6f 72 20 69 73 20 72 65 74 75 72 6e 65 64 20 74  or is returned t
43e0: 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 49 66  o the caller. If
43f0: 20 69 74 20 72 65 74 75 72 6e 73 20 53 51 4c 49   it returns SQLI
4400: 54 45 5f 4f 4b 2c 20 74 68 65 20 6e 65 77 0a 20  TE_OK, the new. 
4410: 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69   ** connection i
4420: 73 20 6e 61 6d 65 64 20 22 61 6e 6f 6e 22 2e 20  s named "anon". 
4430: 4f 74 68 65 72 77 69 73 65 2c 20 74 68 65 20 76  Otherwise, the v
4440: 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79  alue returned by
4450: 20 74 68 65 0a 20 20 2a 2a 20 73 63 72 69 70 74   the.  ** script
4460: 20 69 73 20 75 73 65 64 20 61 73 20 74 68 65 20   is used as the 
4470: 63 6f 6e 6e 65 63 74 69 6f 6e 20 6e 61 6d 65 2e  connection name.
4480: 0a 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65  .  */.  Tcl_Rese
4490: 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72  tResult(p->inter
44a0: 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  p);.  if( p->pSc
44b0: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
44c0: 54 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53  TESTVFS_OPEN_MAS
44d0: 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a  K ){.    Tcl_Obj
44e0: 20 2a 70 41 72 67 20 3d 20 54 63 6c 5f 4e 65 77   *pArg = Tcl_New
44f0: 4f 62 6a 28 29 3b 0a 20 20 20 20 54 63 6c 5f 49  Obj();.    Tcl_I
4500: 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 41 72 67  ncrRefCount(pArg
4510: 29 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73  );.    if( flags
4520: 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49  &SQLITE_OPEN_MAI
4530: 4e 5f 44 42 20 29 7b 0a 20 20 20 20 20 20 63 6f  N_DB ){.      co
4540: 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 26 7a  nst char *z = &z
4550: 4e 61 6d 65 5b 73 74 72 6c 65 6e 28 7a 4e 61 6d  Name[strlen(zNam
4560: 65 29 2b 31 5d 3b 0a 20 20 20 20 20 20 77 68 69  e)+1];.      whi
4570: 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 20 20  le( *z ){.      
4580: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
4590: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 41  endElement(0, pA
45a0: 72 67 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  rg, Tcl_NewStrin
45b0: 67 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 20 20  gObj(z, -1));.  
45c0: 20 20 20 20 20 20 7a 20 2b 3d 20 73 74 72 6c 65        z += strle
45d0: 6e 28 7a 29 20 2b 20 31 3b 0a 20 20 20 20 20 20  n(z) + 1;.      
45e0: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
45f0: 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 41  endElement(0, pA
4600: 72 67 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  rg, Tcl_NewStrin
4610: 67 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 20 20  gObj(z, -1));.  
4620: 20 20 20 20 20 20 7a 20 2b 3d 20 73 74 72 6c 65        z += strle
4630: 6e 28 7a 29 20 2b 20 31 3b 0a 20 20 20 20 20 20  n(z) + 1;.      
4640: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 74 76 66 73  }.    }.    tvfs
4650: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 4f 70 65  ExecTcl(p, "xOpe
4660: 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  n", Tcl_NewStrin
4670: 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e  gObj(pFd->zFilen
4680: 61 6d 65 2c 20 2d 31 29 2c 20 70 41 72 67 2c 20  ame, -1), pArg, 
4690: 30 2c 20 30 29 3b 0a 20 20 20 20 54 63 6c 5f 44  0, 0);.    Tcl_D
46a0: 65 63 72 52 65 66 43 6f 75 6e 74 28 70 41 72 67  ecrRefCount(pArg
46b0: 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52  );.    if( tvfsR
46c0: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
46d0: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72  ) ){.      if( r
46e0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
46f0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65  eturn rc;.    }e
4700: 6c 73 65 7b 0a 20 20 20 20 20 20 70 49 64 20 3d  lse{.      pId =
4710: 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c   Tcl_GetObjResul
4720: 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20  t(p->interp);.  
4730: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 28    }.  }..  if( (
4740: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
4750: 4f 50 45 4e 5f 4d 41 53 4b 29 20 26 26 20 20 74  OPEN_MASK) &&  t
4760: 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70  vfsInjectIoerr(p
4770: 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ) ) return SQLIT
4780: 45 5f 49 4f 45 52 52 3b 0a 20 20 69 66 28 20 74  E_IOERR;.  if( t
4790: 76 66 73 49 6e 6a 65 63 74 43 61 6e 74 6f 70 65  vfsInjectCantope
47a0: 6e 65 72 72 28 70 29 20 29 20 72 65 74 75 72 6e  nerr(p) ) return
47b0: 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e   SQLITE_CANTOPEN
47c0: 3b 0a 20 20 69 66 28 20 74 76 66 73 49 6e 6a 65  ;.  if( tvfsInje
47d0: 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 20 72  ctFullerr(p) ) r
47e0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 46 55 4c  eturn SQLITE_FUL
47f0: 4c 3b 0a 0a 20 20 69 66 28 20 21 70 49 64 20 29  L;..  if( !pId )
4800: 7b 0a 20 20 20 20 70 49 64 20 3d 20 54 63 6c 5f  {.    pId = Tcl_
4810: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 61 6e  NewStringObj("an
4820: 6f 6e 22 2c 20 2d 31 29 3b 0a 20 20 7d 0a 20 20  on", -1);.  }.  
4830: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
4840: 28 70 49 64 29 3b 0a 20 20 70 46 64 2d 3e 70 53  (pId);.  pFd->pS
4850: 68 6d 49 64 20 3d 20 70 49 64 3b 0a 20 20 54 63  hmId = pId;.  Tc
4860: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d  l_ResetResult(p-
4870: 3e 69 6e 74 65 72 70 29 3b 0a 0a 20 20 72 63 20  >interp);..  rc 
4880: 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 28  = sqlite3OsOpen(
4890: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
48a0: 20 7a 4e 61 6d 65 2c 20 70 46 64 2d 3e 70 52 65   zName, pFd->pRe
48b0: 61 6c 2c 20 66 6c 61 67 73 2c 20 70 4f 75 74 46  al, flags, pOutF
48c0: 6c 61 67 73 29 3b 0a 20 20 69 66 28 20 70 46 64  lags);.  if( pFd
48d0: 2d 3e 70 52 65 61 6c 2d 3e 70 4d 65 74 68 6f 64  ->pReal->pMethod
48e0: 73 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  s ){.    sqlite3
48f0: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 70 4d 65  _io_methods *pMe
4900: 74 68 6f 64 73 3b 0a 20 20 20 20 69 6e 74 20 6e  thods;.    int n
4910: 42 79 74 65 3b 0a 0a 20 20 20 20 69 66 28 20 70  Byte;..    if( p
4920: 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 31 20  Vfs->iVersion>1 
4930: 29 7b 0a 20 20 20 20 20 20 6e 42 79 74 65 20 3d  ){.      nByte =
4940: 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f   sizeof(sqlite3_
4950: 69 6f 5f 6d 65 74 68 6f 64 73 29 3b 0a 20 20 20  io_methods);.   
4960: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e 42   }else{.      nB
4970: 79 74 65 20 3d 20 6f 66 66 73 65 74 6f 66 28 73  yte = offsetof(s
4980: 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64  qlite3_io_method
4990: 73 2c 20 78 53 68 6d 4d 61 70 29 3b 0a 20 20 20  s, xShmMap);.   
49a0: 20 7d 0a 0a 20 20 20 20 70 4d 65 74 68 6f 64 73   }..    pMethods
49b0: 20 3d 20 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d   = (sqlite3_io_m
49c0: 65 74 68 6f 64 73 20 2a 29 63 6b 61 6c 6c 6f 63  ethods *)ckalloc
49d0: 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 6d 65 6d  (nByte);.    mem
49e0: 63 70 79 28 70 4d 65 74 68 6f 64 73 2c 20 26 74  cpy(pMethods, &t
49f0: 76 66 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 2c 20  vfs_io_methods, 
4a00: 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 4d 65 74  nByte);.    pMet
4a10: 68 6f 64 73 2d 3e 69 56 65 72 73 69 6f 6e 20 3d  hods->iVersion =
4a20: 20 70 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d 65   pFd->pReal->pMe
4a30: 74 68 6f 64 73 2d 3e 69 56 65 72 73 69 6f 6e 3b  thods->iVersion;
4a40: 0a 20 20 20 20 69 66 28 20 70 4d 65 74 68 6f 64  .    if( pMethod
4a50: 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 70 56 66 73  s->iVersion>pVfs
4a60: 2d 3e 69 56 65 72 73 69 6f 6e 20 29 7b 0a 20 20  ->iVersion ){.  
4a70: 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e 69 56      pMethods->iV
4a80: 65 72 73 69 6f 6e 20 3d 20 70 56 66 73 2d 3e 69  ersion = pVfs->i
4a90: 56 65 72 73 69 6f 6e 3b 0a 20 20 20 20 7d 0a 20  Version;.    }. 
4aa0: 20 20 20 69 66 28 20 70 56 66 73 2d 3e 69 56 65     if( pVfs->iVe
4ab0: 72 73 69 6f 6e 3e 31 20 26 26 20 28 28 54 65 73  rsion>1 && ((Tes
4ac0: 74 76 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70  tvfs *)pVfs->pAp
4ad0: 70 44 61 74 61 29 2d 3e 69 73 4e 6f 73 68 6d 20  pData)->isNoshm 
4ae0: 29 7b 0a 20 20 20 20 20 20 70 4d 65 74 68 6f 64  ){.      pMethod
4af0: 73 2d 3e 78 53 68 6d 55 6e 6d 61 70 20 3d 20 30  s->xShmUnmap = 0
4b00: 3b 0a 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73  ;.      pMethods
4b10: 2d 3e 78 53 68 6d 4c 6f 63 6b 20 3d 20 30 3b 0a  ->xShmLock = 0;.
4b20: 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e        pMethods->
4b30: 78 53 68 6d 42 61 72 72 69 65 72 20 3d 20 30 3b  xShmBarrier = 0;
4b40: 0a 20 20 20 20 20 20 70 4d 65 74 68 6f 64 73 2d  .      pMethods-
4b50: 3e 78 53 68 6d 4d 61 70 20 3d 20 30 3b 0a 20 20  >xShmMap = 0;.  
4b60: 20 20 7d 0a 20 20 20 20 70 46 69 6c 65 2d 3e 70    }.    pFile->p
4b70: 4d 65 74 68 6f 64 73 20 3d 20 70 4d 65 74 68 6f  Methods = pMetho
4b80: 64 73 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  ds;.  }..  retur
4b90: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44  n rc;.}../*.** D
4ba0: 65 6c 65 74 65 20 74 68 65 20 66 69 6c 65 20 6c  elete the file l
4bb0: 6f 63 61 74 65 64 20 61 74 20 7a 50 61 74 68 2e  ocated at zPath.
4bc0: 20 49 66 20 74 68 65 20 64 69 72 53 79 6e 63 20   If the dirSync 
4bd0: 61 72 67 75 6d 65 6e 74 20 69 73 20 74 72 75 65  argument is true
4be0: 2c 0a 2a 2a 20 65 6e 73 75 72 65 20 74 68 65 20  ,.** ensure the 
4bf0: 66 69 6c 65 2d 73 79 73 74 65 6d 20 6d 6f 64 69  file-system modi
4c00: 66 69 63 61 74 69 6f 6e 73 20 61 72 65 20 73 79  fications are sy
4c10: 6e 63 65 64 20 74 6f 20 64 69 73 6b 20 62 65 66  nced to disk bef
4c20: 6f 72 65 0a 2a 2a 20 72 65 74 75 72 6e 69 6e 67  ore.** returning
4c30: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4c40: 74 76 66 73 44 65 6c 65 74 65 28 73 71 6c 69 74  tvfsDelete(sqlit
4c50: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f  e3_vfs *pVfs, co
4c60: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c  nst char *zPath,
4c70: 20 69 6e 74 20 64 69 72 53 79 6e 63 29 7b 0a 20   int dirSync){. 
4c80: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
4c90: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  _OK;.  Testvfs *
4ca0: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
4cb0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a  Vfs->pAppData;..
4cc0: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
4cd0: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
4ce0: 56 46 53 5f 44 45 4c 45 54 45 5f 4d 41 53 4b 20  VFS_DELETE_MASK 
4cf0: 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54  ){.    tvfsExecT
4d00: 63 6c 28 70 2c 20 22 78 44 65 6c 65 74 65 22 2c  cl(p, "xDelete",
4d10: 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65   .        Tcl_Ne
4d20: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 50 61 74 68  wStringObj(zPath
4d30: 2c 20 2d 31 29 2c 20 54 63 6c 5f 4e 65 77 49 6e  , -1), Tcl_NewIn
4d40: 74 4f 62 6a 28 64 69 72 53 79 6e 63 29 2c 20 30  tObj(dirSync), 0
4d50: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74  , 0.    );.    t
4d60: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
4d70: 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 69 66 28   &rc);.  }.  if(
4d80: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4d90: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
4da0: 65 33 4f 73 44 65 6c 65 74 65 28 50 41 52 45 4e  e3OsDelete(PAREN
4db0: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74  TVFS(pVfs), zPat
4dc0: 68 2c 20 64 69 72 53 79 6e 63 29 3b 0a 20 20 7d  h, dirSync);.  }
4dd0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
4de0: 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 66 6f 72 20  ./*.** Test for 
4df0: 61 63 63 65 73 73 20 70 65 72 6d 69 73 73 69 6f  access permissio
4e00: 6e 73 2e 20 52 65 74 75 72 6e 20 74 72 75 65 20  ns. Return true 
4e10: 69 66 20 74 68 65 20 72 65 71 75 65 73 74 65 64  if the requested
4e20: 20 70 65 72 6d 69 73 73 69 6f 6e 0a 2a 2a 20 69   permission.** i
4e30: 73 20 61 76 61 69 6c 61 62 6c 65 2c 20 6f 72 20  s available, or 
4e40: 66 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65 2e  false otherwise.
4e50: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
4e60: 76 66 73 41 63 63 65 73 73 28 0a 20 20 73 71 6c  vfsAccess(.  sql
4e70: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4e80: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
4e90: 50 61 74 68 2c 20 0a 20 20 69 6e 74 20 66 6c 61  Path, .  int fla
4ea0: 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70 52 65 73  gs, .  int *pRes
4eb0: 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74 76 66 73  Out.){.  Testvfs
4ec0: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
4ed0: 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  )pVfs->pAppData;
4ee0: 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70  .  if( p->pScrip
4ef0: 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  t && p->mask&TES
4f00: 54 56 46 53 5f 41 43 43 45 53 53 5f 4d 41 53 4b  TVFS_ACCESS_MASK
4f10: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a   ){.    int rc;.
4f20: 20 20 20 20 63 68 61 72 20 2a 7a 41 72 67 20 3d      char *zArg =
4f30: 20 30 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67   0;.    if( flag
4f40: 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53 53  s==SQLITE_ACCESS
4f50: 5f 45 58 49 53 54 53 20 29 20 7a 41 72 67 20 3d  _EXISTS ) zArg =
4f60: 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f   "SQLITE_ACCESS_
4f70: 45 58 49 53 54 53 22 3b 0a 20 20 20 20 69 66 28  EXISTS";.    if(
4f80: 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41   flags==SQLITE_A
4f90: 43 43 45 53 53 5f 52 45 41 44 57 52 49 54 45 20  CCESS_READWRITE 
4fa0: 29 20 7a 41 72 67 20 3d 20 22 53 51 4c 49 54 45  ) zArg = "SQLITE
4fb0: 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49 54  _ACCESS_READWRIT
4fc0: 45 22 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67  E";.    if( flag
4fd0: 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53 53  s==SQLITE_ACCESS
4fe0: 5f 52 45 41 44 20 29 20 7a 41 72 67 20 3d 20 22  _READ ) zArg = "
4ff0: 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45  SQLITE_ACCESS_RE
5000: 41 44 22 3b 0a 20 20 20 20 74 76 66 73 45 78 65  AD";.    tvfsExe
5010: 63 54 63 6c 28 70 2c 20 22 78 41 63 63 65 73 73  cTcl(p, "xAccess
5020: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
5030: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 50 61  NewStringObj(zPa
5040: 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f 4e 65 77  th, -1), Tcl_New
5050: 53 74 72 69 6e 67 4f 62 6a 28 7a 41 72 67 2c 20  StringObj(zArg, 
5060: 2d 31 29 2c 20 30 2c 20 30 0a 20 20 20 20 29 3b  -1), 0, 0.    );
5070: 0a 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73  .    if( tvfsRes
5080: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20  ultCode(p, &rc) 
5090: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  ){.      if( rc!
50a0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
50b0: 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73  urn rc;.    }els
50c0: 65 7b 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 74  e{.      Tcl_Int
50d0: 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d  erp *interp = p-
50e0: 3e 69 6e 74 65 72 70 3b 0a 20 20 20 20 20 20 69  >interp;.      i
50f0: 66 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f 47  f( TCL_OK==Tcl_G
5100: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
5110: 28 30 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  (0, Tcl_GetObjRe
5120: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 70 52  sult(interp), pR
5130: 65 73 4f 75 74 29 20 29 7b 0a 20 20 20 20 20 20  esOut) ){.      
5140: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5150: 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OK;.      }.    
5160: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  }.  }.  return s
5170: 71 6c 69 74 65 33 4f 73 41 63 63 65 73 73 28 50  qlite3OsAccess(P
5180: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
5190: 7a 50 61 74 68 2c 20 66 6c 61 67 73 2c 20 70 52  zPath, flags, pR
51a0: 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  esOut);.}../*.**
51b0: 20 50 6f 70 75 6c 61 74 65 20 62 75 66 66 65 72   Populate buffer
51c0: 20 7a 4f 75 74 20 77 69 74 68 20 74 68 65 20 66   zOut with the f
51d0: 75 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61  ull canonical pa
51e0: 74 68 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f 6e  thname correspon
51f0: 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 70  ding.** to the p
5200: 61 74 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74 68  athname in zPath
5210: 2e 20 7a 4f 75 74 20 69 73 20 67 75 61 72 61 6e  . zOut is guaran
5220: 74 65 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f  teed to point to
5230: 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66 20   a buffer.** of 
5240: 61 74 20 6c 65 61 73 74 20 28 44 45 56 53 59 4d  at least (DEVSYM
5250: 5f 4d 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31 29  _MAX_PATHNAME+1)
5260: 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   bytes..*/.stati
5270: 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c 50 61  c int tvfsFullPa
5280: 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74 65  thname(.  sqlite
5290: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20  3_vfs *pVfs, .  
52a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74  const char *zPat
52b0: 68 2c 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20  h, .  int nOut, 
52c0: 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29 7b  .  char *zOut.){
52d0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
52e0: 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d  (Testvfs *)pVfs-
52f0: 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 69 66 28  >pAppData;.  if(
5300: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
5310: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 46  ->mask&TESTVFS_F
5320: 55 4c 4c 50 41 54 48 4e 41 4d 45 5f 4d 41 53 4b  ULLPATHNAME_MASK
5330: 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a   ){.    int rc;.
5340: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
5350: 70 2c 20 22 78 46 75 6c 6c 50 61 74 68 6e 61 6d  p, "xFullPathnam
5360: 65 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  e", Tcl_NewStrin
5370: 67 4f 62 6a 28 7a 50 61 74 68 2c 20 2d 31 29 2c  gObj(zPath, -1),
5380: 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69   0, 0, 0);.    i
5390: 66 28 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64  f( tvfsResultCod
53a0: 65 28 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20  e(p, &rc) ){.   
53b0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
53c0: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
53d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
53e0: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 75  turn sqlite3OsFu
53f0: 6c 6c 50 61 74 68 6e 61 6d 65 28 50 41 52 45 4e  llPathname(PAREN
5400: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74  TVFS(pVfs), zPat
5410: 68 2c 20 6e 4f 75 74 2c 20 7a 4f 75 74 29 3b 0a  h, nOut, zOut);.
5420: 7d 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  }..#ifndef SQLIT
5430: 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45  E_OMIT_LOAD_EXTE
5440: 4e 53 49 4f 4e 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e  NSION./*.** Open
5450: 20 74 68 65 20 64 79 6e 61 6d 69 63 20 6c 69 62   the dynamic lib
5460: 72 61 72 79 20 6c 6f 63 61 74 65 64 20 61 74 20  rary located at 
5470: 7a 50 61 74 68 20 61 6e 64 20 72 65 74 75 72 6e  zPath and return
5480: 20 61 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74   a handle..*/.st
5490: 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66 73 44  atic void *tvfsD
54a0: 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66  lOpen(sqlite3_vf
54b0: 73 20 2a 70 56 66 73 2c 20 63 6f 6e 73 74 20 63  s *pVfs, const c
54c0: 68 61 72 20 2a 7a 50 61 74 68 29 7b 0a 20 20 72  har *zPath){.  r
54d0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 44  eturn sqlite3OsD
54e0: 6c 4f 70 65 6e 28 50 41 52 45 4e 54 56 46 53 28  lOpen(PARENTVFS(
54f0: 70 56 66 73 29 2c 20 7a 50 61 74 68 29 3b 0a 7d  pVfs), zPath);.}
5500: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65  ../*.** Populate
5510: 20 74 68 65 20 62 75 66 66 65 72 20 7a 45 72 72   the buffer zErr
5520: 4d 73 67 20 28 73 69 7a 65 20 6e 42 79 74 65 20  Msg (size nByte 
5530: 62 79 74 65 73 29 20 77 69 74 68 20 61 20 68 75  bytes) with a hu
5540: 6d 61 6e 20 72 65 61 64 61 62 6c 65 0a 2a 2a 20  man readable.** 
5550: 75 74 66 2d 38 20 73 74 72 69 6e 67 20 64 65 73  utf-8 string des
5560: 63 72 69 62 69 6e 67 20 74 68 65 20 6d 6f 73 74  cribing the most
5570: 20 72 65 63 65 6e 74 20 65 72 72 6f 72 20 65 6e   recent error en
5580: 63 6f 75 6e 74 65 72 65 64 20 61 73 73 6f 63 69  countered associ
5590: 61 74 65 64 20 0a 2a 2a 20 77 69 74 68 20 64 79  ated .** with dy
55a0: 6e 61 6d 69 63 20 6c 69 62 72 61 72 69 65 73 2e  namic libraries.
55b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
55c0: 74 76 66 73 44 6c 45 72 72 6f 72 28 73 71 6c 69  tvfsDlError(sqli
55d0: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69  te3_vfs *pVfs, i
55e0: 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a  nt nByte, char *
55f0: 7a 45 72 72 4d 73 67 29 7b 0a 20 20 73 71 6c 69  zErrMsg){.  sqli
5600: 74 65 33 4f 73 44 6c 45 72 72 6f 72 28 50 41 52  te3OsDlError(PAR
5610: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 6e 42  ENTVFS(pVfs), nB
5620: 79 74 65 2c 20 7a 45 72 72 4d 73 67 29 3b 0a 7d  yte, zErrMsg);.}
5630: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ../*.** Return a
5640: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
5650: 73 79 6d 62 6f 6c 20 7a 53 79 6d 62 6f 6c 20 69  symbol zSymbol i
5660: 6e 20 74 68 65 20 64 79 6e 61 6d 69 63 20 6c 69  n the dynamic li
5670: 62 72 61 72 79 20 70 48 61 6e 64 6c 65 2e 0a 2a  brary pHandle..*
5680: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 28 2a  /.static void (*
5690: 74 76 66 73 44 6c 53 79 6d 28 73 71 6c 69 74 65  tvfsDlSym(sqlite
56a0: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 76 6f 69  3_vfs *pVfs, voi
56b0: 64 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  d *p, const char
56c0: 20 2a 7a 53 79 6d 29 29 28 76 6f 69 64 29 7b 0a   *zSym))(void){.
56d0: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
56e0: 4f 73 44 6c 53 79 6d 28 50 41 52 45 4e 54 56 46  OsDlSym(PARENTVF
56f0: 53 28 70 56 66 73 29 2c 20 70 2c 20 7a 53 79 6d  S(pVfs), p, zSym
5700: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73  );.}../*.** Clos
5710: 65 20 74 68 65 20 64 79 6e 61 6d 69 63 20 6c 69  e the dynamic li
5720: 62 72 61 72 79 20 68 61 6e 64 6c 65 20 70 48 61  brary handle pHa
5730: 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ndle..*/.static 
5740: 76 6f 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65  void tvfsDlClose
5750: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
5760: 66 73 2c 20 76 6f 69 64 20 2a 70 48 61 6e 64 6c  fs, void *pHandl
5770: 65 29 7b 0a 20 20 73 71 6c 69 74 65 33 4f 73 44  e){.  sqlite3OsD
5780: 6c 43 6c 6f 73 65 28 50 41 52 45 4e 54 56 46 53  lClose(PARENTVFS
5790: 28 70 56 66 73 29 2c 20 70 48 61 6e 64 6c 65 29  (pVfs), pHandle)
57a0: 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
57b0: 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45  LITE_OMIT_LOAD_E
57c0: 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 0a 2f 2a 0a  XTENSION */../*.
57d0: 2a 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 65 20  ** Populate the 
57e0: 62 75 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74  buffer pointed t
57f0: 6f 20 62 79 20 7a 42 75 66 4f 75 74 20 77 69 74  o by zBufOut wit
5800: 68 20 6e 42 79 74 65 20 62 79 74 65 73 20 6f 66  h nByte bytes of
5810: 20 0a 2a 2a 20 72 61 6e 64 6f 6d 20 64 61 74 61   .** random data
5820: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
5830: 74 76 66 73 52 61 6e 64 6f 6d 6e 65 73 73 28 73  tvfsRandomness(s
5840: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
5850: 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61  , int nByte, cha
5860: 72 20 2a 7a 42 75 66 4f 75 74 29 7b 0a 20 20 72  r *zBufOut){.  r
5870: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52  eturn sqlite3OsR
5880: 61 6e 64 6f 6d 6e 65 73 73 28 50 41 52 45 4e 54  andomness(PARENT
5890: 56 46 53 28 70 56 66 73 29 2c 20 6e 42 79 74 65  VFS(pVfs), nByte
58a0: 2c 20 7a 42 75 66 4f 75 74 29 3b 0a 7d 0a 0a 2f  , zBufOut);.}../
58b0: 2a 0a 2a 2a 20 53 6c 65 65 70 20 66 6f 72 20 6e  *.** Sleep for n
58c0: 4d 69 63 72 6f 20 6d 69 63 72 6f 73 65 63 6f 6e  Micro microsecon
58d0: 64 73 2e 20 52 65 74 75 72 6e 20 74 68 65 20 6e  ds. Return the n
58e0: 75 6d 62 65 72 20 6f 66 20 6d 69 63 72 6f 73 65  umber of microse
58f0: 63 6f 6e 64 73 20 0a 2a 2a 20 61 63 74 75 61 6c  conds .** actual
5900: 6c 79 20 73 6c 65 70 74 2e 0a 2a 2f 0a 73 74 61  ly slept..*/.sta
5910: 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65 65  tic int tvfsSlee
5920: 70 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  p(sqlite3_vfs *p
5930: 56 66 73 2c 20 69 6e 74 20 6e 4d 69 63 72 6f 29  Vfs, int nMicro)
5940: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
5950: 65 33 4f 73 53 6c 65 65 70 28 50 41 52 45 4e 54  e3OsSleep(PARENT
5960: 56 46 53 28 70 56 66 73 29 2c 20 6e 4d 69 63 72  VFS(pVfs), nMicr
5970: 6f 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  o);.}../*.** Ret
5980: 75 72 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20  urn the current 
5990: 74 69 6d 65 20 61 73 20 61 20 4a 75 6c 69 61 6e  time as a Julian
59a0: 20 44 61 79 20 6e 75 6d 62 65 72 20 69 6e 20 2a   Day number in *
59b0: 70 54 69 6d 65 4f 75 74 2e 0a 2a 2f 0a 73 74 61  pTimeOut..*/.sta
59c0: 74 69 63 20 69 6e 74 20 74 76 66 73 43 75 72 72  tic int tvfsCurr
59d0: 65 6e 74 54 69 6d 65 28 73 71 6c 69 74 65 33 5f  entTime(sqlite3_
59e0: 76 66 73 20 2a 70 56 66 73 2c 20 64 6f 75 62 6c  vfs *pVfs, doubl
59f0: 65 20 2a 70 54 69 6d 65 4f 75 74 29 7b 0a 20 20  e *pTimeOut){.  
5a00: 72 65 74 75 72 6e 20 50 41 52 45 4e 54 56 46 53  return PARENTVFS
5a10: 28 70 56 66 73 29 2d 3e 78 43 75 72 72 65 6e 74  (pVfs)->xCurrent
5a20: 54 69 6d 65 28 50 41 52 45 4e 54 56 46 53 28 70  Time(PARENTVFS(p
5a30: 56 66 73 29 2c 20 70 54 69 6d 65 4f 75 74 29 3b  Vfs), pTimeOut);
5a40: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
5a50: 76 66 73 53 68 6d 4f 70 65 6e 28 73 71 6c 69 74  vfsShmOpen(sqlit
5a60: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b  e3_file *pFile){
5a70: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 3b 0a 20  .  Testvfs *p;. 
5a80: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
5a90: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
5aa0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
5ab0: 2a 2f 0a 20 20 54 65 73 74 76 66 73 42 75 66 66  */.  TestvfsBuff
5ac0: 65 72 20 2a 70 42 75 66 66 65 72 3b 20 20 20 20  er *pBuffer;    
5ad0: 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74       /* Buffer t
5ae0: 6f 20 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f  o open connectio
5af0: 6e 20 74 6f 20 2a 2f 0a 20 20 54 65 73 74 76 66  n to */.  Testvf
5b00: 73 46 64 20 2a 70 46 64 3b 20 20 20 20 20 20 20  sFd *pFd;       
5b10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
5b20: 20 74 65 73 74 76 66 73 20 66 69 6c 65 20 73 74   testvfs file st
5b30: 72 75 63 74 75 72 65 20 2a 2f 0a 0a 20 20 70 46  ructure */..  pF
5b40: 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  d = tvfsGetFd(pF
5b50: 69 6c 65 29 3b 0a 20 20 70 20 3d 20 28 54 65 73  ile);.  p = (Tes
5b60: 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73  tvfs *)pFd->pVfs
5b70: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20 61 73  ->pAppData;.  as
5b80: 73 65 72 74 28 20 30 3d 3d 70 2d 3e 69 73 46 75  sert( 0==p->isFu
5b90: 6c 6c 73 68 6d 20 29 3b 0a 20 20 61 73 73 65 72  llshm );.  asser
5ba0: 74 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26  t( pFd->pShmId &
5bb0: 26 20 70 46 64 2d 3e 70 53 68 6d 3d 3d 30 20 26  & pFd->pShm==0 &
5bc0: 26 20 70 46 64 2d 3e 70 4e 65 78 74 3d 3d 30 20  & pFd->pNext==0 
5bd0: 29 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61 74  );..  /* Evaluat
5be0: 65 20 74 68 65 20 54 63 6c 20 73 63 72 69 70 74  e the Tcl script
5bf0: 3a 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 53  : .  **.  **   S
5c00: 43 52 49 50 54 20 78 53 68 6d 4f 70 65 6e 20 46  CRIPT xShmOpen F
5c10: 49 4c 45 4e 41 4d 45 0a 20 20 2a 2f 0a 20 20 54  ILENAME.  */.  T
5c20: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70  cl_ResetResult(p
5c30: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66 28  ->interp);.  if(
5c40: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
5c50: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
5c60: 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20  HMOPEN_MASK ){. 
5c70: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
5c80: 2c 20 22 78 53 68 6d 4f 70 65 6e 22 2c 20 54 63  , "xShmOpen", Tc
5c90: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
5ca0: 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d  Fd->zFilename, -
5cb0: 31 29 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20  1), 0, 0, 0);.  
5cc0: 20 20 69 66 28 20 74 76 66 73 52 65 73 75 6c 74    if( tvfsResult
5cd0: 43 6f 64 65 28 70 2c 20 26 72 63 29 20 29 7b 0a  Code(p, &rc) ){.
5ce0: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
5cf0: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
5d00: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   rc;.    }.  }..
5d10: 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
5d20: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 69 66 28  LITE_OK );.  if(
5d30: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
5d40: 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 26 26  _SHMOPEN_MASK &&
5d50: 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72   tvfsInjectIoerr
5d60: 28 70 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  (p) ){.    retur
5d70: 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a  n SQLITE_IOERR;.
5d80: 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68    }..  /* Search
5d90: 20 66 6f 72 20 61 20 54 65 73 74 76 66 73 42 75   for a TestvfsBu
5da0: 66 66 65 72 2e 20 43 72 65 61 74 65 20 61 20 6e  ffer. Create a n
5db0: 65 77 20 6f 6e 65 20 69 66 20 72 65 71 75 69 72  ew one if requir
5dc0: 65 64 2e 20 2a 2f 0a 20 20 66 6f 72 28 70 42 75  ed. */.  for(pBu
5dd0: 66 66 65 72 3d 70 2d 3e 70 42 75 66 66 65 72 3b  ffer=p->pBuffer;
5de0: 20 70 42 75 66 66 65 72 3b 20 70 42 75 66 66 65   pBuffer; pBuffe
5df0: 72 3d 70 42 75 66 66 65 72 2d 3e 70 4e 65 78 74  r=pBuffer->pNext
5e00: 29 7b 0a 20 20 20 20 69 66 28 20 30 3d 3d 73 74  ){.    if( 0==st
5e10: 72 63 6d 70 28 70 46 64 2d 3e 7a 46 69 6c 65 6e  rcmp(pFd->zFilen
5e20: 61 6d 65 2c 20 70 42 75 66 66 65 72 2d 3e 7a 46  ame, pBuffer->zF
5e30: 69 6c 65 29 20 29 20 62 72 65 61 6b 3b 0a 20 20  ile) ) break;.  
5e40: 7d 0a 20 20 69 66 28 20 21 70 42 75 66 66 65 72  }.  if( !pBuffer
5e50: 20 29 7b 0a 20 20 20 20 69 6e 74 20 73 7a 4e 61   ){.    int szNa
5e60: 6d 65 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e  me = (int)strlen
5e70: 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29  (pFd->zFilename)
5e80: 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  ;.    int nByte 
5e90: 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  = sizeof(Testvfs
5ea0: 42 75 66 66 65 72 29 20 2b 20 73 7a 4e 61 6d 65  Buffer) + szName
5eb0: 20 2b 20 31 3b 0a 20 20 20 20 70 42 75 66 66 65   + 1;.    pBuffe
5ec0: 72 20 3d 20 28 54 65 73 74 76 66 73 42 75 66 66  r = (TestvfsBuff
5ed0: 65 72 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e 42 79  er *)ckalloc(nBy
5ee0: 74 65 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  te);.    memset(
5ef0: 70 42 75 66 66 65 72 2c 20 30 2c 20 6e 42 79 74  pBuffer, 0, nByt
5f00: 65 29 3b 0a 20 20 20 20 70 42 75 66 66 65 72 2d  e);.    pBuffer-
5f10: 3e 7a 46 69 6c 65 20 3d 20 28 63 68 61 72 20 2a  >zFile = (char *
5f20: 29 26 70 42 75 66 66 65 72 5b 31 5d 3b 0a 20 20  )&pBuffer[1];.  
5f30: 20 20 6d 65 6d 63 70 79 28 70 42 75 66 66 65 72    memcpy(pBuffer
5f40: 2d 3e 7a 46 69 6c 65 2c 20 70 46 64 2d 3e 7a 46  ->zFile, pFd->zF
5f50: 69 6c 65 6e 61 6d 65 2c 20 73 7a 4e 61 6d 65 2b  ilename, szName+
5f60: 31 29 3b 0a 20 20 20 20 70 42 75 66 66 65 72 2d  1);.    pBuffer-
5f70: 3e 70 4e 65 78 74 20 3d 20 70 2d 3e 70 42 75 66  >pNext = p->pBuf
5f80: 66 65 72 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66  fer;.    p->pBuf
5f90: 66 65 72 20 3d 20 70 42 75 66 66 65 72 3b 0a 20  fer = pBuffer;. 
5fa0: 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74   }..  /* Connect
5fb0: 20 74 68 65 20 54 65 73 74 76 66 73 42 75 66 66   the TestvfsBuff
5fc0: 65 72 20 74 6f 20 74 68 65 20 6e 65 77 20 54 65  er to the new Te
5fd0: 73 74 76 66 73 53 68 6d 20 68 61 6e 64 6c 65 20  stvfsShm handle 
5fe0: 61 6e 64 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20  and return. */. 
5ff0: 20 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42   pFd->pNext = pB
6000: 75 66 66 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20  uffer->pFile;.  
6010: 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d  pBuffer->pFile =
6020: 20 70 46 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68   pFd;.  pFd->pSh
6030: 6d 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 72  m = pBuffer;.  r
6040: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
6050: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
6060: 74 76 66 73 41 6c 6c 6f 63 50 61 67 65 28 54 65  tvfsAllocPage(Te
6070: 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 2c 20  stvfsBuffer *p, 
6080: 69 6e 74 20 69 50 61 67 65 2c 20 69 6e 74 20 70  int iPage, int p
6090: 67 73 7a 29 7b 0a 20 20 61 73 73 65 72 74 28 20  gsz){.  assert( 
60a0: 69 50 61 67 65 3c 54 45 53 54 56 46 53 5f 4d 41  iPage<TESTVFS_MA
60b0: 58 5f 50 41 47 45 53 20 29 3b 0a 20 20 69 66 28  X_PAGES );.  if(
60c0: 20 70 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d   p->aPage[iPage]
60d0: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 61 50  ==0 ){.    p->aP
60e0: 61 67 65 5b 69 50 61 67 65 5d 20 3d 20 28 75 38  age[iPage] = (u8
60f0: 20 2a 29 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29   *)ckalloc(pgsz)
6100: 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e  ;.    memset(p->
6110: 61 50 61 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c  aPage[iPage], 0,
6120: 20 70 67 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70   pgsz);.    p->p
6130: 67 73 7a 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a  gsz = pgsz;.  }.
6140: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  }..static int tv
6150: 66 73 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69  fsShmMap(.  sqli
6160: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
6170: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
6180: 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61  andle open on da
6190: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
61a0: 20 69 6e 74 20 69 50 61 67 65 2c 20 20 20 20 20   int iPage,     
61b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61c0: 20 2f 2a 20 50 61 67 65 20 74 6f 20 72 65 74 72   /* Page to retr
61d0: 69 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67  ieve */.  int pg
61e0: 73 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  sz,             
61f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
6200: 65 20 6f 66 20 70 61 67 65 73 20 2a 2f 0a 20 20  e of pages */.  
6210: 69 6e 74 20 69 73 57 72 69 74 65 2c 20 20 20 20  int isWrite,    
6220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6230: 2f 2a 20 54 72 75 65 20 74 6f 20 65 78 74 65 6e  /* True to exten
6240: 64 20 66 69 6c 65 20 69 66 20 6e 65 63 65 73 73  d file if necess
6250: 61 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f  ary */.  void vo
6260: 6c 61 74 69 6c 65 20 2a 2a 70 70 20 20 20 20 20  latile **pp     
6270: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
6280: 20 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a   Mapped memory *
6290: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
62a0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73  SQLITE_OK;.  Tes
62b0: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
62c0: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
62d0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
62e0: 54 65 73 74 76 66 73 20 2a 29 28 70 46 64 2d 3e  Testvfs *)(pFd->
62f0: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29 3b  pVfs->pAppData);
6300: 0a 0a 20 20 69 66 28 20 70 2d 3e 69 73 46 75 6c  ..  if( p->isFul
6310: 6c 73 68 6d 20 29 7b 0a 20 20 20 20 72 65 74 75  lshm ){.    retu
6320: 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d  rn sqlite3OsShmM
6330: 61 70 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 69  ap(pFd->pReal, i
6340: 50 61 67 65 2c 20 70 67 73 7a 2c 20 69 73 57 72  Page, pgsz, isWr
6350: 69 74 65 2c 20 70 70 29 3b 0a 20 20 7d 0a 0a 20  ite, pp);.  }.. 
6360: 20 69 66 28 20 30 3d 3d 70 46 64 2d 3e 70 53 68   if( 0==pFd->pSh
6370: 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 74 76  m ){.    rc = tv
6380: 66 73 53 68 6d 4f 70 65 6e 28 70 46 69 6c 65 29  fsShmOpen(pFile)
6390: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
63a0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
63b0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
63c0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e  }.  }..  if( p->
63d0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
63e0: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41  sk&TESTVFS_SHMMA
63f0: 50 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54 63  P_MASK ){.    Tc
6400: 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54 63  l_Obj *pArg = Tc
6410: 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20  l_NewObj();.    
6420: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
6430: 28 70 41 72 67 29 3b 0a 20 20 20 20 54 63 6c 5f  (pArg);.    Tcl_
6440: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
6450: 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ment(p->interp, 
6460: 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pArg, Tcl_NewInt
6470: 4f 62 6a 28 69 50 61 67 65 29 29 3b 0a 20 20 20  Obj(iPage));.   
6480: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
6490: 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74  ndElement(p->int
64a0: 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e  erp, pArg, Tcl_N
64b0: 65 77 49 6e 74 4f 62 6a 28 70 67 73 7a 29 29 3b  ewIntObj(pgsz));
64c0: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
64d0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
64e0: 3e 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54  >interp, pArg, T
64f0: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 73 57  cl_NewIntObj(isW
6500: 72 69 74 65 29 29 3b 0a 20 20 20 20 74 76 66 73  rite));.    tvfs
6510: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d  ExecTcl(p, "xShm
6520: 4d 61 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54  Map", .        T
6530: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
6540: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
6550: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
6560: 49 64 2c 20 70 41 72 67 2c 20 30 0a 20 20 20 20  Id, pArg, 0.    
6570: 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c  );.    tvfsResul
6580: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20  tCode(p, &rc);. 
6590: 20 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f     Tcl_DecrRefCo
65a0: 75 6e 74 28 70 41 72 67 29 3b 0a 20 20 7d 0a 20  unt(pArg);.  }. 
65b0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
65c0: 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  OK && p->mask&TE
65d0: 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53  STVFS_SHMMAP_MAS
65e0: 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49  K && tvfsInjectI
65f0: 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72  oerr(p) ){.    r
6600: 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52  c = SQLITE_IOERR
6610: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
6620: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73  =SQLITE_OK && is
6630: 57 72 69 74 65 20 26 26 20 21 70 46 64 2d 3e 70  Write && !pFd->p
6640: 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50 61 67 65  Shm->aPage[iPage
6650: 5d 20 29 7b 0a 20 20 20 20 74 76 66 73 41 6c 6c  ] ){.    tvfsAll
6660: 6f 63 50 61 67 65 28 70 46 64 2d 3e 70 53 68 6d  ocPage(pFd->pShm
6670: 2c 20 69 50 61 67 65 2c 20 70 67 73 7a 29 3b 0a  , iPage, pgsz);.
6680: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 28 76 6f 69    }.  *pp = (voi
6690: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 29 70 46 64  d volatile *)pFd
66a0: 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50  ->pShm->aPage[iP
66b0: 61 67 65 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20  age];..  return 
66c0: 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69  rc;.}...static i
66d0: 6e 74 20 74 76 66 73 53 68 6d 4c 6f 63 6b 28 0a  nt tvfsShmLock(.
66e0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
66f0: 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 6f 66 73  pFile,.  int ofs
6700: 74 2c 0a 20 20 69 6e 74 20 6e 2c 0a 20 20 69 6e  t,.  int n,.  in
6710: 74 20 66 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74  t flags.){.  int
6720: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
6730: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
6740: 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  d = tvfsGetFd(pF
6750: 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20  ile);.  Testvfs 
6760: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
6770: 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70  (pFd->pVfs->pApp
6780: 44 61 74 61 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f  Data);.  int nLo
6790: 63 6b 3b 0a 20 20 63 68 61 72 20 7a 4c 6f 63 6b  ck;.  char zLock
67a0: 5b 38 30 5d 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  [80];..  if( p->
67b0: 69 73 46 75 6c 6c 73 68 6d 20 29 7b 0a 20 20 20  isFullshm ){.   
67c0: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
67d0: 73 53 68 6d 4c 6f 63 6b 28 70 46 64 2d 3e 70 52  sShmLock(pFd->pR
67e0: 65 61 6c 2c 20 6f 66 73 74 2c 20 6e 2c 20 66 6c  eal, ofst, n, fl
67f0: 61 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  ags);.  }..  if(
6800: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
6810: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53  ->mask&TESTVFS_S
6820: 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b 0a 20  HMLOCK_MASK ){. 
6830: 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
6840: 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4c 6f 63 6b  ntf(sizeof(zLock
6850: 29 2c 20 7a 4c 6f 63 6b 2c 20 22 25 64 20 25 64  ), zLock, "%d %d
6860: 22 2c 20 6f 66 73 74 2c 20 6e 29 3b 0a 20 20 20  ", ofst, n);.   
6870: 20 6e 4c 6f 63 6b 20 3d 20 28 69 6e 74 29 73 74   nLock = (int)st
6880: 72 6c 65 6e 28 7a 4c 6f 63 6b 29 3b 0a 20 20 20  rlen(zLock);.   
6890: 20 69 66 28 20 66 6c 61 67 73 20 26 20 53 51 4c   if( flags & SQL
68a0: 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 29 7b 0a  ITE_SHM_LOCK ){.
68b0: 20 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c        strcpy(&zL
68c0: 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 6c 6f  ock[nLock], " lo
68d0: 63 6b 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ck");.    }else{
68e0: 0a 20 20 20 20 20 20 73 74 72 63 70 79 28 26 7a  .      strcpy(&z
68f0: 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 75  Lock[nLock], " u
6900: 6e 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d 0a 20  nlock");.    }. 
6910: 20 20 20 6e 4c 6f 63 6b 20 2b 3d 20 28 69 6e 74     nLock += (int
6920: 29 73 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e  )strlen(&zLock[n
6930: 4c 6f 63 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20  Lock]);.    if( 
6940: 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  flags & SQLITE_S
6950: 48 4d 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20  HM_SHARED ){.   
6960: 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b     strcpy(&zLock
6970: 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65  [nLock], " share
6980: 64 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  d");.    }else{.
6990: 20 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c        strcpy(&zL
69a0: 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78  ock[nLock], " ex
69b0: 63 6c 75 73 69 76 65 22 29 3b 0a 20 20 20 20 7d  clusive");.    }
69c0: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
69d0: 28 70 2c 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20  (p, "xShmLock", 
69e0: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77  .        Tcl_New
69f0: 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70  StringObj(pFd->p
6a00: 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c  Shm->zFile, -1),
6a10: 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20   pFd->pShmId,.  
6a20: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
6a30: 69 6e 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31  ingObj(zLock, -1
6a40: 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20  ), 0.    );.    
6a50: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
6a60: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69  , &rc);.  }..  i
6a70: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6a80: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
6a90: 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b  VFS_SHMLOCK_MASK
6aa0: 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f   && tvfsInjectIo
6ab0: 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63  err(p) ){.    rc
6ac0: 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b   = SQLITE_IOERR;
6ad0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
6ae0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
6af0: 20 69 6e 74 20 69 73 4c 6f 63 6b 20 3d 20 28 66   int isLock = (f
6b00: 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48  lags & SQLITE_SH
6b10: 4d 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 69 6e 74  M_LOCK);.    int
6b20: 20 69 73 45 78 63 6c 20 3d 20 28 66 6c 61 67 73   isExcl = (flags
6b30: 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58   & SQLITE_SHM_EX
6b40: 43 4c 55 53 49 56 45 29 3b 0a 20 20 20 20 75 33  CLUSIVE);.    u3
6b50: 32 20 6d 61 73 6b 20 3d 20 28 28 28 31 3c 3c 6e  2 mask = (((1<<n
6b60: 29 2d 31 29 20 3c 3c 20 6f 66 73 74 29 3b 0a 20  )-1) << ofst);. 
6b70: 20 20 20 69 66 28 20 69 73 4c 6f 63 6b 20 29 7b     if( isLock ){
6b80: 0a 20 20 20 20 20 20 54 65 73 74 76 66 73 46 64  .      TestvfsFd
6b90: 20 2a 70 32 3b 0a 20 20 20 20 20 20 66 6f 72 28   *p2;.      for(
6ba0: 70 32 3d 70 46 64 2d 3e 70 53 68 6d 2d 3e 70 46  p2=pFd->pShm->pF
6bb0: 69 6c 65 3b 20 70 32 3b 20 70 32 3d 70 32 2d 3e  ile; p2; p2=p2->
6bc0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
6bd0: 69 66 28 20 70 32 3d 3d 70 46 64 20 29 20 63 6f  if( p2==pFd ) co
6be0: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20  ntinue;.        
6bf0: 69 66 28 20 28 70 32 2d 3e 65 78 63 6c 6c 6f 63  if( (p2->exclloc
6c00: 6b 26 6d 61 73 6b 29 20 7c 7c 20 28 69 73 45 78  k&mask) || (isEx
6c10: 63 6c 20 26 26 20 70 32 2d 3e 73 68 61 72 65 64  cl && p2->shared
6c20: 6c 6f 63 6b 26 6d 61 73 6b 29 20 29 7b 0a 20 20  lock&mask) ){.  
6c30: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
6c40: 49 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 20 20  ITE_BUSY;.      
6c50: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
6c60: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
6c70: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
6c80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
6c90: 69 66 28 20 69 73 45 78 63 6c 20 29 20 20 70 46  if( isExcl )  pF
6ca0: 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d  d->excllock |= m
6cb0: 61 73 6b 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ask;.        if(
6cc0: 20 21 69 73 45 78 63 6c 20 29 20 70 46 64 2d 3e   !isExcl ) pFd->
6cd0: 73 68 61 72 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61  sharedlock |= ma
6ce0: 73 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  sk;.      }.    
6cf0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28  }else{.      if(
6d00: 20 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e   isExcl )  pFd->
6d10: 65 78 63 6c 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61  excllock &= (~ma
6d20: 73 6b 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  sk);.      if( !
6d30: 69 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68  isExcl ) pFd->sh
6d40: 61 72 65 64 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61  aredlock &= (~ma
6d50: 73 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  sk);.    }.  }..
6d60: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6d70: 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73  static void tvfs
6d80: 53 68 6d 42 61 72 72 69 65 72 28 73 71 6c 69 74  ShmBarrier(sqlit
6d90: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b  e3_file *pFile){
6da0: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
6db0: 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  d = tvfsGetFd(pF
6dc0: 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20  ile);.  Testvfs 
6dd0: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
6de0: 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70  (pFd->pVfs->pApp
6df0: 44 61 74 61 29 3b 0a 0a 20 20 69 66 28 20 70 2d  Data);..  if( p-
6e00: 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d  >pScript && p->m
6e10: 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 42  ask&TESTVFS_SHMB
6e20: 41 52 52 49 45 52 5f 4d 41 53 4b 20 29 7b 0a 20  ARRIER_MASK ){. 
6e30: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
6e40: 20 3d 20 70 46 64 2d 3e 70 53 68 6d 20 3f 20 70   = pFd->pShm ? p
6e50: 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 20  Fd->pShm->zFile 
6e60: 3a 20 22 22 3b 0a 20 20 20 20 74 76 66 73 45 78  : "";.    tvfsEx
6e70: 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 42 61  ecTcl(p, "xShmBa
6e80: 72 72 69 65 72 22 2c 20 54 63 6c 5f 4e 65 77 53  rrier", Tcl_NewS
6e90: 74 72 69 6e 67 4f 62 6a 28 7a 2c 20 2d 31 29 2c  tringObj(z, -1),
6ea0: 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30 2c   pFd->pShmId, 0,
6eb0: 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20   0);.  }..  if( 
6ec0: 70 2d 3e 69 73 46 75 6c 6c 73 68 6d 20 29 7b 0a  p->isFullshm ){.
6ed0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68 6d      sqlite3OsShm
6ee0: 42 61 72 72 69 65 72 28 70 46 64 2d 3e 70 52 65  Barrier(pFd->pRe
6ef0: 61 6c 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b  al);.    return;
6f00: 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69  .  }.}..static i
6f10: 6e 74 20 74 76 66 73 53 68 6d 55 6e 6d 61 70 28  nt tvfsShmUnmap(
6f20: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
6f30: 2a 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 64 65  *pFile,.  int de
6f40: 6c 65 74 65 46 6c 61 67 0a 29 7b 0a 20 20 69 6e  leteFlag.){.  in
6f50: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
6f60: 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70  ;.  TestvfsFd *p
6f70: 46 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70  Fd = tvfsGetFd(p
6f80: 46 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73  File);.  Testvfs
6f90: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
6fa0: 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70  )(pFd->pVfs->pAp
6fb0: 70 44 61 74 61 29 3b 0a 20 20 54 65 73 74 76 66  pData);.  Testvf
6fc0: 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  sBuffer *pBuffer
6fd0: 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b 0a 20 20   = pFd->pShm;.  
6fe0: 54 65 73 74 76 66 73 46 64 20 2a 2a 70 70 46 64  TestvfsFd **ppFd
6ff0: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 69 73 46 75  ;..  if( p->isFu
7000: 6c 6c 73 68 6d 20 29 7b 0a 20 20 20 20 72 65 74  llshm ){.    ret
7010: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 68 6d  urn sqlite3OsShm
7020: 55 6e 6d 61 70 28 70 46 64 2d 3e 70 52 65 61 6c  Unmap(pFd->pReal
7030: 2c 20 64 65 6c 65 74 65 46 6c 61 67 29 3b 0a 20  , deleteFlag);. 
7040: 20 7d 0a 0a 20 20 69 66 28 20 21 70 42 75 66 66   }..  if( !pBuff
7050: 65 72 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  er ) return SQLI
7060: 54 45 5f 4f 4b 3b 0a 20 20 61 73 73 65 72 74 28  TE_OK;.  assert(
7070: 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26 26 20   pFd->pShmId && 
7080: 70 46 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a 20 20  pFd->pShm );..  
7090: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
70a0: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
70b0: 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20  S_SHMCLOSE_MASK 
70c0: 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54  ){.    tvfsExecT
70d0: 63 6c 28 70 2c 20 22 78 53 68 6d 55 6e 6d 61 70  cl(p, "xShmUnmap
70e0: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
70f0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
7100: 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d  ->pShm->zFile, -
7110: 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c  1), pFd->pShmId,
7120: 20 30 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20   0, 0.    );.   
7130: 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28   tvfsResultCode(
7140: 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20  p, &rc);.  }..  
7150: 66 6f 72 28 70 70 46 64 3d 26 70 42 75 66 66 65  for(ppFd=&pBuffe
7160: 72 2d 3e 70 46 69 6c 65 3b 20 2a 70 70 46 64 21  r->pFile; *ppFd!
7170: 3d 70 46 64 3b 20 70 70 46 64 3d 26 28 28 2a 70  =pFd; ppFd=&((*p
7180: 70 46 64 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20  pFd)->pNext));. 
7190: 20 61 73 73 65 72 74 28 20 28 2a 70 70 46 64 29   assert( (*ppFd)
71a0: 3d 3d 70 46 64 20 29 3b 0a 20 20 2a 70 70 46 64  ==pFd );.  *ppFd
71b0: 20 3d 20 70 46 64 2d 3e 70 4e 65 78 74 3b 0a 20   = pFd->pNext;. 
71c0: 20 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20 30 3b   pFd->pNext = 0;
71d0: 0a 0a 20 20 69 66 28 20 70 42 75 66 66 65 72 2d  ..  if( pBuffer-
71e0: 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20  >pFile==0 ){.   
71f0: 20 69 6e 74 20 69 3b 0a 20 20 20 20 54 65 73 74   int i;.    Test
7200: 76 66 73 42 75 66 66 65 72 20 2a 2a 70 70 3b 0a  vfsBuffer **pp;.
7210: 20 20 20 20 66 6f 72 28 70 70 3d 26 70 2d 3e 70      for(pp=&p->p
7220: 42 75 66 66 65 72 3b 20 2a 70 70 21 3d 70 42 75  Buffer; *pp!=pBu
7230: 66 66 65 72 3b 20 70 70 3d 26 28 28 2a 70 70 29  ffer; pp=&((*pp)
7240: 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 2a  ->pNext));.    *
7250: 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78  pp = (*pp)->pNex
7260: 74 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  t;.    for(i=0; 
7270: 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69  pBuffer->aPage[i
7280: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63  ]; i++){.      c
7290: 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 42  kfree((char *)pB
72a0: 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 29  uffer->aPage[i])
72b0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 6b 66 72  ;.    }.    ckfr
72c0: 65 65 28 28 63 68 61 72 20 2a 29 70 42 75 66 66  ee((char *)pBuff
72d0: 65 72 29 3b 0a 20 20 7d 0a 20 20 70 46 64 2d 3e  er);.  }.  pFd->
72e0: 70 53 68 6d 20 3d 20 30 3b 0a 0a 20 20 72 65 74  pShm = 0;..  ret
72f0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
7300: 63 20 69 6e 74 20 74 76 66 73 46 65 74 63 68 28  c int tvfsFetch(
7310: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  .    sqlite3_fil
7320: 65 20 2a 70 46 69 6c 65 2c 20 0a 20 20 20 20 73  e *pFile, .    s
7330: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
7340: 73 74 2c 20 0a 20 20 20 20 69 6e 74 20 69 41 6d  st, .    int iAm
7350: 74 2c 20 0a 20 20 20 20 76 6f 69 64 20 2a 2a 70  t, .    void **p
7360: 70 0a 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  p.){.  TestvfsFd
7370: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
7380: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
7390: 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 65 74 63  rn sqlite3OsFetc
73a0: 68 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 69 4f  h(pFd->pReal, iO
73b0: 66 73 74 2c 20 69 41 6d 74 2c 20 70 70 29 3b 0a  fst, iAmt, pp);.
73c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  }..static int tv
73d0: 66 73 55 6e 66 65 74 63 68 28 73 71 6c 69 74 65  fsUnfetch(sqlite
73e0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73  3_file *pFile, s
73f0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
7400: 73 74 2c 20 76 6f 69 64 20 2a 70 29 7b 0a 20 20  st, void *p){.  
7410: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
7420: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
7430: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  );.  return sqli
7440: 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70 46 64  te3OsUnfetch(pFd
7450: 2d 3e 70 52 65 61 6c 2c 20 69 4f 66 73 74 2c 20  ->pReal, iOfst, 
7460: 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  p);.}..static in
7470: 74 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63 6d  t testvfs_obj_cm
7480: 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20  d(.  ClientData 
7490: 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  cd,.  Tcl_Interp
74a0: 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20   *interp,.  int 
74b0: 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20  objc,.  Tcl_Obj 
74c0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b  *CONST objv[].){
74d0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
74e0: 28 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a 0a  (Testvfs *)cd;..
74f0: 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20 7b    enum DB_enum {
7500: 20 0a 20 20 20 20 43 4d 44 5f 53 48 4d 2c 20 43   .    CMD_SHM, C
7510: 4d 44 5f 44 45 4c 45 54 45 2c 20 43 4d 44 5f 46  MD_DELETE, CMD_F
7520: 49 4c 54 45 52 2c 20 43 4d 44 5f 49 4f 45 52 52  ILTER, CMD_IOERR
7530: 2c 20 43 4d 44 5f 53 43 52 49 50 54 2c 20 0a 20  , CMD_SCRIPT, . 
7540: 20 20 20 43 4d 44 5f 44 45 56 43 48 41 52 2c 20     CMD_DEVCHAR, 
7550: 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a 45 2c 20  CMD_SECTORSIZE, 
7560: 43 4d 44 5f 46 55 4c 4c 45 52 52 2c 20 43 4d 44  CMD_FULLERR, CMD
7570: 5f 43 41 4e 54 4f 50 45 4e 45 52 52 0a 20 20 7d  _CANTOPENERR.  }
7580: 3b 0a 20 20 73 74 72 75 63 74 20 54 65 73 74 76  ;.  struct Testv
7590: 66 73 53 75 62 63 6d 64 20 7b 0a 20 20 20 20 63  fsSubcmd {.    c
75a0: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
75b0: 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20 65 43 6d  enum DB_enum eCm
75c0: 64 3b 0a 20 20 7d 20 61 53 75 62 63 6d 64 5b 5d  d;.  } aSubcmd[]
75d0: 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 68 6d 22   = {.    { "shm"
75e0: 2c 20 20 20 20 20 20 20 20 20 43 4d 44 5f 53 48  ,         CMD_SH
75f0: 4d 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20  M         },.   
7600: 20 7b 20 22 64 65 6c 65 74 65 22 2c 20 20 20 20   { "delete",    
7610: 20 20 43 4d 44 5f 44 45 4c 45 54 45 20 20 20 20    CMD_DELETE    
7620: 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66 69 6c 74    },.    { "filt
7630: 65 72 22 2c 20 20 20 20 20 20 43 4d 44 5f 46 49  er",      CMD_FI
7640: 4c 54 45 52 20 20 20 20 20 20 7d 2c 0a 20 20 20  LTER      },.   
7650: 20 7b 20 22 69 6f 65 72 72 22 2c 20 20 20 20 20   { "ioerr",     
7660: 20 20 43 4d 44 5f 49 4f 45 52 52 20 20 20 20 20    CMD_IOERR     
7670: 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66 75 6c 6c    },.    { "full
7680: 65 72 72 22 2c 20 20 20 20 20 43 4d 44 5f 46 55  err",     CMD_FU
7690: 4c 4c 45 52 52 20 20 20 20 20 7d 2c 0a 20 20 20  LLERR     },.   
76a0: 20 7b 20 22 63 61 6e 74 6f 70 65 6e 65 72 72 22   { "cantopenerr"
76b0: 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45 52  , CMD_CANTOPENER
76c0: 52 20 7d 2c 0a 20 20 20 20 7b 20 22 73 63 72 69  R },.    { "scri
76d0: 70 74 22 2c 20 20 20 20 20 20 43 4d 44 5f 53 43  pt",      CMD_SC
76e0: 52 49 50 54 20 20 20 20 20 20 7d 2c 0a 20 20 20  RIPT      },.   
76f0: 20 7b 20 22 64 65 76 63 68 61 72 22 2c 20 20 20   { "devchar",   
7700: 20 20 43 4d 44 5f 44 45 56 43 48 41 52 20 20 20    CMD_DEVCHAR   
7710: 20 20 7d 2c 0a 20 20 20 20 7b 20 22 73 65 63 74    },.    { "sect
7720: 6f 72 73 69 7a 65 22 2c 20 20 43 4d 44 5f 53 45  orsize",  CMD_SE
7730: 43 54 4f 52 53 49 5a 45 20 20 7d 2c 0a 20 20 20  CTORSIZE  },.   
7740: 20 7b 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a 20   { 0, 0 }.  };. 
7750: 20 69 6e 74 20 69 3b 0a 20 20 0a 20 20 69 66 28   int i;.  .  if(
7760: 20 6f 62 6a 63 3c 32 20 29 7b 0a 20 20 20 20 54   objc<2 ){.    T
7770: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
7780: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
7790: 20 22 53 55 42 43 4f 4d 4d 41 4e 44 20 2e 2e 2e   "SUBCOMMAND ...
77a0: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
77b0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
77c0: 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 64 65 78  if( Tcl_GetIndex
77d0: 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 0a 20  FromObjStruct(. 
77e0: 20 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 6f         interp, o
77f0: 62 6a 76 5b 31 5d 2c 20 61 53 75 62 63 6d 64 2c  bjv[1], aSubcmd,
7800: 20 73 69 7a 65 6f 66 28 61 53 75 62 63 6d 64 5b   sizeof(aSubcmd[
7810: 30 5d 29 2c 20 22 73 75 62 63 6f 6d 6d 61 6e 64  0]), "subcommand
7820: 22 2c 20 30 2c 20 26 69 29 20 0a 20 20 29 7b 0a  ", 0, &i) .  ){.
7830: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
7840: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f  RROR;.  }.  Tcl_
7850: 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65  ResetResult(inte
7860: 72 70 29 3b 0a 0a 20 20 73 77 69 74 63 68 28 20  rp);..  switch( 
7870: 61 53 75 62 63 6d 64 5b 69 5d 2e 65 43 6d 64 20  aSubcmd[i].eCmd 
7880: 29 7b 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f  ){.    case CMD_
7890: 53 48 4d 3a 20 7b 0a 20 20 20 20 20 20 54 63 6c  SHM: {.      Tcl
78a0: 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20 20 20 20  _Obj *pObj;.    
78b0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 20 20 20 20    int rc;.      
78c0: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70  TestvfsBuffer *p
78d0: 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20 63 68  Buffer;.      ch
78e0: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
78f0: 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 26 26 20   if( objc!=3 && 
7900: 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20 20 20  objc!=4 ){.     
7910: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
7920: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
7930: 62 6a 76 2c 20 22 46 49 4c 45 20 3f 56 41 4c 55  bjv, "FILE ?VALU
7940: 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  E?");.        re
7950: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
7960: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e        }.      zN
7970: 61 6d 65 20 3d 20 63 6b 61 6c 6c 6f 63 28 70 2d  ame = ckalloc(p-
7980: 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68  >pParent->mxPath
7990: 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20 72 63 20  name);.      rc 
79a0: 3d 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46  = p->pParent->xF
79b0: 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 20  ullPathname(.   
79c0: 20 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e         p->pParen
79d0: 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  t, Tcl_GetString
79e0: 28 6f 62 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20  (objv[2]), .    
79f0: 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74        p->pParent
7a00: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e  ->mxPathname, zN
7a10: 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ame.      );.   
7a20: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
7a30: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
7a40: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
7a50: 28 69 6e 74 65 72 70 2c 20 22 66 61 69 6c 65 64  (interp, "failed
7a60: 20 74 6f 20 67 65 74 20 66 75 6c 6c 20 70 61 74   to get full pat
7a70: 68 3a 20 22 2c 0a 20 20 20 20 20 20 20 20 20 20  h: ",.          
7a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
7a90: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
7aa0: 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 20  v[2]), 0);.     
7ab0: 20 20 20 63 6b 66 72 65 65 28 7a 4e 61 6d 65 29     ckfree(zName)
7ac0: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7ad0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
7ae0: 20 20 7d 0a 20 20 20 20 20 20 66 6f 72 28 70 42    }.      for(pB
7af0: 75 66 66 65 72 3d 70 2d 3e 70 42 75 66 66 65 72  uffer=p->pBuffer
7b00: 3b 20 70 42 75 66 66 65 72 3b 20 70 42 75 66 66  ; pBuffer; pBuff
7b10: 65 72 3d 70 42 75 66 66 65 72 2d 3e 70 4e 65 78  er=pBuffer->pNex
7b20: 74 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t){.        if( 
7b30: 30 3d 3d 73 74 72 63 6d 70 28 70 42 75 66 66 65  0==strcmp(pBuffe
7b40: 72 2d 3e 7a 46 69 6c 65 2c 20 7a 4e 61 6d 65 29  r->zFile, zName)
7b50: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
7b60: 7d 0a 20 20 20 20 20 20 63 6b 66 72 65 65 28 7a  }.      ckfree(z
7b70: 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 69 66 28  Name);.      if(
7b80: 20 21 70 42 75 66 66 65 72 20 29 7b 0a 20 20 20   !pBuffer ){.   
7b90: 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52       Tcl_AppendR
7ba0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e  esult(interp, "n
7bb0: 6f 20 73 75 63 68 20 66 69 6c 65 3a 20 22 2c 20  o such file: ", 
7bc0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
7bd0: 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20  jv[2]), 0);.    
7be0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
7bf0: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
7c00: 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20      if( objc==4 
7c10: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  ){.        int n
7c20: 3b 0a 20 20 20 20 20 20 20 20 75 38 20 2a 61 20  ;.        u8 *a 
7c30: 3d 20 54 63 6c 5f 47 65 74 42 79 74 65 41 72 72  = Tcl_GetByteArr
7c40: 61 79 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 33  ayFromObj(objv[3
7c50: 5d 2c 20 26 6e 29 3b 0a 20 20 20 20 20 20 20 20  ], &n);.        
7c60: 69 6e 74 20 70 67 73 7a 20 3d 20 70 42 75 66 66  int pgsz = pBuff
7c70: 65 72 2d 3e 70 67 73 7a 3b 0a 20 20 20 20 20 20  er->pgsz;.      
7c80: 20 20 69 66 28 20 70 67 73 7a 3d 3d 30 20 29 20    if( pgsz==0 ) 
7c90: 70 67 73 7a 20 3d 20 36 35 35 33 36 3b 0a 20 20  pgsz = 65536;.  
7ca0: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
7cb0: 2a 70 67 73 7a 3c 6e 3b 20 69 2b 2b 29 7b 0a 20  *pgsz<n; i++){. 
7cc0: 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79           int nBy
7cd0: 74 65 20 3d 20 70 67 73 7a 3b 0a 20 20 20 20 20  te = pgsz;.     
7ce0: 20 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50 61       tvfsAllocPa
7cf0: 67 65 28 70 42 75 66 66 65 72 2c 20 69 2c 20 70  ge(pBuffer, i, p
7d00: 67 73 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20  gsz);.          
7d10: 69 66 28 20 6e 2d 69 2a 70 67 73 7a 3c 70 67 73  if( n-i*pgsz<pgs
7d20: 7a 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  z ){.           
7d30: 20 6e 42 79 74 65 20 3d 20 6e 3b 0a 20 20 20 20   nByte = n;.    
7d40: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
7d50: 20 20 6d 65 6d 63 70 79 28 70 42 75 66 66 65 72    memcpy(pBuffer
7d60: 2d 3e 61 50 61 67 65 5b 69 5d 2c 20 26 61 5b 69  ->aPage[i], &a[i
7d70: 2a 70 67 73 7a 5d 2c 20 6e 42 79 74 65 29 3b 0a  *pgsz], nByte);.
7d80: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7d90: 7d 0a 0a 20 20 20 20 20 20 70 4f 62 6a 20 3d 20  }..      pObj = 
7da0: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
7db0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 70 42 75      for(i=0; pBu
7dc0: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 3b 20  ffer->aPage[i]; 
7dd0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  i++){.        in
7de0: 74 20 70 67 73 7a 20 3d 20 70 42 75 66 66 65 72  t pgsz = pBuffer
7df0: 2d 3e 70 67 73 7a 3b 0a 20 20 20 20 20 20 20 20  ->pgsz;.        
7e00: 69 66 28 20 70 67 73 7a 3d 3d 30 20 29 20 70 67  if( pgsz==0 ) pg
7e10: 73 7a 20 3d 20 36 35 35 33 36 3b 0a 20 20 20 20  sz = 65536;.    
7e20: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 4f 62      Tcl_AppendOb
7e30: 6a 54 6f 4f 62 6a 28 70 4f 62 6a 2c 20 54 63 6c  jToObj(pObj, Tcl
7e40: 5f 4e 65 77 42 79 74 65 41 72 72 61 79 4f 62 6a  _NewByteArrayObj
7e50: 28 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b  (pBuffer->aPage[
7e60: 69 5d 2c 20 70 67 73 7a 29 29 3b 0a 20 20 20 20  i], pgsz));.    
7e70: 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65    }.      Tcl_Se
7e80: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
7e90: 70 2c 20 70 4f 62 6a 29 3b 0a 20 20 20 20 20 20  p, pObj);.      
7ea0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
7eb0: 20 20 2f 2a 20 20 54 45 53 54 56 46 53 20 66 69    /*  TESTVFS fi
7ec0: 6c 74 65 72 20 4d 45 54 48 4f 44 2d 4c 49 53 54  lter METHOD-LIST
7ed0: 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20  .    **.    **  
7ee0: 20 20 20 41 63 74 69 76 61 74 65 20 73 70 65 63     Activate spec
7ef0: 69 61 6c 20 70 72 6f 63 65 73 73 69 6e 67 20 66  ial processing f
7f00: 6f 72 20 74 68 6f 73 65 20 6d 65 74 68 6f 64 73  or those methods
7f10: 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 74 68   contained in th
7f20: 65 20 6c 69 73 74 0a 20 20 20 20 2a 2f 0a 20 20  e list.    */.  
7f30: 20 20 63 61 73 65 20 43 4d 44 5f 46 49 4c 54 45    case CMD_FILTE
7f40: 52 3a 20 7b 0a 20 20 20 20 20 20 73 74 61 74 69  R: {.      stati
7f50: 63 20 73 74 72 75 63 74 20 56 66 73 4d 65 74 68  c struct VfsMeth
7f60: 6f 64 20 7b 0a 20 20 20 20 20 20 20 20 63 68 61  od {.        cha
7f70: 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20  r *zName;.      
7f80: 20 20 69 6e 74 20 6d 61 73 6b 3b 0a 20 20 20 20    int mask;.    
7f90: 20 20 7d 20 76 66 73 6d 65 74 68 6f 64 20 5b 5d    } vfsmethod []
7fa0: 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22   = {.        { "
7fb0: 78 53 68 6d 4f 70 65 6e 22 2c 20 20 20 20 20 20  xShmOpen",      
7fc0: 20 20 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d       TESTVFS_SHM
7fd0: 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  OPEN_MASK },.   
7fe0: 20 20 20 20 20 7b 20 22 78 53 68 6d 4c 6f 63 6b       { "xShmLock
7ff0: 22 2c 20 20 20 20 20 20 20 20 20 20 20 54 45 53  ",           TES
8000: 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53  TVFS_SHMLOCK_MAS
8010: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
8020: 78 53 68 6d 42 61 72 72 69 65 72 22 2c 20 20 20  xShmBarrier",   
8030: 20 20 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d       TESTVFS_SHM
8040: 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a  BARRIER_MASK },.
8050: 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 55          { "xShmU
8060: 6e 6d 61 70 22 2c 20 20 20 20 20 20 20 20 20 20  nmap",          
8070: 54 45 53 54 56 46 53 5f 53 48 4d 43 4c 4f 53 45  TESTVFS_SHMCLOSE
8080: 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20  _MASK },.       
8090: 20 7b 20 22 78 53 68 6d 4d 61 70 22 2c 20 20 20   { "xShmMap",   
80a0: 20 20 20 20 20 20 20 20 20 54 45 53 54 56 46 53           TESTVFS
80b0: 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 7d 2c 0a  _SHMMAP_MASK },.
80c0: 20 20 20 20 20 20 20 20 7b 20 22 78 53 79 6e 63          { "xSync
80d0: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ",              
80e0: 54 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53  TESTVFS_SYNC_MAS
80f0: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
8100: 78 44 65 6c 65 74 65 22 2c 20 20 20 20 20 20 20  xDelete",       
8110: 20 20 20 20 20 54 45 53 54 56 46 53 5f 44 45 4c       TESTVFS_DEL
8120: 45 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20  ETE_MASK },.    
8130: 20 20 20 20 7b 20 22 78 57 72 69 74 65 22 2c 20      { "xWrite", 
8140: 20 20 20 20 20 20 20 20 20 20 20 20 54 45 53 54              TEST
8150: 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 7d  VFS_WRITE_MASK }
8160: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 52 65  ,.        { "xRe
8170: 61 64 22 2c 20 20 20 20 20 20 20 20 20 20 20 20  ad",            
8180: 20 20 54 45 53 54 56 46 53 5f 52 45 41 44 5f 4d    TESTVFS_READ_M
8190: 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  ASK },.        {
81a0: 20 22 78 54 72 75 6e 63 61 74 65 22 2c 20 20 20   "xTruncate",   
81b0: 20 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 54         TESTVFS_T
81c0: 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 7d 2c 0a  RUNCATE_MASK },.
81d0: 20 20 20 20 20 20 20 20 7b 20 22 78 4f 70 65 6e          { "xOpen
81e0: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ",              
81f0: 54 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53  TESTVFS_OPEN_MAS
8200: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
8210: 78 43 6c 6f 73 65 22 2c 20 20 20 20 20 20 20 20  xClose",        
8220: 20 20 20 20 20 54 45 53 54 56 46 53 5f 43 4c 4f       TESTVFS_CLO
8230: 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  SE_MASK },.     
8240: 20 20 20 7b 20 22 78 41 63 63 65 73 73 22 2c 20     { "xAccess", 
8250: 20 20 20 20 20 20 20 20 20 20 20 54 45 53 54 56             TESTV
8260: 46 53 5f 41 43 43 45 53 53 5f 4d 41 53 4b 20 7d  FS_ACCESS_MASK }
8270: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 46 75  ,.        { "xFu
8280: 6c 6c 50 61 74 68 6e 61 6d 65 22 2c 20 20 20 20  llPathname",    
8290: 20 20 54 45 53 54 56 46 53 5f 46 55 4c 4c 50 41    TESTVFS_FULLPA
82a0: 54 48 4e 41 4d 45 5f 4d 41 53 4b 20 7d 2c 0a 20  THNAME_MASK },. 
82b0: 20 20 20 20 20 20 20 7b 20 22 78 55 6e 6c 6f 63         { "xUnloc
82c0: 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 54  k",            T
82d0: 45 53 54 56 46 53 5f 55 4e 4c 4f 43 4b 5f 4d 41  ESTVFS_UNLOCK_MA
82e0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
82f0: 22 78 4c 6f 63 6b 22 2c 20 20 20 20 20 20 20 20  "xLock",        
8300: 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 4c 4f        TESTVFS_LO
8310: 43 4b 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  CK_MASK },.     
8320: 20 20 20 7b 20 22 78 43 68 65 63 6b 52 65 73 65     { "xCheckRese
8330: 72 76 65 64 4c 6f 63 6b 22 2c 20 54 45 53 54 56  rvedLock", TESTV
8340: 46 53 5f 43 4b 4c 4f 43 4b 5f 4d 41 53 4b 20 7d  FS_CKLOCK_MASK }
8350: 2c 0a 20 20 20 20 20 20 7d 3b 0a 20 20 20 20 20  ,.      };.     
8360: 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70 45 6c 65   Tcl_Obj **apEle
8370: 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  m = 0;.      int
8380: 20 6e 45 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20   nElem = 0;.    
8390: 20 20 69 6e 74 20 6d 61 73 6b 20 3d 20 30 3b 0a    int mask = 0;.
83a0: 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21 3d        if( objc!=
83b0: 33 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c  3 ){.        Tcl
83c0: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
83d0: 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22  terp, 2, objv, "
83e0: 4c 49 53 54 22 29 3b 0a 20 20 20 20 20 20 20 20  LIST");.        
83f0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
8400: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
8410: 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47  if( Tcl_ListObjG
8420: 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72  etElements(inter
8430: 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45 6c  p, objv[2], &nEl
8440: 65 6d 2c 20 26 61 70 45 6c 65 6d 29 20 29 7b 0a  em, &apElem) ){.
8450: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
8460: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
8470: 7d 0a 20 20 20 20 20 20 54 63 6c 5f 52 65 73 65  }.      Tcl_Rese
8480: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  tResult(interp);
8490: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
84a0: 69 3c 6e 45 6c 65 6d 3b 20 69 2b 2b 29 7b 0a 20  i<nElem; i++){. 
84b0: 20 20 20 20 20 20 20 69 6e 74 20 69 4d 65 74 68         int iMeth
84c0: 6f 64 3b 0a 20 20 20 20 20 20 20 20 63 68 61 72  od;.        char
84d0: 20 2a 7a 45 6c 65 6d 20 3d 20 54 63 6c 5f 47 65   *zElem = Tcl_Ge
84e0: 74 53 74 72 69 6e 67 28 61 70 45 6c 65 6d 5b 69  tString(apElem[i
84f0: 5d 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  ]);.        for(
8500: 69 4d 65 74 68 6f 64 3d 30 3b 20 69 4d 65 74 68  iMethod=0; iMeth
8510: 6f 64 3c 41 72 72 61 79 53 69 7a 65 28 76 66 73  od<ArraySize(vfs
8520: 6d 65 74 68 6f 64 29 3b 20 69 4d 65 74 68 6f 64  method); iMethod
8530: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ++){.          i
8540: 66 28 20 73 74 72 63 6d 70 28 7a 45 6c 65 6d 2c  f( strcmp(zElem,
8550: 20 76 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74 68   vfsmethod[iMeth
8560: 6f 64 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b  od].zName)==0 ){
8570: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 61 73  .            mas
8580: 6b 20 7c 3d 20 76 66 73 6d 65 74 68 6f 64 5b 69  k |= vfsmethod[i
8590: 4d 65 74 68 6f 64 5d 2e 6d 61 73 6b 3b 0a 20 20  Method].mask;.  
85a0: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
85b0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
85c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
85d0: 66 28 20 69 4d 65 74 68 6f 64 3d 3d 41 72 72 61  f( iMethod==Arra
85e0: 79 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64 29  ySize(vfsmethod)
85f0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54 63   ){.          Tc
8600: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
8610: 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 20  nterp, "unknown 
8620: 6d 65 74 68 6f 64 3a 20 22 2c 20 7a 45 6c 65 6d  method: ", zElem
8630: 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , 0);.          
8640: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
8650: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
8660: 20 20 7d 0a 20 20 20 20 20 20 70 2d 3e 6d 61 73    }.      p->mas
8670: 6b 20 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20  k = mask;.      
8680: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
8690: 20 20 2f 2a 0a 20 20 20 20 2a 2a 20 20 54 45 53    /*.    **  TES
86a0: 54 56 46 53 20 73 63 72 69 70 74 20 3f 53 43 52  TVFS script ?SCR
86b0: 49 50 54 3f 0a 20 20 20 20 2a 2a 0a 20 20 20 20  IPT?.    **.    
86c0: 2a 2a 20 20 51 75 65 72 79 20 6f 72 20 73 65 74  **  Query or set
86d0: 20 74 68 65 20 73 63 72 69 70 74 20 74 6f 20 62   the script to b
86e0: 65 20 72 75 6e 20 77 68 65 6e 20 66 69 6c 74 65  e run when filte
86f0: 72 65 64 20 56 46 53 20 65 76 65 6e 74 73 0a 20  red VFS events. 
8700: 20 20 20 2a 2a 20 20 6f 63 63 75 72 2e 0a 20 20     **  occur..  
8710: 20 20 2a 2f 0a 20 20 20 20 63 61 73 65 20 43 4d    */.    case CM
8720: 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20 20 20 20  D_SCRIPT: {.    
8730: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
8740: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42 79  .        int nBy
8750: 74 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  te;.        if( 
8760: 70 2d 3e 70 53 63 72 69 70 74 20 29 7b 0a 20 20  p->pScript ){.  
8770: 20 20 20 20 20 20 20 20 54 63 6c 5f 44 65 63 72          Tcl_Decr
8780: 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72  RefCount(p->pScr
8790: 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ipt);.          
87a0: 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 30 3b 0a  p->pScript = 0;.
87b0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
87c0: 20 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46    Tcl_GetStringF
87d0: 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20  romObj(objv[2], 
87e0: 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20  &nByte);.       
87f0: 20 69 66 28 20 6e 42 79 74 65 3e 30 20 29 7b 0a   if( nByte>0 ){.
8800: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70 53 63            p->pSc
8810: 72 69 70 74 20 3d 20 54 63 6c 5f 44 75 70 6c 69  ript = Tcl_Dupli
8820: 63 61 74 65 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29  cateObj(objv[2])
8830: 3b 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f  ;.          Tcl_
8840: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e  IncrRefCount(p->
8850: 70 53 63 72 69 70 74 29 3b 0a 20 20 20 20 20 20  pScript);.      
8860: 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20    }.      }else 
8870: 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20  if( objc!=2 ){. 
8880: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
8890: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
88a0: 32 2c 20 6f 62 6a 76 2c 20 22 3f 53 43 52 49 50  2, objv, "?SCRIP
88b0: 54 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  T?");.        re
88c0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
88d0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 54        }..      T
88e0: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
88f0: 6e 74 65 72 70 29 3b 0a 20 20 20 20 20 20 69 66  nterp);.      if
8900: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29 20 54  ( p->pScript ) T
8910: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
8920: 69 6e 74 65 72 70 2c 20 70 2d 3e 70 53 63 72 69  interp, p->pScri
8930: 70 74 29 3b 0a 0a 20 20 20 20 20 20 62 72 65 61  pt);..      brea
8940: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  k;.    }..    /*
8950: 0a 20 20 20 20 2a 2a 20 54 45 53 54 56 46 53 20  .    ** TESTVFS 
8960: 69 6f 65 72 72 20 3f 49 46 41 49 4c 20 50 45 52  ioerr ?IFAIL PER
8970: 53 49 53 54 3f 0a 20 20 20 20 2a 2a 0a 20 20 20  SIST?.    **.   
8980: 20 2a 2a 20 20 20 57 68 65 72 65 20 49 46 41 49   **   Where IFAI
8990: 4c 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20  L is an integer 
89a0: 61 6e 64 20 50 45 52 53 49 53 54 20 69 73 20 62  and PERSIST is b
89b0: 6f 6f 6c 65 61 6e 2e 0a 20 20 20 20 2a 2f 0a 20  oolean..    */. 
89c0: 20 20 20 63 61 73 65 20 43 4d 44 5f 43 41 4e 54     case CMD_CANT
89d0: 4f 50 45 4e 45 52 52 3a 0a 20 20 20 20 63 61 73  OPENERR:.    cas
89e0: 65 20 43 4d 44 5f 49 4f 45 52 52 3a 0a 20 20 20  e CMD_IOERR:.   
89f0: 20 63 61 73 65 20 43 4d 44 5f 46 55 4c 4c 45 52   case CMD_FULLER
8a00: 52 3a 20 7b 0a 20 20 20 20 20 20 54 65 73 74 46  R: {.      TestF
8a10: 61 75 6c 74 49 6e 6a 65 63 74 20 2a 70 54 65 73  aultInject *pTes
8a20: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  t = 0;.      int
8a30: 20 69 52 65 74 3b 0a 0a 20 20 20 20 20 20 73 77   iRet;..      sw
8a40: 69 74 63 68 28 20 61 53 75 62 63 6d 64 5b 69 5d  itch( aSubcmd[i]
8a50: 2e 65 43 6d 64 20 29 7b 0a 20 20 20 20 20 20 20  .eCmd ){.       
8a60: 20 63 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a   case CMD_IOERR:
8a70: 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 69 6f 65   pTest = &p->ioe
8a80: 72 72 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20  rr_err; break;. 
8a90: 20 20 20 20 20 20 20 63 61 73 65 20 43 4d 44 5f         case CMD_
8aa0: 46 55 4c 4c 45 52 52 3a 20 70 54 65 73 74 20 3d  FULLERR: pTest =
8ab0: 20 26 70 2d 3e 66 75 6c 6c 5f 65 72 72 3b 20 62   &p->full_err; b
8ac0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
8ad0: 73 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45  se CMD_CANTOPENE
8ae0: 52 52 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e  RR: pTest = &p->
8af0: 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 20 62 72  cantopen_err; br
8b00: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 64 65 66  eak;.        def
8b10: 61 75 6c 74 3a 20 61 73 73 65 72 74 28 30 29 3b  ault: assert(0);
8b20: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
8b30: 52 65 74 20 3d 20 70 54 65 73 74 2d 3e 6e 46 61  Ret = pTest->nFa
8b40: 69 6c 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d  il;.      pTest-
8b50: 3e 6e 46 61 69 6c 20 3d 20 30 3b 0a 20 20 20 20  >nFail = 0;.    
8b60: 20 20 70 54 65 73 74 2d 3e 65 46 61 75 6c 74 20    pTest->eFault 
8b70: 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 65 73 74  = 0;.      pTest
8b80: 2d 3e 69 43 6e 74 20 3d 20 30 3b 0a 0a 20 20 20  ->iCnt = 0;..   
8b90: 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20 29     if( objc==4 )
8ba0: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 43  {.        int iC
8bb0: 6e 74 2c 20 69 50 65 72 73 69 73 74 3b 0a 20 20  nt, iPersist;.  
8bc0: 20 20 20 20 20 20 69 66 28 20 54 43 4c 5f 4f 4b        if( TCL_OK
8bd0: 21 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d  !=Tcl_GetIntFrom
8be0: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
8bf0: 5b 32 5d 2c 20 26 69 43 6e 74 29 0a 20 20 20 20  [2], &iCnt).    
8c00: 20 20 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b 21 3d       || TCL_OK!=
8c10: 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72  Tcl_GetBooleanFr
8c20: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
8c30: 6a 76 5b 33 5d 2c 20 26 69 50 65 72 73 69 73 74  jv[3], &iPersist
8c40: 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20  ).        ){.   
8c50: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
8c60: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20  L_ERROR;.       
8c70: 20 7d 0a 20 20 20 20 20 20 20 20 70 54 65 73 74   }.        pTest
8c80: 2d 3e 65 46 61 75 6c 74 20 3d 20 69 50 65 72 73  ->eFault = iPers
8c90: 69 73 74 3f 46 41 55 4c 54 5f 49 4e 4a 45 43 54  ist?FAULT_INJECT
8ca0: 5f 50 45 52 53 49 53 54 45 4e 54 3a 46 41 55 4c  _PERSISTENT:FAUL
8cb0: 54 5f 49 4e 4a 45 43 54 5f 54 52 41 4e 53 49 45  T_INJECT_TRANSIE
8cc0: 4e 54 3b 0a 20 20 20 20 20 20 20 20 70 54 65 73  NT;.        pTes
8cd0: 74 2d 3e 69 43 6e 74 20 3d 20 69 43 6e 74 3b 0a  t->iCnt = iCnt;.
8ce0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
8cf0: 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 20  objc!=2 ){.     
8d00: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
8d10: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
8d20: 62 6a 76 2c 20 22 3f 43 4e 54 20 50 45 52 53 49  bjv, "?CNT PERSI
8d30: 53 54 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72  ST?");.        r
8d40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
8d50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54  .      }.      T
8d60: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
8d70: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49  interp, Tcl_NewI
8d80: 6e 74 4f 62 6a 28 69 52 65 74 29 29 3b 0a 20 20  ntObj(iRet));.  
8d90: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
8da0: 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 44  ..    case CMD_D
8db0: 45 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20 20 54  ELETE: {.      T
8dc0: 63 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61 6e 64  cl_DeleteCommand
8dd0: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74  (interp, Tcl_Get
8de0: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 29  String(objv[0]))
8df0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
8e00: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43     }..    case C
8e10: 4d 44 5f 44 45 56 43 48 41 52 3a 20 7b 0a 20 20  MD_DEVCHAR: {.  
8e20: 20 20 20 20 73 74 72 75 63 74 20 44 65 76 69 63      struct Devic
8e30: 65 46 6c 61 67 20 7b 0a 20 20 20 20 20 20 20 20  eFlag {.        
8e40: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
8e50: 20 20 20 20 20 69 6e 74 20 69 56 61 6c 75 65 3b       int iValue;
8e60: 0a 20 20 20 20 20 20 7d 20 61 46 6c 61 67 5b 5d  .      } aFlag[]
8e70: 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22   = {.        { "
8e80: 64 65 66 61 75 6c 74 22 2c 20 20 20 20 20 20 20  default",       
8e90: 20 20 20 20 20 20 20 20 2d 31 20 7d 2c 0a 20 20          -1 },.  
8ea0: 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 22        { "atomic"
8eb0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8ec0: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54   SQLITE_IOCAP_AT
8ed0: 4f 4d 49 43 20 20 20 20 20 20 20 20 20 20 20 20  OMIC            
8ee0: 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b      },.        {
8ef0: 20 22 61 74 6f 6d 69 63 35 31 32 22 2c 20 20 20   "atomic512",   
8f00: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8f10: 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 35 31 32  _IOCAP_ATOMIC512
8f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 2c 0a               },.
8f30: 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69          { "atomi
8f40: 63 31 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20  c1k",           
8f50: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
8f60: 41 54 4f 4d 49 43 31 4b 20 20 20 20 20 20 20 20  ATOMIC1K        
8f70: 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20        },.       
8f80: 20 7b 20 22 61 74 6f 6d 69 63 32 6b 22 2c 20 20   { "atomic2k",  
8f90: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
8fa0: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 32  TE_IOCAP_ATOMIC2
8fb0: 4b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d  K              }
8fc0: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f  ,.        { "ato
8fd0: 6d 69 63 34 6b 22 2c 20 20 20 20 20 20 20 20 20  mic4k",         
8fe0: 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41       SQLITE_IOCA
8ff0: 50 5f 41 54 4f 4d 49 43 34 4b 20 20 20 20 20 20  P_ATOMIC4K      
9000: 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20          },.     
9010: 20 20 20 7b 20 22 61 74 6f 6d 69 63 38 6b 22 2c     { "atomic8k",
9020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
9030: 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49  LITE_IOCAP_ATOMI
9040: 43 38 4b 20 20 20 20 20 20 20 20 20 20 20 20 20  C8K             
9050: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61   },.        { "a
9060: 74 6f 6d 69 63 31 36 6b 22 2c 20 20 20 20 20 20  tomic16k",      
9070: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f         SQLITE_IO
9080: 43 41 50 5f 41 54 4f 4d 49 43 31 36 4b 20 20 20  CAP_ATOMIC16K   
9090: 20 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20            },.   
90a0: 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 33 32       { "atomic32
90b0: 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  k",             
90c0: 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f  SQLITE_IOCAP_ATO
90d0: 4d 49 43 33 32 4b 20 20 20 20 20 20 20 20 20 20  MIC32K          
90e0: 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20     },.        { 
90f0: 22 61 74 6f 6d 69 63 36 34 6b 22 2c 20 20 20 20  "atomic64k",    
9100: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
9110: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 36 34 4b 20  IOCAP_ATOMIC64K 
9120: 20 20 20 20 20 20 20 20 20 20 20 20 7d 2c 0a 20              },. 
9130: 20 20 20 20 20 20 20 7b 20 22 73 65 71 75 65 6e         { "sequen
9140: 74 69 61 6c 22 2c 20 20 20 20 20 20 20 20 20 20  tial",          
9150: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53    SQLITE_IOCAP_S
9160: 45 51 55 45 4e 54 49 41 4c 20 20 20 20 20 20 20  EQUENTIAL       
9170: 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20       },.        
9180: 7b 20 22 73 61 66 65 5f 61 70 70 65 6e 64 22 2c  { "safe_append",
9190: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
91a0: 45 5f 49 4f 43 41 50 5f 53 41 46 45 5f 41 50 50  E_IOCAP_SAFE_APP
91b0: 45 4e 44 20 20 20 20 20 20 20 20 20 20 20 7d 2c  END           },
91c0: 0a 20 20 20 20 20 20 20 20 7b 20 22 75 6e 64 65  .        { "unde
91d0: 6c 65 74 61 62 6c 65 5f 77 68 65 6e 5f 6f 70 65  letable_when_ope
91e0: 6e 22 2c 20 53 51 4c 49 54 45 5f 49 4f 43 41 50  n", SQLITE_IOCAP
91f0: 5f 55 4e 44 45 4c 45 54 41 42 4c 45 5f 57 48 45  _UNDELETABLE_WHE
9200: 4e 5f 4f 50 45 4e 20 7d 2c 0a 20 20 20 20 20 20  N_OPEN },.      
9210: 20 20 7b 20 22 70 6f 77 65 72 73 61 66 65 5f 6f    { "powersafe_o
9220: 76 65 72 77 72 69 74 65 22 2c 20 20 20 53 51 4c  verwrite",   SQL
9230: 49 54 45 5f 49 4f 43 41 50 5f 50 4f 57 45 52 53  ITE_IOCAP_POWERS
9240: 41 46 45 5f 4f 56 45 52 57 52 49 54 45 20 20 20  AFE_OVERWRITE   
9250: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 69 6d  },.        { "im
9260: 6d 75 74 61 62 6c 65 22 2c 20 20 20 20 20 20 20  mutable",       
9270: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
9280: 41 50 5f 49 4d 4d 55 54 41 42 4c 45 20 20 20 20  AP_IMMUTABLE    
9290: 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20           },.    
92a0: 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 20      { 0, 0 }.   
92b0: 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f     };.      Tcl_
92c0: 4f 62 6a 20 2a 70 52 65 74 3b 0a 20 20 20 20 20  Obj *pRet;.     
92d0: 20 69 6e 74 20 69 46 6c 61 67 3b 0a 0a 20 20 20   int iFlag;..   
92e0: 20 20 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b     if( objc>3 ){
92f0: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f  .        Tcl_Wro
9300: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
9310: 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 41 54 54  , 2, objv, "?ATT
9320: 52 2d 4c 49 53 54 3f 22 29 3b 0a 20 20 20 20 20  R-LIST?");.     
9330: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
9340: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
9350: 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29     if( objc==3 )
9360: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b  {.        int j;
9370: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65  .        int iNe
9380: 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 54  w = 0;.        T
9390: 63 6c 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73 20 3d  cl_Obj **flags =
93a0: 20 30 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   0;.        int 
93b0: 6e 46 6c 61 67 73 20 3d 20 30 3b 0a 0a 20 20 20  nFlags = 0;..   
93c0: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 4c 69 73       if( Tcl_Lis
93d0: 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28  tObjGetElements(
93e0: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c  interp, objv[2],
93f0: 20 26 6e 46 6c 61 67 73 2c 20 26 66 6c 61 67 73   &nFlags, &flags
9400: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  ) ){.          r
9410: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
9420: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
9430: 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e      for(j=0; j<n
9440: 46 6c 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20 20 20  Flags; j++){.   
9450: 20 20 20 20 20 20 20 69 6e 74 20 69 64 78 20 3d         int idx =
9460: 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66   0;.          if
9470: 28 20 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72  ( Tcl_GetIndexFr
9480: 6f 6d 4f 62 6a 53 74 72 75 63 74 28 69 6e 74 65  omObjStruct(inte
9490: 72 70 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20 61 46  rp, flags[j], aF
94a0: 6c 61 67 2c 20 0a 20 20 20 20 20 20 20 20 20 20  lag, .          
94b0: 20 20 20 20 20 20 73 69 7a 65 6f 66 28 61 46 6c        sizeof(aFl
94c0: 61 67 5b 30 5d 29 2c 20 22 66 6c 61 67 22 2c 20  ag[0]), "flag", 
94d0: 30 2c 20 26 69 64 78 29 20 0a 20 20 20 20 20 20  0, &idx) .      
94e0: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20      ){.         
94f0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
9500: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  ROR;.          }
9510: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61  .          if( a
9520: 46 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65  Flag[idx].iValue
9530: 3c 30 20 26 26 20 6e 46 6c 61 67 73 3e 31 20 29  <0 && nFlags>1 )
9540: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 54 63  {.            Tc
9550: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
9560: 6e 74 65 72 70 2c 20 22 62 61 64 20 66 6c 61 67  nterp, "bad flag
9570: 73 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  s: ", Tcl_GetStr
9580: 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29  ing(objv[2]), 0)
9590: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  ;.            re
95a0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
95b0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
95c0: 20 20 20 20 20 20 69 4e 65 77 20 7c 3d 20 61 46        iNew |= aF
95d0: 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3b  lag[idx].iValue;
95e0: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  .        }..    
95f0: 20 20 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20      p->iDevchar 
9600: 3d 20 69 4e 65 77 7c 20 30 78 31 30 30 30 30 30  = iNew| 0x100000
9610: 30 30 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  00;.      }..   
9620: 20 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65     pRet = Tcl_Ne
9630: 77 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f  wObj();.      fo
9640: 72 28 69 46 6c 61 67 3d 30 3b 20 69 46 6c 61 67  r(iFlag=0; iFlag
9650: 3c 73 69 7a 65 6f 66 28 61 46 6c 61 67 29 2f 73  <sizeof(aFlag)/s
9660: 69 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d 29 3b  izeof(aFlag[0]);
9670: 20 69 46 6c 61 67 2b 2b 29 7b 0a 20 20 20 20 20   iFlag++){.     
9680: 20 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68     if( p->iDevch
9690: 61 72 20 26 20 61 46 6c 61 67 5b 69 46 6c 61 67  ar & aFlag[iFlag
96a0: 5d 2e 69 56 61 6c 75 65 20 29 7b 0a 20 20 20 20  ].iValue ){.    
96b0: 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62        Tcl_ListOb
96c0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 0a  jAppendElement(.
96d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e                in
96e0: 74 65 72 70 2c 20 70 52 65 74 2c 20 54 63 6c 5f  terp, pRet, Tcl_
96f0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 46 6c  NewStringObj(aFl
9700: 61 67 5b 69 46 6c 61 67 5d 2e 7a 4e 61 6d 65 2c  ag[iFlag].zName,
9710: 20 2d 31 29 0a 20 20 20 20 20 20 20 20 20 20 29   -1).          )
9720: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
9730: 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65    }.      Tcl_Se
9740: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
9750: 70 2c 20 70 52 65 74 29 3b 0a 0a 20 20 20 20 20  p, pRet);..     
9760: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
9770: 20 20 20 63 61 73 65 20 43 4d 44 5f 53 45 43 54     case CMD_SECT
9780: 4f 52 53 49 5a 45 3a 20 7b 0a 20 20 20 20 20 20  ORSIZE: {.      
9790: 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20 20  if( objc>3 ){.  
97a0: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e        Tcl_WrongN
97b0: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32  umArgs(interp, 2
97c0: 2c 20 6f 62 6a 76 2c 20 22 3f 56 41 4c 55 45 3f  , objv, "?VALUE?
97d0: 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  ");.        retu
97e0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
97f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
9800: 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20  objc==3 ){.     
9810: 20 20 20 69 6e 74 20 69 4e 65 77 20 3d 20 30 3b     int iNew = 0;
9820: 0a 20 20 20 20 20 20 20 20 69 66 28 20 54 63 6c  .        if( Tcl
9830: 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  _GetIntFromObj(i
9840: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20  nterp, objv[2], 
9850: 26 69 4e 65 77 29 20 29 7b 0a 20 20 20 20 20 20  &iNew) ){.      
9860: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
9870: 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a  RROR;.        }.
9880: 20 20 20 20 20 20 20 20 70 2d 3e 69 53 65 63 74          p->iSect
9890: 6f 72 73 69 7a 65 20 3d 20 69 4e 65 77 3b 0a 20  orsize = iNew;. 
98a0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c       }.      Tcl
98b0: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
98c0: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  terp, Tcl_NewInt
98d0: 4f 62 6a 28 70 2d 3e 69 53 65 63 74 6f 72 73 69  Obj(p->iSectorsi
98e0: 7a 65 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61  ze));.      brea
98f0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  k;.    }.  }..  
9900: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
9910: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 65  ..static void te
9920: 73 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 28 43 6c  stvfs_obj_del(Cl
9930: 69 65 6e 74 44 61 74 61 20 63 64 29 7b 0a 20 20  ientData cd){.  
9940: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
9950: 73 74 76 66 73 20 2a 29 63 64 3b 0a 20 20 69 66  stvfs *)cd;.  if
9960: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29 20 54  ( p->pScript ) T
9970: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
9980: 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 73  p->pScript);.  s
9990: 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72 65 67  qlite3_vfs_unreg
99a0: 69 73 74 65 72 28 70 2d 3e 70 56 66 73 29 3b 0a  ister(p->pVfs);.
99b0: 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a    ckfree((char *
99c0: 29 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63 6b 66  )p->pVfs);.  ckf
99d0: 72 65 65 28 28 63 68 61 72 20 2a 29 70 29 3b 0a  ree((char *)p);.
99e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20  }../*.** Usage: 
99f0: 20 74 65 73 74 76 66 73 20 56 46 53 4e 41 4d 45   testvfs VFSNAME
9a00: 20 3f 53 57 49 54 43 48 45 53 3f 0a 2a 2a 0a 2a   ?SWITCHES?.**.*
9a10: 2a 20 53 77 69 74 63 68 65 73 20 61 72 65 3a 0a  * Switches are:.
9a20: 2a 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d 20 20  **.**   -noshm  
9a30: 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20 20   BOOLEAN        
9a40: 20 20 20 20 20 28 54 72 75 65 20 74 6f 20 6f 6d       (True to om
9a50: 69 74 20 73 68 6d 20 6d 65 74 68 6f 64 73 2e 20  it shm methods. 
9a60: 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a  Default false).*
9a70: 2a 20 20 20 2d 64 65 66 61 75 6c 74 20 42 4f 4f  *   -default BOO
9a80: 4c 45 41 4e 20 20 20 20 20 20 20 20 20 20 20 20  LEAN            
9a90: 20 28 54 72 75 65 20 74 6f 20 6d 61 6b 65 20 74   (True to make t
9aa0: 68 65 20 76 66 73 20 64 65 66 61 75 6c 74 2e 20  he vfs default. 
9ab0: 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a  Default false).*
9ac0: 2a 0a 2a 2a 20 54 68 69 73 20 63 6f 6d 6d 61 6e  *.** This comman
9ad0: 64 20 63 72 65 61 74 65 73 20 74 77 6f 20 74 68  d creates two th
9ae0: 69 6e 67 73 20 77 68 65 6e 20 69 74 20 69 73 20  ings when it is 
9af0: 69 6e 76 6f 6b 65 64 3a 20 61 6e 20 53 51 4c 69  invoked: an SQLi
9b00: 74 65 20 56 46 53 2c 20 61 6e 64 0a 2a 2a 20 61  te VFS, and.** a
9b10: 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20 42 6f   Tcl command. Bo
9b20: 74 68 20 61 72 65 20 6e 61 6d 65 64 20 56 46 53  th are named VFS
9b30: 4e 41 4d 45 2e 20 54 68 65 20 56 46 53 20 69 73  NAME. The VFS is
9b40: 20 69 6e 73 74 61 6c 6c 65 64 2e 20 49 74 20 69   installed. It i
9b50: 73 20 6e 6f 74 0a 2a 2a 20 69 6e 73 74 61 6c 6c  s not.** install
9b60: 65 64 20 61 73 20 74 68 65 20 64 65 66 61 75 6c  ed as the defaul
9b70: 74 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  t VFS..**.** The
9b80: 20 56 46 53 20 70 61 73 73 65 73 20 61 6c 6c 20   VFS passes all 
9b90: 66 69 6c 65 20 49 2f 4f 20 63 61 6c 6c 73 20 74  file I/O calls t
9ba0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 75 6e  hrough to the un
9bb0: 64 65 72 6c 79 69 6e 67 20 56 46 53 2e 0a 2a 2a  derlying VFS..**
9bc0: 0a 2a 2a 20 57 68 65 6e 65 76 65 72 20 74 68 65  .** Whenever the
9bd0: 20 78 53 68 6d 4d 61 70 20 6d 65 74 68 6f 64 20   xShmMap method 
9be0: 6f 66 20 74 68 65 20 56 46 53 0a 2a 2a 20 69 73  of the VFS.** is
9bf0: 20 69 6e 76 6f 6b 65 64 2c 20 74 68 65 20 53 43   invoked, the SC
9c00: 52 49 50 54 20 69 73 20 65 78 65 63 75 74 65 64  RIPT is executed
9c10: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   as follows:.**.
9c20: 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53 68 6d  **   SCRIPT xShm
9c30: 4d 61 70 20 20 20 20 46 49 4c 45 4e 41 4d 45 20  Map    FILENAME 
9c40: 49 44 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  ID.**.** The val
9c50: 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20 74  ue returned by t
9c60: 68 65 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f 66  he invocation of
9c70: 20 53 43 52 49 50 54 20 61 62 6f 76 65 20 69 73   SCRIPT above is
9c80: 20 69 6e 74 65 72 70 72 65 74 65 64 20 61 73 0a   interpreted as.
9c90: 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  ** an SQLite err
9ca0: 6f 72 20 63 6f 64 65 20 61 6e 64 20 72 65 74 75  or code and retu
9cb0: 72 6e 65 64 20 74 6f 20 53 51 4c 69 74 65 2e 20  rned to SQLite. 
9cc0: 45 69 74 68 65 72 20 61 20 73 79 6d 62 6f 6c 69  Either a symboli
9cd0: 63 20 0a 2a 2a 20 22 53 51 4c 49 54 45 5f 4f 4b  c .** "SQLITE_OK
9ce0: 22 20 6f 72 20 6e 75 6d 65 72 69 63 20 22 30 22  " or numeric "0"
9cf0: 20 76 61 6c 75 65 20 6d 61 79 20 62 65 20 72 65   value may be re
9d00: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  turned..**.** Th
9d10: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
9d20: 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20  e shared-memory 
9d30: 62 75 66 66 65 72 20 61 73 73 6f 63 69 61 74 65  buffer associate
9d40: 64 20 77 69 74 68 20 61 20 67 69 76 65 6e 20 66  d with a given f
9d50: 69 6c 65 0a 2a 2a 20 6d 61 79 20 62 65 20 72 65  ile.** may be re
9d60: 61 64 20 61 6e 64 20 73 65 74 20 75 73 69 6e 67  ad and set using
9d70: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63   the following c
9d80: 6f 6d 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20  ommand:.**.**   
9d90: 56 46 53 4e 41 4d 45 20 73 68 6d 20 46 49 4c 45  VFSNAME shm FILE
9da0: 4e 41 4d 45 20 3f 4e 45 57 56 41 4c 55 45 3f 0a  NAME ?NEWVALUE?.
9db0: 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 78  **.** When the x
9dc0: 53 68 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64 20 69  ShmLock method i
9dd0: 73 20 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c  s invoked by SQL
9de0: 69 74 65 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69  ite, the followi
9df0: 6e 67 20 73 63 72 69 70 74 20 69 73 0a 2a 2a 20  ng script is.** 
9e00: 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52  run:.**.**   SCR
9e10: 49 50 54 20 78 53 68 6d 4c 6f 63 6b 20 20 20 20  IPT xShmLock    
9e20: 46 49 4c 45 4e 41 4d 45 20 49 44 20 4c 4f 43 4b  FILENAME ID LOCK
9e30: 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 4c 4f 43  .**.** where LOC
9e40: 4b 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d  K is of the form
9e50: 20 22 4f 46 46 53 45 54 20 4e 42 59 54 45 20 6c   "OFFSET NBYTE l
9e60: 6f 63 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61 72 65  ock/unlock share
9e70: 64 2f 65 78 63 6c 75 73 69 76 65 22 0a 2a 2f 0a  d/exclusive".*/.
9e80: 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 76  static int testv
9e90: 66 73 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74  fs_cmd(.  Client
9ea0: 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49  Data cd,.  Tcl_I
9eb0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
9ec0: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
9ed0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
9ee0: 5b 5d 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 73  [].){.  static s
9ef0: 71 6c 69 74 65 33 5f 76 66 73 20 74 76 66 73 5f  qlite3_vfs tvfs_
9f00: 76 66 73 20 3d 20 7b 0a 20 20 20 20 33 2c 20 20  vfs = {.    3,  
9f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9f20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65            /* iVe
9f30: 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20  rsion */.    0, 
9f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9f50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 7a             /* sz
9f60: 4f 73 46 69 6c 65 20 2a 2f 0a 20 20 20 20 30 2c  OsFile */.    0,
9f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9f80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6d              /* m
9f90: 78 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 20  xPathname */.   
9fa0: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
9fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9fc0: 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20 30  * pNext */.    0
9fd0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9ff0: 7a 4e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20  zName */.    0, 
a000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a010: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41             /* pA
a020: 70 70 44 61 74 61 20 2a 2f 0a 20 20 20 20 74 76  ppData */.    tv
a030: 66 73 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  fsOpen,         
a040: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
a050: 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73  Open */.    tvfs
a060: 44 65 6c 65 74 65 2c 20 20 20 20 20 20 20 20 20  Delete,         
a070: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
a080: 6c 65 74 65 20 2a 2f 0a 20 20 20 20 74 76 66 73  lete */.    tvfs
a090: 41 63 63 65 73 73 2c 20 20 20 20 20 20 20 20 20  Access,         
a0a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63            /* xAc
a0b0: 63 65 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73  cess */.    tvfs
a0c0: 46 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20  FullPathname,   
a0d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 75            /* xFu
a0e0: 6c 6c 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 23 69  llPathname */.#i
a0f0: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
a100: 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e  T_LOAD_EXTENSION
a110: 0a 20 20 20 20 74 76 66 73 44 6c 4f 70 65 6e 2c  .    tvfsDlOpen,
a120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a130: 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f     /* xDlOpen */
a140: 0a 20 20 20 20 74 76 66 73 44 6c 45 72 72 6f 72  .    tvfsDlError
a150: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
a160: 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a     /* xDlError *
a170: 2f 0a 20 20 20 20 74 76 66 73 44 6c 53 79 6d 2c  /.    tvfsDlSym,
a180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a190: 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f      /* xDlSym */
a1a0: 0a 20 20 20 20 74 76 66 73 44 6c 43 6c 6f 73 65  .    tvfsDlClose
a1b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
a1c0: 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a     /* xDlClose *
a1d0: 2f 0a 23 65 6c 73 65 0a 20 20 20 20 30 2c 20 20  /.#else.    0,  
a1e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
a200: 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20  Open */.    0,  
a210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a220: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
a230: 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30 2c 20  Error */.    0, 
a240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a250: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
a260: 6c 53 79 6d 20 2a 2f 0a 20 20 20 20 30 2c 20 20  lSym */.    0,  
a270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
a290: 43 6c 6f 73 65 20 2a 2f 0a 23 65 6e 64 69 66 20  Close */.#endif 
a2a0: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  /* SQLITE_OMIT_L
a2b0: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f  OAD_EXTENSION */
a2c0: 0a 20 20 20 20 74 76 66 73 52 61 6e 64 6f 6d 6e  .    tvfsRandomn
a2d0: 65 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ess,            
a2e0: 20 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e 65 73     /* xRandomnes
a2f0: 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 53 6c 65  s */.    tvfsSle
a300: 65 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ep,             
a310: 20 20 20 20 20 20 20 2f 2a 20 78 53 6c 65 65 70         /* xSleep
a320: 20 2a 2f 0a 20 20 20 20 74 76 66 73 43 75 72 72   */.    tvfsCurr
a330: 65 6e 74 54 69 6d 65 2c 20 20 20 20 20 20 20 20  entTime,        
a340: 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e        /* xCurren
a350: 74 54 69 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20  tTime */.    0, 
a360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a370: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 47             /* xG
a380: 65 74 4c 61 73 74 45 72 72 6f 72 20 2a 2f 0a 20  etLastError */. 
a390: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
a3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a3b0: 20 2f 2a 20 78 43 75 72 72 65 6e 74 54 69 6d 65   /* xCurrentTime
a3c0: 49 6e 74 36 34 20 2a 2f 0a 20 20 20 20 30 2c 20  Int64 */.    0, 
a3d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a3e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
a3f0: 65 74 53 79 73 74 65 6d 43 61 6c 6c 20 2a 2f 0a  etSystemCall */.
a400: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
a410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a420: 20 20 2f 2a 20 78 47 65 74 53 79 73 74 65 6d 43    /* xGetSystemC
a430: 61 6c 6c 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  all */.    0,   
a440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a450: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e 65 78           /* xNex
a460: 74 53 79 73 74 65 6d 43 61 6c 6c 20 2a 2f 0a 20  tSystemCall */. 
a470: 20 7d 3b 0a 0a 20 20 54 65 73 74 76 66 73 20 2a   };..  Testvfs *
a480: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
a490: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6f 62         /* New ob
a4a0: 6a 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ject */.  sqlite
a4b0: 33 5f 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20  3_vfs *pVfs;    
a4c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77            /* New
a4d0: 20 56 46 53 20 2a 2f 0a 20 20 63 68 61 72 20 2a   VFS */.  char *
a4e0: 7a 56 66 73 3b 0a 20 20 69 6e 74 20 6e 42 79 74  zVfs;.  int nByt
a4f0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
a500: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
a510: 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c   of space to all
a520: 6f 63 61 74 65 20 61 74 20 70 20 2a 2f 0a 0a 20  ocate at p */.. 
a530: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 73   int i;.  int is
a540: 4e 6f 73 68 6d 20 3d 20 30 3b 20 20 20 20 20 20  Noshm = 0;      
a550: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
a560: 65 20 69 66 20 2d 6e 6f 73 68 6d 20 69 73 20 70  e if -noshm is p
a570: 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69  assed */.  int i
a580: 73 46 75 6c 6c 73 68 6d 20 3d 20 30 3b 20 20 20  sFullshm = 0;   
a590: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
a5a0: 75 65 20 69 66 20 2d 66 75 6c 6c 73 68 6d 20 69  ue if -fullshm i
a5b0: 73 20 70 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e  s passed */.  in
a5c0: 74 20 69 73 44 65 66 61 75 6c 74 20 3d 20 30 3b  t isDefault = 0;
a5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a5e0: 20 54 72 75 65 20 69 66 20 2d 64 65 66 61 75 6c   True if -defaul
a5f0: 74 20 69 73 20 70 61 73 73 65 64 20 2a 2f 0a 20  t is passed */. 
a600: 20 69 6e 74 20 73 7a 4f 73 46 69 6c 65 20 3d 20   int szOsFile = 
a610: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
a620: 20 2f 2a 20 56 61 6c 75 65 20 70 61 73 73 65 64   /* Value passed
a630: 20 74 6f 20 2d 73 7a 6f 73 66 69 6c 65 20 2a 2f   to -szosfile */
a640: 0a 20 20 69 6e 74 20 6d 78 50 61 74 68 6e 61 6d  .  int mxPathnam
a650: 65 20 3d 20 2d 31 3b 20 20 20 20 20 20 20 20 20  e = -1;         
a660: 20 20 20 2f 2a 20 56 61 6c 75 65 20 70 61 73 73     /* Value pass
a670: 65 64 20 74 6f 20 2d 6d 78 70 61 74 68 6e 61 6d  ed to -mxpathnam
a680: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 56 65 72 73  e */.  int iVers
a690: 69 6f 6e 20 3d 20 33 3b 20 20 20 20 20 20 20 20  ion = 3;        
a6a0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
a6b0: 70 61 73 73 65 64 20 74 6f 20 2d 69 76 65 72 73  passed to -ivers
a6c0: 69 6f 6e 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62  ion */..  if( ob
a6d0: 6a 63 3c 32 20 7c 7c 20 30 21 3d 28 6f 62 6a 63  jc<2 || 0!=(objc
a6e0: 25 32 29 20 29 20 67 6f 74 6f 20 62 61 64 5f 61  %2) ) goto bad_a
a6f0: 72 67 73 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20  rgs;.  for(i=2; 
a700: 69 3c 6f 62 6a 63 3b 20 69 20 2b 3d 20 32 29 7b  i<objc; i += 2){
a710: 0a 20 20 20 20 69 6e 74 20 6e 53 77 69 74 63 68  .    int nSwitch
a720: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 77 69  ;.    char *zSwi
a730: 74 63 68 3b 0a 20 20 20 20 7a 53 77 69 74 63 68  tch;.    zSwitch
a740: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
a750: 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 69 5d 2c  FromObj(objv[i],
a760: 20 26 6e 53 77 69 74 63 68 29 3b 20 0a 0a 20 20   &nSwitch); ..  
a770: 20 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20    if( nSwitch>2 
a780: 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d  && 0==strncmp("-
a790: 6e 6f 73 68 6d 22 2c 20 7a 53 77 69 74 63 68 2c  noshm", zSwitch,
a7a0: 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20   nSwitch) ){.   
a7b0: 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 42 6f     if( Tcl_GetBo
a7c0: 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74  oleanFromObj(int
a7d0: 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20  erp, objv[i+1], 
a7e0: 26 69 73 4e 6f 73 68 6d 29 20 29 7b 0a 20 20 20  &isNoshm) ){.   
a7f0: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
a800: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
a810: 20 20 20 20 20 69 66 28 20 69 73 4e 6f 73 68 6d       if( isNoshm
a820: 20 29 20 69 73 46 75 6c 6c 73 68 6d 20 3d 20 30   ) isFullshm = 0
a830: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  ;.    }.    else
a840: 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26   if( nSwitch>2 &
a850: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 64  & 0==strncmp("-d
a860: 65 66 61 75 6c 74 22 2c 20 7a 53 77 69 74 63 68  efault", zSwitch
a870: 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20  , nSwitch) ){.  
a880: 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 42      if( Tcl_GetB
a890: 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e  ooleanFromObj(in
a8a0: 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c  terp, objv[i+1],
a8b0: 20 26 69 73 44 65 66 61 75 6c 74 29 20 29 7b 0a   &isDefault) ){.
a8c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
a8d0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
a8e0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  }.    }.    else
a8f0: 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26   if( nSwitch>2 &
a900: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 73  & 0==strncmp("-s
a910: 7a 6f 73 66 69 6c 65 22 2c 20 7a 53 77 69 74 63  zosfile", zSwitc
a920: 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20  h, nSwitch) ){. 
a930: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74       if( Tcl_Get
a940: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
a950: 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 73  p, objv[i+1], &s
a960: 7a 4f 73 46 69 6c 65 29 20 29 7b 0a 20 20 20 20  zOsFile) ){.    
a970: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
a980: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
a990: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
a9a0: 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d   nSwitch>2 && 0=
a9b0: 3d 73 74 72 6e 63 6d 70 28 22 2d 6d 78 70 61 74  =strncmp("-mxpat
a9c0: 68 6e 61 6d 65 22 2c 20 7a 53 77 69 74 63 68 2c  hname", zSwitch,
a9d0: 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20   nSwitch) ){.   
a9e0: 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e     if( Tcl_GetIn
a9f0: 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  tFromObj(interp,
aa00: 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 6d 78 50   objv[i+1], &mxP
aa10: 61 74 68 6e 61 6d 65 29 20 29 7b 0a 20 20 20 20  athname) ){.    
aa20: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
aa30: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
aa40: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
aa50: 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d   nSwitch>2 && 0=
aa60: 3d 73 74 72 6e 63 6d 70 28 22 2d 69 76 65 72 73  =strncmp("-ivers
aa70: 69 6f 6e 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e  ion", zSwitch, n
aa80: 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20  Switch) ){.     
aa90: 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46   if( Tcl_GetIntF
aaa0: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
aab0: 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 56 65 72 73  bjv[i+1], &iVers
aac0: 69 6f 6e 29 20 29 7b 0a 20 20 20 20 20 20 20 20  ion) ){.        
aad0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
aae0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
aaf0: 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77      else if( nSw
ab00: 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72  itch>2 && 0==str
ab10: 6e 63 6d 70 28 22 2d 66 75 6c 6c 73 68 6d 22 2c  ncmp("-fullshm",
ab20: 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63   zSwitch, nSwitc
ab30: 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  h) ){.      if( 
ab40: 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72  Tcl_GetBooleanFr
ab50: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
ab60: 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 46 75 6c 6c  jv[i+1], &isFull
ab70: 73 68 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  shm) ){.        
ab80: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
ab90: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
aba0: 69 66 28 20 69 73 46 75 6c 6c 73 68 6d 20 29 20  if( isFullshm ) 
abb0: 69 73 4e 6f 73 68 6d 20 3d 20 30 3b 0a 20 20 20  isNoshm = 0;.   
abc0: 20 7d 0a 20 20 20 20 65 6c 73 65 7b 0a 20 20 20   }.    else{.   
abd0: 20 20 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73     goto bad_args
abe0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
abf0: 66 28 20 73 7a 4f 73 46 69 6c 65 3c 73 69 7a 65  f( szOsFile<size
ac00: 6f 66 28 54 65 73 74 76 66 73 46 69 6c 65 29 20  of(TestvfsFile) 
ac10: 29 7b 0a 20 20 20 20 73 7a 4f 73 46 69 6c 65 20  ){.    szOsFile 
ac20: 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  = sizeof(Testvfs
ac30: 46 69 6c 65 29 3b 0a 20 20 7d 0a 0a 20 20 7a 56  File);.  }..  zV
ac40: 66 73 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  fs = Tcl_GetStri
ac50: 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 6e  ng(objv[1]);.  n
ac60: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 54 65  Byte = sizeof(Te
ac70: 73 74 76 66 73 29 20 2b 20 28 69 6e 74 29 73 74  stvfs) + (int)st
ac80: 72 6c 65 6e 28 7a 56 66 73 29 2b 31 3b 0a 20 20  rlen(zVfs)+1;.  
ac90: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63  p = (Testvfs *)c
aca0: 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  kalloc(nByte);. 
acb0: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42   memset(p, 0, nB
acc0: 79 74 65 29 3b 0a 20 20 70 2d 3e 69 44 65 76 63  yte);.  p->iDevc
acd0: 68 61 72 20 3d 20 2d 31 3b 0a 20 20 70 2d 3e 69  har = -1;.  p->i
ace0: 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 2d 31 3b  Sectorsize = -1;
acf0: 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20 74 68  ..  /* Create th
ad00: 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 63 6f 6d  e new object com
ad10: 6d 61 6e 64 20 62 65 66 6f 72 65 20 71 75 65 72  mand before quer
ad20: 79 69 6e 67 20 53 51 4c 69 74 65 20 66 6f 72 20  ying SQLite for 
ad30: 61 20 64 65 66 61 75 6c 74 20 56 46 53 0a 20 20  a default VFS.  
ad40: 2a 2a 20 74 6f 20 75 73 65 20 66 6f 72 20 27 72  ** to use for 'r
ad50: 65 61 6c 27 20 49 4f 20 6f 70 65 72 61 74 69 6f  eal' IO operatio
ad60: 6e 73 2e 20 54 68 69 73 20 69 73 20 62 65 63 61  ns. This is beca
ad70: 75 73 65 20 63 72 65 61 74 69 6e 67 20 74 68 65  use creating the
ad80: 20 6e 65 77 20 56 46 53 0a 20 20 2a 2a 20 6d 61   new VFS.  ** ma
ad90: 79 20 64 65 6c 65 74 65 20 61 6e 20 65 78 69 73  y delete an exis
ada0: 74 69 6e 67 20 5b 74 65 73 74 76 66 73 5d 20 56  ting [testvfs] V
adb0: 46 53 20 6f 66 20 74 68 65 20 73 61 6d 65 20 6e  FS of the same n
adc0: 61 6d 65 2e 20 49 66 20 73 75 63 68 20 61 20 56  ame. If such a V
add0: 46 53 0a 20 20 2a 2a 20 69 73 20 63 75 72 72 65  FS.  ** is curre
ade0: 6e 74 6c 79 20 74 68 65 20 64 65 66 61 75 6c 74  ntly the default
adf0: 2c 20 74 68 65 20 6e 65 77 20 5b 74 65 73 74 76  , the new [testv
ae00: 66 73 5d 20 6d 61 79 20 65 6e 64 20 75 70 20 63  fs] may end up c
ae10: 61 6c 6c 69 6e 67 20 74 68 65 20 0a 20 20 2a 2a  alling the .  **
ae20: 20 6d 65 74 68 6f 64 73 20 6f 66 20 61 20 64 65   methods of a de
ae30: 6c 65 74 65 64 20 6f 62 6a 65 63 74 2e 0a 20 20  leted object..  
ae40: 2a 2f 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  */.  Tcl_CreateO
ae50: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
ae60: 2c 20 7a 56 66 73 2c 20 74 65 73 74 76 66 73 5f  , zVfs, testvfs_
ae70: 6f 62 6a 5f 63 6d 64 2c 20 70 2c 20 74 65 73 74  obj_cmd, p, test
ae80: 76 66 73 5f 6f 62 6a 5f 64 65 6c 29 3b 0a 20 20  vfs_obj_del);.  
ae90: 70 2d 3e 70 50 61 72 65 6e 74 20 3d 20 73 71 6c  p->pParent = sql
aea0: 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30 29  ite3_vfs_find(0)
aeb0: 3b 0a 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d 20  ;.  p->interp = 
aec0: 69 6e 74 65 72 70 3b 0a 0a 20 20 70 2d 3e 7a 4e  interp;..  p->zN
aed0: 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29 26 70  ame = (char *)&p
aee0: 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 2d  [1];.  memcpy(p-
aef0: 3e 7a 4e 61 6d 65 2c 20 7a 56 66 73 2c 20 73 74  >zName, zVfs, st
af00: 72 6c 65 6e 28 7a 56 66 73 29 2b 31 29 3b 0a 0a  rlen(zVfs)+1);..
af10: 20 20 70 56 66 73 20 3d 20 28 73 71 6c 69 74 65    pVfs = (sqlite
af20: 33 5f 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63 28  3_vfs *)ckalloc(
af30: 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76  sizeof(sqlite3_v
af40: 66 73 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70  fs));.  memcpy(p
af50: 56 66 73 2c 20 26 74 76 66 73 5f 76 66 73 2c 20  Vfs, &tvfs_vfs, 
af60: 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76  sizeof(sqlite3_v
af70: 66 73 29 29 3b 0a 20 20 70 56 66 73 2d 3e 70 41  fs));.  pVfs->pA
af80: 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20 2a  ppData = (void *
af90: 29 70 3b 0a 20 20 70 56 66 73 2d 3e 69 56 65 72  )p;.  pVfs->iVer
afa0: 73 69 6f 6e 20 3d 20 69 56 65 72 73 69 6f 6e 3b  sion = iVersion;
afb0: 0a 20 20 70 56 66 73 2d 3e 7a 4e 61 6d 65 20 3d  .  pVfs->zName =
afc0: 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 70 56 66   p->zName;.  pVf
afd0: 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20  s->mxPathname = 
afe0: 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61  p->pParent->mxPa
aff0: 74 68 6e 61 6d 65 3b 0a 20 20 69 66 28 20 6d 78  thname;.  if( mx
b000: 50 61 74 68 6e 61 6d 65 3e 3d 30 20 26 26 20 6d  Pathname>=0 && m
b010: 78 50 61 74 68 6e 61 6d 65 3c 70 56 66 73 2d 3e  xPathname<pVfs->
b020: 6d 78 50 61 74 68 6e 61 6d 65 20 29 7b 0a 20 20  mxPathname ){.  
b030: 20 20 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e 61    pVfs->mxPathna
b040: 6d 65 20 3d 20 6d 78 50 61 74 68 6e 61 6d 65 3b  me = mxPathname;
b050: 0a 20 20 7d 0a 20 20 70 56 66 73 2d 3e 73 7a 4f  .  }.  pVfs->szO
b060: 73 46 69 6c 65 20 3d 20 73 7a 4f 73 46 69 6c 65  sFile = szOsFile
b070: 3b 0a 20 20 70 2d 3e 70 56 66 73 20 3d 20 70 56  ;.  p->pVfs = pV
b080: 66 73 3b 0a 20 20 70 2d 3e 69 73 4e 6f 73 68 6d  fs;.  p->isNoshm
b090: 20 3d 20 69 73 4e 6f 73 68 6d 3b 0a 20 20 70 2d   = isNoshm;.  p-
b0a0: 3e 69 73 46 75 6c 6c 73 68 6d 20 3d 20 69 73 46  >isFullshm = isF
b0b0: 75 6c 6c 73 68 6d 3b 0a 20 20 70 2d 3e 6d 61 73  ullshm;.  p->mas
b0c0: 6b 20 3d 20 54 45 53 54 56 46 53 5f 41 4c 4c 5f  k = TESTVFS_ALL_
b0d0: 4d 41 53 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33  MASK;..  sqlite3
b0e0: 5f 76 66 73 5f 72 65 67 69 73 74 65 72 28 70 56  _vfs_register(pV
b0f0: 66 73 2c 20 69 73 44 65 66 61 75 6c 74 29 3b 0a  fs, isDefault);.
b100: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
b110: 3b 0a 0a 20 62 61 64 5f 61 72 67 73 3a 0a 20 20  ;.. bad_args:.  
b120: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
b130: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
b140: 2c 20 22 56 46 53 4e 41 4d 45 20 3f 2d 6e 6f 73  , "VFSNAME ?-nos
b150: 68 6d 20 42 4f 4f 4c 3f 20 3f 2d 66 75 6c 6c 73  hm BOOL? ?-fulls
b160: 68 6d 20 42 4f 4f 4c 3f 20 3f 2d 64 65 66 61 75  hm BOOL? ?-defau
b170: 6c 74 20 42 4f 4f 4c 3f 20 3f 2d 6d 78 70 61 74  lt BOOL? ?-mxpat
b180: 68 6e 61 6d 65 20 49 4e 54 3f 20 3f 2d 73 7a 6f  hname INT? ?-szo
b190: 73 66 69 6c 65 20 49 4e 54 3f 20 3f 2d 69 76 65  sfile INT? ?-ive
b1a0: 72 73 69 6f 6e 20 49 4e 54 3f 22 29 3b 0a 20 20  rsion INT?");.  
b1b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
b1c0: 3b 0a 7d 0a 0a 69 6e 74 20 53 71 6c 69 74 65 74  ;.}..int Sqlitet
b1d0: 65 73 74 76 66 73 5f 49 6e 69 74 28 54 63 6c 5f  estvfs_Init(Tcl_
b1e0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b  Interp *interp){
b1f0: 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  .  Tcl_CreateObj
b200: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
b210: 22 74 65 73 74 76 66 73 22 2c 20 74 65 73 74 76  "testvfs", testv
b220: 66 73 5f 63 6d 64 2c 20 30 2c 20 30 29 3b 0a 20  fs_cmd, 0, 0);. 
b230: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
b240: 7d 0a 0a 23 65 6e 64 69 66 0a                    }..#endif.