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

Artifact 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 4d 61 79 20 30  /*.** 2010 May 0
0010: 35 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  5.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2f 0a 23 69 66 20  *****.**.*/.#if 
0180: 53 51 4c 49 54 45 5f 54 45 53 54 20 20 20 20 20  SQLITE_TEST     
0190: 20 20 20 20 20 2f 2a 20 54 68 69 73 20 66 69 6c       /* This fil
01a0: 65 20 69 73 20 75 73 65 64 20 66 6f 72 20 74 65  e is used for te
01b0: 73 74 69 6e 67 20 6f 6e 6c 79 20 2a 2f 0a 0a 2f  sting only */../
01c0: 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63  *.** This file c
01d0: 6f 6e 74 61 69 6e 73 20 74 68 65 20 69 6d 70 6c  ontains the impl
01e0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
01f0: 65 20 54 63 6c 20 5b 74 65 73 74 76 66 73 5d 20  e Tcl [testvfs] 
0200: 63 6f 6d 6d 61 6e 64 2c 0a 2a 2a 20 75 73 65 64  command,.** used
0210: 20 74 6f 20 63 72 65 61 74 65 20 53 51 4c 69 74   to create SQLit
0220: 65 20 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61  e VFS implementa
0230: 74 69 6f 6e 73 20 77 69 74 68 20 76 61 72 69 6f  tions with vario
0240: 75 73 20 70 72 6f 70 65 72 74 69 65 73 20 61 6e  us properties an
0250: 64 0a 2a 2a 20 69 6e 73 74 72 75 6d 65 6e 74 61  d.** instrumenta
0260: 74 69 6f 6e 20 74 6f 20 73 75 70 70 6f 72 74 20  tion to support 
0270: 74 65 73 74 69 6e 67 20 53 51 4c 69 74 65 2e 0a  testing SQLite..
0280: 2a 2a 0a 2a 2a 20 20 20 74 65 73 74 76 66 73 20  **.**   testvfs 
0290: 56 46 53 4e 41 4d 45 20 3f 4f 50 54 49 4f 4e 53  VFSNAME ?OPTIONS
02a0: 3f 0a 2a 2a 0a 2a 2a 20 41 76 61 69 6c 61 62 6c  ?.**.** Availabl
02b0: 65 20 6f 70 74 69 6f 6e 73 20 61 72 65 3a 0a 2a  e options are:.*
02c0: 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d 20 20 20  *.**   -noshm   
02d0: 20 20 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20     BOOLEAN      
02e0: 20 20 28 54 72 75 65 20 74 6f 20 6f 6d 69 74 20    (True to omit 
02f0: 73 68 6d 20 6d 65 74 68 6f 64 73 2e 20 44 65 66  shm methods. Def
0300: 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 20 20  ault false).**  
0310: 20 2d 64 65 66 61 75 6c 74 20 20 20 20 42 4f 4f   -default    BOO
0320: 4c 45 41 4e 20 20 20 20 20 20 20 20 28 54 72 75  LEAN        (Tru
0330: 65 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 76 66  e to make the vf
0340: 73 20 64 65 66 61 75 6c 74 2e 20 44 65 66 61 75  s default. Defau
0350: 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 20 20 20 2d  lt false).**   -
0360: 73 7a 6f 73 66 69 6c 65 20 20 20 49 4e 54 45 47  szosfile   INTEG
0370: 45 52 20 20 20 20 20 20 20 20 28 56 61 6c 75 65  ER        (Value
0380: 20 66 6f 72 20 73 71 6c 69 74 65 33 5f 76 66 73   for sqlite3_vfs
0390: 2e 73 7a 4f 73 46 69 6c 65 29 0a 2a 2a 20 20 20  .szOsFile).**   
03a0: 2d 6d 78 70 61 74 68 6e 61 6d 65 20 49 4e 54 45  -mxpathname INTE
03b0: 47 45 52 20 20 20 20 20 20 20 20 28 56 61 6c 75  GER        (Valu
03c0: 65 20 66 6f 72 20 73 71 6c 69 74 65 33 5f 76 66  e for sqlite3_vf
03d0: 73 2e 6d 78 50 61 74 68 6e 61 6d 65 29 0a 2a 2a  s.mxPathname).**
03e0: 20 20 20 2d 69 76 65 72 73 69 6f 6e 20 20 20 49     -iversion   I
03f0: 4e 54 45 47 45 52 20 20 20 20 20 20 20 20 28 56  NTEGER        (V
0400: 61 6c 75 65 20 66 6f 72 20 73 71 6c 69 74 65 33  alue for sqlite3
0410: 5f 76 66 73 2e 69 56 65 72 73 69 6f 6e 29 0a 2a  _vfs.iVersion).*
0420: 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  /..#include "sql
0430: 69 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64 65  ite3.h".#include
0440: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a   "sqliteInt.h"..
0450: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54  typedef struct T
0460: 65 73 74 76 66 73 20 54 65 73 74 76 66 73 3b 0a  estvfs Testvfs;.
0470: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54  typedef struct T
0480: 65 73 74 76 66 73 53 68 6d 20 54 65 73 74 76 66  estvfsShm Testvf
0490: 73 53 68 6d 3b 0a 74 79 70 65 64 65 66 20 73 74  sShm;.typedef st
04a0: 72 75 63 74 20 54 65 73 74 76 66 73 42 75 66 66  ruct TestvfsBuff
04b0: 65 72 20 54 65 73 74 76 66 73 42 75 66 66 65 72  er TestvfsBuffer
04c0: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
04d0: 20 54 65 73 74 76 66 73 46 69 6c 65 20 54 65 73   TestvfsFile Tes
04e0: 74 76 66 73 46 69 6c 65 3b 0a 74 79 70 65 64 65  tvfsFile;.typede
04f0: 66 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73  f struct Testvfs
0500: 46 64 20 54 65 73 74 76 66 73 46 64 3b 0a 0a 2f  Fd TestvfsFd;../
0510: 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 66 69 6c  *.** An open fil
0520: 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 72  e handle..*/.str
0530: 75 63 74 20 54 65 73 74 76 66 73 46 69 6c 65 20  uct TestvfsFile 
0540: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  {.  sqlite3_file
0550: 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20   base;          
0560: 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73      /* Base clas
0570: 73 2e 20 20 4d 75 73 74 20 62 65 20 66 69 72 73  s.  Must be firs
0580: 74 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 46 64  t */.  TestvfsFd
0590: 20 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20   *pFd;          
05a0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 64         /* File d
05b0: 61 74 61 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e  ata */.};.#defin
05c0: 65 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  e tvfsGetFd(pFil
05d0: 65 29 20 28 28 28 54 65 73 74 76 66 73 46 69 6c  e) (((TestvfsFil
05e0: 65 20 2a 29 70 46 69 6c 65 29 2d 3e 70 46 64 29  e *)pFile)->pFd)
05f0: 0a 0a 73 74 72 75 63 74 20 54 65 73 74 76 66 73  ..struct Testvfs
0600: 46 64 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  Fd {.  sqlite3_v
0610: 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20 20  fs *pVfs;       
0620: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56 46         /* The VF
0630: 53 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  S */.  const cha
0640: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20 20  r *zFilename;   
0650: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 6e 61         /* Filena
0660: 6d 65 20 61 73 20 70 61 73 73 65 64 20 74 6f 20  me as passed to 
0670: 78 4f 70 65 6e 28 29 20 2a 2f 0a 20 20 73 71 6c  xOpen() */.  sql
0680: 69 74 65 33 5f 66 69 6c 65 20 2a 70 52 65 61 6c  ite3_file *pReal
0690: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
06a0: 54 68 65 20 72 65 61 6c 2c 20 75 6e 64 65 72 6c  The real, underl
06b0: 79 69 6e 67 20 66 69 6c 65 20 64 65 73 63 72 69  ying file descri
06c0: 70 74 6f 72 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  ptor */.  Tcl_Ob
06d0: 6a 20 2a 70 53 68 6d 49 64 3b 20 20 20 20 20 20  j *pShmId;      
06e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 61            /* Sha
06f0: 72 65 64 20 6d 65 6d 6f 72 79 20 69 64 20 66 6f  red memory id fo
0700: 72 20 54 63 6c 20 63 61 6c 6c 62 61 63 6b 73 20  r Tcl callbacks 
0710: 2a 2f 0a 0a 20 20 54 65 73 74 76 66 73 42 75 66  */..  TestvfsBuf
0720: 66 65 72 20 2a 70 53 68 6d 3b 20 20 20 20 20 20  fer *pShm;      
0730: 20 20 20 20 20 20 2f 2a 20 53 68 61 72 65 64 20        /* Shared 
0740: 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 20 2a 2f  memory buffer */
0750: 0a 20 20 75 33 32 20 65 78 63 6c 6c 6f 63 6b 3b  .  u32 excllock;
0760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0770: 20 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 65 78     /* Mask of ex
0780: 63 6c 75 73 69 76 65 20 6c 6f 63 6b 73 20 2a 2f  clusive locks */
0790: 0a 20 20 75 33 32 20 73 68 61 72 65 64 6c 6f 63  .  u32 sharedloc
07a0: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
07b0: 20 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 73 68     /* Mask of sh
07c0: 61 72 65 64 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20  ared locks */.  
07d0: 54 65 73 74 76 66 73 46 64 20 2a 70 4e 65 78 74  TestvfsFd *pNext
07e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
07f0: 2f 2a 20 4e 65 78 74 20 68 61 6e 64 6c 65 20 6f  /* Next handle o
0800: 70 65 6e 65 64 20 6f 6e 20 74 68 65 20 73 61 6d  pened on the sam
0810: 65 20 66 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a 0a 23  e file */.};...#
0820: 64 65 66 69 6e 65 20 46 41 55 4c 54 5f 49 4e 4a  define FAULT_INJ
0830: 45 43 54 5f 4e 4f 4e 45 20 20 20 20 20 20 20 30  ECT_NONE       0
0840: 0a 23 64 65 66 69 6e 65 20 46 41 55 4c 54 5f 49  .#define FAULT_I
0850: 4e 4a 45 43 54 5f 54 52 41 4e 53 49 45 4e 54 20  NJECT_TRANSIENT 
0860: 20 31 0a 23 64 65 66 69 6e 65 20 46 41 55 4c 54   1.#define FAULT
0870: 5f 49 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45  _INJECT_PERSISTE
0880: 4e 54 20 32 0a 0a 74 79 70 65 64 65 66 20 73 74  NT 2..typedef st
0890: 72 75 63 74 20 54 65 73 74 46 61 75 6c 74 49 6e  ruct TestFaultIn
08a0: 6a 65 63 74 20 54 65 73 74 46 61 75 6c 74 49 6e  ject TestFaultIn
08b0: 6a 65 63 74 3b 0a 73 74 72 75 63 74 20 54 65 73  ject;.struct Tes
08c0: 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 7b 0a 20  tFaultInject {. 
08d0: 20 69 6e 74 20 69 43 6e 74 3b 20 20 20 20 20 20   int iCnt;      
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08f0: 20 2f 2a 20 52 65 6d 61 69 6e 69 6e 67 20 63 61   /* Remaining ca
0900: 6c 6c 73 20 62 65 66 6f 72 65 20 66 61 75 6c 74  lls before fault
0910: 20 69 6e 6a 65 63 74 69 6f 6e 20 2a 2f 0a 20 20   injection */.  
0920: 69 6e 74 20 65 46 61 75 6c 74 3b 20 20 20 20 20  int eFault;     
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0940: 2f 2a 20 41 20 46 41 55 4c 54 5f 49 4e 4a 45 43  /* A FAULT_INJEC
0950: 54 5f 2a 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69  T_* value */.  i
0960: 6e 74 20 6e 46 61 69 6c 3b 20 20 20 20 20 20 20  nt nFail;       
0970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0980: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 66 61 75 6c  * Number of faul
0990: 74 73 20 69 6e 6a 65 63 74 65 64 20 2a 2f 0a 7d  ts injected */.}
09a0: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74  ;../*.** An inst
09b0: 61 6e 63 65 20 6f 66 20 74 68 69 73 20 73 74 72  ance of this str
09c0: 75 63 74 75 72 65 20 69 73 20 61 6c 6c 6f 63 61  ucture is alloca
09d0: 74 65 64 20 66 6f 72 20 65 61 63 68 20 56 46 53  ted for each VFS
09e0: 20 63 72 65 61 74 65 64 2e 20 54 68 65 0a 2a 2a   created. The.**
09f0: 20 73 71 6c 69 74 65 33 5f 76 66 73 2e 70 41 70   sqlite3_vfs.pAp
0a00: 70 44 61 74 61 20 66 69 65 6c 64 20 6f 66 20 74  pData field of t
0a10: 68 65 20 56 46 53 20 73 74 72 75 63 74 75 72 65  he VFS structure
0a20: 20 72 65 67 69 73 74 65 72 65 64 20 77 69 74 68   registered with
0a30: 20 53 51 4c 69 74 65 0a 2a 2a 20 69 73 20 73 65   SQLite.** is se
0a40: 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 69 74  t to point to it
0a50: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73 74  ..*/.struct Test
0a60: 76 66 73 20 7b 0a 20 20 63 68 61 72 20 2a 7a 4e  vfs {.  char *zN
0a70: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
0a80: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
0a90: 6f 66 20 74 68 69 73 20 56 46 53 20 2a 2f 0a 20  of this VFS */. 
0aa0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 50   sqlite3_vfs *pP
0ab0: 61 72 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20  arent;          
0ac0: 20 2f 2a 20 54 68 65 20 56 46 53 20 74 6f 20 75   /* The VFS to u
0ad0: 73 65 20 66 6f 72 20 66 69 6c 65 20 49 4f 20 2a  se for file IO *
0ae0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  /.  sqlite3_vfs 
0af0: 2a 70 56 66 73 3b 20 20 20 20 20 20 20 20 20 20  *pVfs;          
0b00: 20 20 20 20 2f 2a 20 54 68 65 20 74 65 73 74 76      /* The testv
0b10: 66 73 20 72 65 67 69 73 74 65 72 65 64 20 77 69  fs registered wi
0b20: 74 68 20 53 51 4c 69 74 65 20 2a 2f 0a 20 20 54  th SQLite */.  T
0b30: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
0b40: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  p;             /
0b50: 2a 20 49 6e 74 65 72 70 72 65 74 65 72 20 74 6f  * Interpreter to
0b60: 20 72 75 6e 20 73 63 72 69 70 74 20 69 6e 20 2a   run script in *
0b70: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63  /.  Tcl_Obj *pSc
0b80: 72 69 70 74 3b 20 20 20 20 20 20 20 20 20 20 20  ript;           
0b90: 20 20 20 20 2f 2a 20 53 63 72 69 70 74 20 74 6f      /* Script to
0ba0: 20 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e   execute */.  in
0bb0: 74 20 6e 53 63 72 69 70 74 3b 20 20 20 20 20 20  t nScript;      
0bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0bd0: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65   Number of eleme
0be0: 6e 74 73 20 69 6e 20 61 72 72 61 79 20 61 70 53  nts in array apS
0bf0: 63 72 69 70 74 20 2a 2f 0a 20 20 54 63 6c 5f 4f  cript */.  Tcl_O
0c00: 62 6a 20 2a 2a 61 70 53 63 72 69 70 74 3b 20 20  bj **apScript;  
0c10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
0c20: 72 61 79 20 76 65 72 73 69 6f 6e 20 6f 66 20 70  ray version of p
0c30: 53 63 72 69 70 74 20 2a 2f 0a 20 20 54 65 73 74  Script */.  Test
0c40: 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66 66  vfsBuffer *pBuff
0c50: 65 72 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  er;         /* L
0c60: 69 73 74 20 6f 66 20 73 68 61 72 65 64 20 62 75  ist of shared bu
0c70: 66 66 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20 69  ffers */.  int i
0c80: 73 4e 6f 73 68 6d 3b 0a 0a 20 20 69 6e 74 20 6d  sNoshm;..  int m
0c90: 61 73 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ask;            
0ca0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
0cb0: 73 6b 20 63 6f 6e 74 72 6f 6c 6c 69 6e 67 20 5b  sk controlling [
0cc0: 73 63 72 69 70 74 5d 20 61 6e 64 20 5b 69 6f 65  script] and [ioe
0cd0: 72 72 5d 20 2a 2f 0a 0a 20 20 54 65 73 74 46 61  rr] */..  TestFa
0ce0: 75 6c 74 49 6e 6a 65 63 74 20 69 6f 65 72 72 5f  ultInject ioerr_
0cf0: 65 72 72 3b 0a 20 20 54 65 73 74 46 61 75 6c 74  err;.  TestFault
0d00: 49 6e 6a 65 63 74 20 66 75 6c 6c 5f 65 72 72 3b  Inject full_err;
0d10: 0a 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65  .  TestFaultInje
0d20: 63 74 20 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b  ct cantopen_err;
0d30: 0a 0a 23 69 66 20 30 0a 20 20 69 6e 74 20 69 49  ..#if 0.  int iI
0d40: 6f 65 72 72 43 6e 74 3b 0a 20 20 69 6e 74 20 69  oerrCnt;.  int i
0d50: 6f 65 72 72 3b 0a 20 20 69 6e 74 20 6e 49 6f 65  oerr;.  int nIoe
0d60: 72 72 46 61 69 6c 3b 0a 20 20 69 6e 74 20 69 46  rrFail;.  int iF
0d70: 75 6c 6c 43 6e 74 3b 0a 20 20 69 6e 74 20 66 75  ullCnt;.  int fu
0d80: 6c 6c 65 72 72 3b 0a 20 20 69 6e 74 20 6e 46 75  llerr;.  int nFu
0d90: 6c 6c 46 61 69 6c 3b 0a 23 65 6e 64 69 66 0a 0a  llFail;.#endif..
0da0: 20 20 69 6e 74 20 69 44 65 76 63 68 61 72 3b 0a    int iDevchar;.
0db0: 20 20 69 6e 74 20 69 53 65 63 74 6f 72 73 69 7a    int iSectorsiz
0dc0: 65 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  e;.};../*.** The
0dd0: 20 54 65 73 74 76 66 73 2e 6d 61 73 6b 20 76 61   Testvfs.mask va
0de0: 72 69 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f  riable is set to
0df0: 20 61 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 20 6f   a combination o
0e00: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 2e  f the following.
0e10: 0a 2a 2a 20 49 66 20 61 20 62 69 74 20 69 73 20  .** If a bit is 
0e20: 63 6c 65 61 72 20 69 6e 20 54 65 73 74 76 66 73  clear in Testvfs
0e30: 2e 6d 61 73 6b 2c 20 74 68 65 6e 20 63 61 6c 6c  .mask, then call
0e40: 73 20 6d 61 64 65 20 62 79 20 53 51 4c 69 74 65  s made by SQLite
0e50: 20 74 6f 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72   to the .** corr
0e60: 65 73 70 6f 6e 64 69 6e 67 20 56 46 53 20 6d 65  esponding VFS me
0e70: 74 68 6f 64 20 69 73 20 69 67 6e 6f 72 65 64 20  thod is ignored 
0e80: 66 6f 72 20 70 75 72 70 6f 73 65 73 20 6f 66 3a  for purposes of:
0e90: 0a 2a 2a 0a 2a 2a 20 20 20 2b 20 53 69 6d 75 6c  .**.**   + Simul
0ea0: 61 74 69 6e 67 20 49 4f 20 65 72 72 6f 72 73 2c  ating IO errors,
0eb0: 20 61 6e 64 0a 2a 2a 20 20 20 2b 20 49 6e 76 6f   and.**   + Invo
0ec0: 6b 69 6e 67 20 74 68 65 20 54 63 6c 20 63 61 6c  king the Tcl cal
0ed0: 6c 62 61 63 6b 20 73 63 72 69 70 74 2e 0a 2a 2f  lback script..*/
0ee0: 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53  .#define TESTVFS
0ef0: 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 20 20  _SHMOPEN_MASK   
0f00: 20 30 78 30 30 30 30 30 30 30 31 0a 23 64 65 66   0x00000001.#def
0f10: 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d 4c  ine TESTVFS_SHML
0f20: 4f 43 4b 5f 4d 41 53 4b 20 20 20 20 30 78 30 30  OCK_MASK    0x00
0f30: 30 30 30 30 31 30 0a 23 64 65 66 69 6e 65 20 54  000010.#define T
0f40: 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41  ESTVFS_SHMMAP_MA
0f50: 53 4b 20 20 20 20 20 30 78 30 30 30 30 30 30 32  SK     0x0000002
0f60: 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  0.#define TESTVF
0f70: 53 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53  S_SHMBARRIER_MAS
0f80: 4b 20 30 78 30 30 30 30 30 30 34 30 0a 23 64 65  K 0x00000040.#de
0f90: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d  fine TESTVFS_SHM
0fa0: 43 4c 4f 53 45 5f 4d 41 53 4b 20 20 20 30 78 30  CLOSE_MASK   0x0
0fb0: 30 30 30 30 30 38 30 0a 0a 23 64 65 66 69 6e 65  0000080..#define
0fc0: 20 54 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41   TESTVFS_OPEN_MA
0fd0: 53 4b 20 20 20 20 20 20 20 30 78 30 30 30 30 30  SK       0x00000
0fe0: 31 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  100.#define TEST
0ff0: 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 20 20  VFS_SYNC_MASK   
1000: 20 20 20 20 30 78 30 30 30 30 30 32 30 30 0a 23      0x00000200.#
1010: 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 44  define TESTVFS_D
1020: 45 4c 45 54 45 5f 4d 41 53 4b 20 20 20 20 20 30  ELETE_MASK     0
1030: 78 30 30 30 30 30 34 30 30 0a 23 64 65 66 69 6e  x00000400.#defin
1040: 65 20 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f  e TESTVFS_CLOSE_
1050: 4d 41 53 4b 20 20 20 20 20 20 30 78 30 30 30 30  MASK      0x0000
1060: 30 38 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53  0800.#define TES
1070: 54 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20  TVFS_WRITE_MASK 
1080: 20 20 20 20 20 30 78 30 30 30 30 31 30 30 30 0a       0x00001000.
1090: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
10a0: 54 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 20 20  TRUNCATE_MASK   
10b0: 30 78 30 30 30 30 32 30 30 30 0a 23 64 65 66 69  0x00002000.#defi
10c0: 6e 65 20 54 45 53 54 56 46 53 5f 41 43 43 45 53  ne TESTVFS_ACCES
10d0: 53 5f 4d 41 53 4b 20 20 20 20 20 30 78 30 30 30  S_MASK     0x000
10e0: 30 34 30 30 30 0a 23 64 65 66 69 6e 65 20 54 45  04000.#define TE
10f0: 53 54 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20 20  STVFS_ALL_MASK  
1100: 20 20 20 20 20 20 30 78 30 30 30 30 37 46 46 46        0x00007FFF
1110: 0a 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  ...#define TESTV
1120: 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 31 30 32  FS_MAX_PAGES 102
1130: 34 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72 65  4../*.** A share
1140: 64 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e  d-memory buffer.
1150: 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f 66   There is one of
1160: 20 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20 66   these objects f
1170: 6f 72 20 65 61 63 68 20 73 68 61 72 65 64 0a 2a  or each shared.*
1180: 2a 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20  * memory region 
1190: 6f 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74  opened by client
11a0: 73 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e 74  s. If two client
11b0: 73 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65 20  s open the same 
11c0: 66 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20 61  file,.** there a
11d0: 72 65 20 74 77 6f 20 54 65 73 74 76 66 73 46 69  re two TestvfsFi
11e0: 6c 65 20 73 74 72 75 63 74 75 72 65 73 20 62 75  le structures bu
11f0: 74 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74 76  t only one Testv
1200: 66 73 42 75 66 66 65 72 20 73 74 72 75 63 74 75  fsBuffer structu
1210: 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65  re..*/.struct Te
1220: 73 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20 20  stvfsBuffer {.  
1230: 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20 20  char *zFile;    
1240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1250: 2f 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66 69  /* Associated fi
1260: 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74  le name */.  int
1270: 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20   pgsz;          
1280: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1290: 50 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 75  Page size */.  u
12a0: 38 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46 53  8 *aPage[TESTVFS
12b0: 5f 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20 2f  _MAX_PAGES];   /
12c0: 2a 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c 6c  * Array of ckall
12d0: 6f 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20 20  oc'd pages */.  
12e0: 54 65 73 74 76 66 73 46 64 20 2a 70 46 69 6c 65  TestvfsFd *pFile
12f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1300: 2f 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e 20  /* List of open 
1310: 68 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65 73  handles */.  Tes
1320: 74 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65 78  tvfsBuffer *pNex
1330: 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t;           /* 
1340: 4e 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c  Next in linked l
1350: 69 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66 65  ist of all buffe
1360: 72 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69  rs */.};...#defi
1370: 6e 65 20 50 41 52 45 4e 54 56 46 53 28 78 29 20  ne PARENTVFS(x) 
1380: 28 28 28 54 65 73 74 76 66 73 20 2a 29 28 28 78  (((Testvfs *)((x
1390: 29 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e 70  )->pAppData))->p
13a0: 50 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e 65  Parent)..#define
13b0: 20 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52 47   TESTVFS_MAX_ARG
13c0: 53 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  S 12.../*.** Met
13d0: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
13e0: 20 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c 65   for TestvfsFile
13f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1400: 74 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65  tvfsClose(sqlite
1410: 33 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63  3_file*);.static
1420: 20 69 6e 74 20 74 76 66 73 52 65 61 64 28 73 71   int tvfsRead(sq
1430: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f 69  lite3_file*, voi
1440: 64 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73 71  d*, int iAmt, sq
1450: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
1460: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
1470: 76 66 73 57 72 69 74 65 28 73 71 6c 69 74 65 33  vfsWrite(sqlite3
1480: 5f 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f 69  _file*,const voi
1490: 64 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c  d*,int iAmt, sql
14a0: 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74  ite3_int64 iOfst
14b0: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
14c0: 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74  fsTruncate(sqlit
14d0: 65 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74 65  e3_file*, sqlite
14e0: 33 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a 73  3_int64 size);.s
14f0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 79  tatic int tvfsSy
1500: 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  nc(sqlite3_file*
1510: 2c 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74  , int flags);.st
1520: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 69 6c  atic int tvfsFil
1530: 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69  eSize(sqlite3_fi
1540: 6c 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  le*, sqlite3_int
1550: 36 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61 74  64 *pSize);.stat
1560: 69 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28  ic int tvfsLock(
1570: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69  sqlite3_file*, i
1580: 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  nt);.static int 
1590: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
15a0: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a  e3_file*, int);.
15b0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43  static int tvfsC
15c0: 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b  heckReservedLock
15d0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
15e0: 69 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69  int *);.static i
15f0: 6e 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72  nt tvfsFileContr
1600: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  ol(sqlite3_file*
1610: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
1620: 70 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69 6e  pArg);.static in
1630: 74 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65  t tvfsSectorSize
1640: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b  (sqlite3_file*);
1650: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
1660: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
1670: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
1680: 6c 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74  le*);../*.** Met
1690: 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73  hod declarations
16a0: 20 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a 2a   for tvfs_vfs..*
16b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
16c0: 73 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66  sOpen(sqlite3_vf
16d0: 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  s*, const char *
16e0: 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  , sqlite3_file*,
16f0: 20 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73   int , int *);.s
1700: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65  tatic int tvfsDe
1710: 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73  lete(sqlite3_vfs
1720: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  *, const char *z
1730: 4e 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69  Name, int syncDi
1740: 72 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  r);.static int t
1750: 76 66 73 41 63 63 65 73 73 28 73 71 6c 69 74 65  vfsAccess(sqlite
1760: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
1770: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66  ar *zName, int f
1780: 6c 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  lags, int *);.st
1790: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c  atic int tvfsFul
17a0: 6c 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65  lPathname(sqlite
17b0: 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68  3_vfs*, const ch
17c0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20  ar *zName, int, 
17d0: 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69 66  char *zOut);.#if
17e0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
17f0: 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a  _LOAD_EXTENSION.
1800: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66  static void *tvf
1810: 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  sDlOpen(sqlite3_
1820: 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72  vfs*, const char
1830: 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73 74   *zFilename);.st
1840: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
1850: 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66  Error(sqlite3_vf
1860: 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  s*, int nByte, c
1870: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a 73  har *zErrMsg);.s
1880: 74 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66  tatic void (*tvf
1890: 73 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76  sDlSym(sqlite3_v
18a0: 66 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73 74  fs*,void*, const
18b0: 20 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29 29   char *zSymbol))
18c0: 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76  (void);.static v
18d0: 6f 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28  oid tvfsDlClose(
18e0: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f  sqlite3_vfs*, vo
18f0: 69 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20  id*);.#endif /* 
1900: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
1910: 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73 74  _EXTENSION */.st
1920: 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e  atic int tvfsRan
1930: 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f  domness(sqlite3_
1940: 76 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c  vfs*, int nByte,
1950: 20 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74   char *zOut);.st
1960: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65  atic int tvfsSle
1970: 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  ep(sqlite3_vfs*,
1980: 20 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e 64   int microsecond
1990: 73 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  s);.static int t
19a0: 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73  vfsCurrentTime(s
19b0: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f 75  qlite3_vfs*, dou
19c0: 62 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69  ble*);..static i
19d0: 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73  nt tvfsShmOpen(s
19e0: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73  qlite3_file*);.s
19f0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68  tatic int tvfsSh
1a00: 6d 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  mLock(sqlite3_fi
1a10: 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 2c 20  le*, int , int, 
1a20: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
1a30: 20 74 76 66 73 53 68 6d 4d 61 70 28 73 71 6c 69   tvfsShmMap(sqli
1a40: 74 65 33 5f 66 69 6c 65 2a 2c 69 6e 74 2c 69 6e  te3_file*,int,in
1a50: 74 2c 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c 61  t,int, void vola
1a60: 74 69 6c 65 20 2a 2a 29 3b 0a 73 74 61 74 69 63  tile **);.static
1a70: 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72   void tvfsShmBar
1a80: 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c  rier(sqlite3_fil
1a90: 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  e*);.static int 
1aa0: 74 76 66 73 53 68 6d 55 6e 6d 61 70 28 73 71 6c  tvfsShmUnmap(sql
1ab0: 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29  ite3_file*, int)
1ac0: 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  ;..static sqlite
1ad0: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 74 76 66  3_io_methods tvf
1ae0: 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 3d 20 7b  s_io_methods = {
1af0: 0a 20 20 32 2c 20 20 20 20 20 20 20 20 20 20 20  .  2,           
1b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b10: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
1b20: 2f 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20 20  /.  tvfsClose,  
1b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b40: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a 2f      /* xClose */
1b50: 0a 20 20 74 76 66 73 52 65 61 64 2c 20 20 20 20  .  tvfsRead,    
1b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b70: 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a 20     /* xRead */. 
1b80: 20 74 76 66 73 57 72 69 74 65 2c 20 20 20 20 20   tvfsWrite,     
1b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ba0: 20 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20 20   /* xWrite */.  
1bb0: 74 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20 20  tvfsTruncate,   
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bd0: 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a  /* xTruncate */.
1be0: 20 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20 20    tvfsSync,     
1bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c00: 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20    /* xSync */.  
1c10: 74 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20 20  tvfsFileSize,   
1c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c30: 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f 0a  /* xFileSize */.
1c40: 20 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20 20    tvfsLock,     
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c60: 20 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20    /* xLock */.  
1c70: 74 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20 20  tvfsUnlock,     
1c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c90: 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20  /* xUnlock */.  
1ca0: 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76 65  tvfsCheckReserve
1cb0: 64 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20  dLock,          
1cc0: 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  /* xCheckReserve
1cd0: 64 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73 46  dLock */.  tvfsF
1ce0: 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20 20  ileControl,     
1cf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
1d00: 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20  ileControl */.  
1d10: 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c 20  tvfsSectorSize, 
1d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d30: 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20 2a  /* xSectorSize *
1d40: 2f 0a 20 20 74 76 66 73 44 65 76 69 63 65 43 68  /.  tvfsDeviceCh
1d50: 61 72 61 63 74 65 72 69 73 74 69 63 73 2c 20 20  aracteristics,  
1d60: 20 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43 68      /* xDeviceCh
1d70: 61 72 61 63 74 65 72 69 73 74 69 63 73 20 2a 2f  aracteristics */
1d80: 0a 20 20 74 76 66 73 53 68 6d 4d 61 70 2c 20 20  .  tvfsShmMap,  
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1da0: 20 20 20 2f 2a 20 78 53 68 6d 4d 61 70 20 2a 2f     /* xShmMap */
1db0: 0a 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c 20  .  tvfsShmLock, 
1dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dd0: 20 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a     /* xShmLock *
1de0: 2f 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72 69  /.  tvfsShmBarri
1df0: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
1e00: 20 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69      /* xShmBarri
1e10: 65 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 55  er */.  tvfsShmU
1e20: 6e 6d 61 70 20 20 20 20 20 20 20 20 20 20 20 20  nmap            
1e30: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55          /* xShmU
1e40: 6e 6d 61 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74  nmap */.};..stat
1e50: 69 63 20 69 6e 74 20 74 76 66 73 52 65 73 75 6c  ic int tvfsResul
1e60: 74 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a 70  tCode(Testvfs *p
1e70: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 73  , int *pRc){.  s
1e80: 74 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b 0a  truct errcode {.
1e90: 20 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a 20      int eCode;. 
1ea0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
1eb0: 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65 5b  Code;.  } aCode[
1ec0: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c 49  ] = {.    { SQLI
1ed0: 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c 49  TE_OK,     "SQLI
1ee0: 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20 20  TE_OK"     },.  
1ef0: 20 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f 52    { SQLITE_ERROR
1f00: 2c 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52  ,  "SQLITE_ERROR
1f10: 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  "  },.    { SQLI
1f20: 54 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c 49  TE_IOERR,  "SQLI
1f30: 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20 20  TE_IOERR"  },.  
1f40: 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45    { SQLITE_LOCKE
1f50: 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b 45  D, "SQLITE_LOCKE
1f60: 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  D" },.    { SQLI
1f70: 54 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c 49  TE_BUSY,   "SQLI
1f80: 54 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20 20  TE_BUSY"   },.  
1f90: 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  };..  const char
1fa0: 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20   *z;.  int i;.. 
1fb0: 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69   z = Tcl_GetStri
1fc0: 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  ngResult(p->inte
1fd0: 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  rp);.  for(i=0; 
1fe0: 69 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f 64  i<ArraySize(aCod
1ff0: 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  e); i++){.    if
2000: 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 61  ( 0==strcmp(z, a
2010: 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20 29  Code[i].zCode) )
2020: 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 61  {.      *pRc = a
2030: 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a 20  Code[i].eCode;. 
2040: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
2050: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
2060: 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 0;.}..static 
2070: 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 61  int tvfsInjectFa
2080: 75 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e 6a  ult(TestFaultInj
2090: 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ect *p){.  int r
20a0: 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d  et = 0;.  if( p-
20b0: 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20 70  >eFault ){.    p
20c0: 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69 66  ->iCnt--;.    if
20d0: 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c 20  ( p->iCnt==0 || 
20e0: 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70 2d  (p->iCnt<0 && p-
20f0: 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f 49  >eFault==FAULT_I
2100: 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e 54  NJECT_PERSISTENT
2110: 20 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20   ) ){.      ret 
2120: 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46  = 1;.      p->nF
2130: 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  ail++;.    }.  }
2140: 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d  .  return ret;.}
2150: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  ...static int tv
2160: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54 65  fsInjectIoerr(Te
2170: 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74  stvfs *p){.  ret
2180: 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61  urn tvfsInjectFa
2190: 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65 72  ult(&p->ioerr_er
21a0: 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  r);.}..static in
21b0: 74 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c  t tvfsInjectFull
21c0: 65 72 72 28 54 65 73 74 76 66 73 20 2a 70 29 7b  err(Testvfs *p){
21d0: 0a 20 20 72 65 74 75 72 6e 20 74 76 66 73 49 6e  .  return tvfsIn
21e0: 6a 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66 75  jectFault(&p->fu
21f0: 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74 69  ll_err);.}.stati
2200: 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74  c int tvfsInject
2210: 43 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73 74  Cantopenerr(Test
2220: 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  vfs *p){.  retur
2230: 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75 6c  n tvfsInjectFaul
2240: 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65  t(&p->cantopen_e
2250: 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20  rr);.}...static 
2260: 76 6f 69 64 20 74 76 66 73 45 78 65 63 54 63 6c  void tvfsExecTcl
2270: 28 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c 20  (.  Testvfs *p, 
2280: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2290: 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f 62  Method,.  Tcl_Ob
22a0: 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f 4f  j *arg1,.  Tcl_O
22b0: 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c 5f  bj *arg2,.  Tcl_
22c0: 4f 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20 69  Obj *arg3.){.  i
22d0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22f0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72  * Return code fr
2300: 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28 29  om Tcl_EvalObj()
2310: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 3b 20   */.  int nArg; 
2320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2330: 20 20 20 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74        /* Element
2340: 73 20 69 6e 20 65 76 61 6c 27 64 20 6c 69 73 74  s in eval'd list
2350: 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70   */.  int nScrip
2360: 74 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 20  t;.  Tcl_Obj ** 
2370: 61 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  ap;..  assert( p
2380: 2d 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a 20 20  ->pScript );..  
2390: 69 66 28 20 21 70 2d 3e 61 70 53 63 72 69 70 74  if( !p->apScript
23a0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   ){.    int nByt
23b0: 65 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  e;.    int i;.  
23c0: 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63    if( TCL_OK!=Tc
23d0: 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d  l_ListObjGetElem
23e0: 65 6e 74 73 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ents(p->interp, 
23f0: 70 2d 3e 70 53 63 72 69 70 74 2c 20 26 6e 53 63  p->pScript, &nSc
2400: 72 69 70 74 2c 20 26 61 70 29 20 29 7b 0a 20 20  ript, &ap) ){.  
2410: 20 20 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75      Tcl_Backgrou
2420: 6e 64 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72  ndError(p->inter
2430: 70 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 52 65  p);.      Tcl_Re
2440: 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  setResult(p->int
2450: 65 72 70 29 3b 0a 20 20 20 20 20 20 72 65 74 75  erp);.      retu
2460: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  rn;.    }.    p-
2470: 3e 6e 53 63 72 69 70 74 20 3d 20 6e 53 63 72 69  >nScript = nScri
2480: 70 74 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20  pt;.    nByte = 
2490: 28 6e 53 63 72 69 70 74 2b 54 45 53 54 56 46 53  (nScript+TESTVFS
24a0: 5f 4d 41 58 5f 41 52 47 53 29 2a 73 69 7a 65 6f  _MAX_ARGS)*sizeo
24b0: 66 28 54 63 6c 5f 4f 62 6a 20 2a 29 3b 0a 20 20  f(Tcl_Obj *);.  
24c0: 20 20 70 2d 3e 61 70 53 63 72 69 70 74 20 3d 20    p->apScript = 
24d0: 28 54 63 6c 5f 4f 62 6a 20 2a 2a 29 63 6b 61 6c  (Tcl_Obj **)ckal
24e0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
24f0: 6d 65 6d 73 65 74 28 70 2d 3e 61 70 53 63 72 69  memset(p->apScri
2500: 70 74 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  pt, 0, nByte);. 
2510: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53     for(i=0; i<nS
2520: 63 72 69 70 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  cript; i++){.   
2530: 20 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 69     p->apScript[i
2540: 5d 20 3d 20 61 70 5b 69 5d 3b 0a 20 20 20 20 7d  ] = ap[i];.    }
2550: 0a 20 20 7d 0a 0a 20 20 70 2d 3e 61 70 53 63 72  .  }..  p->apScr
2560: 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 5d 20  ipt[p->nScript] 
2570: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
2580: 62 6a 28 7a 4d 65 74 68 6f 64 2c 20 2d 31 29 3b  bj(zMethod, -1);
2590: 0a 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 70  .  p->apScript[p
25a0: 2d 3e 6e 53 63 72 69 70 74 2b 31 5d 20 3d 20 61  ->nScript+1] = a
25b0: 72 67 31 3b 0a 20 20 70 2d 3e 61 70 53 63 72 69  rg1;.  p->apScri
25c0: 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 2b 32 5d  pt[p->nScript+2]
25d0: 20 3d 20 61 72 67 32 3b 0a 20 20 70 2d 3e 61 70   = arg2;.  p->ap
25e0: 53 63 72 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70  Script[p->nScrip
25f0: 74 2b 33 5d 20 3d 20 61 72 67 33 3b 0a 0a 20 20  t+3] = arg3;..  
2600: 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53 63 72  for(nArg=p->nScr
2610: 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69 70 74  ipt; p->apScript
2620: 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b 29 7b  [nArg]; nArg++){
2630: 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  .    Tcl_IncrRef
2640: 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72 69 70  Count(p->apScrip
2650: 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 7d 0a 0a 20  t[nArg]);.  }.. 
2660: 20 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62   rc = Tcl_EvalOb
2670: 6a 76 28 70 2d 3e 69 6e 74 65 72 70 2c 20 6e 41  jv(p->interp, nA
2680: 72 67 2c 20 70 2d 3e 61 70 53 63 72 69 70 74 2c  rg, p->apScript,
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 0a  ->interp);.  }..
2700: 20 20 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53    for(nArg=p->nS
2710: 63 72 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69  cript; p->apScri
2720: 70 74 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b  pt[nArg]; nArg++
2730: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2740: 65 66 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72  efCount(p->apScr
2750: 69 70 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 20 20  ipt[nArg]);.    
2760: 70 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67  p->apScript[nArg
2770: 5d 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f  ] = 0;.  }.}.../
2780: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 74 76  *.** Close an tv
2790: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
27a0: 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f 73 65  ic int tvfsClose
27b0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
27c0: 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b  File){.  int rc;
27d0: 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a  .  TestvfsFile *
27e0: 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73  pTestfile = (Tes
27f0: 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65  tvfsFile *)pFile
2800: 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70  ;.  TestvfsFd *p
2810: 46 64 20 3d 20 70 54 65 73 74 66 69 6c 65 2d 3e  Fd = pTestfile->
2820: 70 46 64 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  pFd;.  Testvfs *
2830: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
2840: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
2850: 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  ta;..  if( p->pS
2860: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
2870: 26 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d  &TESTVFS_CLOSE_M
2880: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
2890: 78 65 63 54 63 6c 28 70 2c 20 22 78 43 6c 6f 73  xecTcl(p, "xClos
28a0: 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  e", .        Tcl
28b0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
28c0: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
28d0: 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20  ), pFd->pShmId, 
28e0: 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20  0.    );.  }..  
28f0: 69 66 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20  if( pFd->pShmId 
2900: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2910: 65 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70 53 68  efCount(pFd->pSh
2920: 6d 49 64 29 3b 0a 20 20 20 20 70 46 64 2d 3e 70  mId);.    pFd->p
2930: 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  ShmId = 0;.  }. 
2940: 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d 65 74   if( pFile->pMet
2950: 68 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b 66 72  hods ){.    ckfr
2960: 65 65 28 28 63 68 61 72 20 2a 29 70 46 69 6c 65  ee((char *)pFile
2970: 2d 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20 20 7d  ->pMethods);.  }
2980: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
2990: 73 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52 65 61  sClose(pFd->pRea
29a0: 6c 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68  l);.  ckfree((ch
29b0: 61 72 20 2a 29 70 46 64 29 3b 0a 20 20 70 54 65  ar *)pFd);.  pTe
29c0: 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 30 3b  stfile->pFd = 0;
29d0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
29e0: 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61 74 61  ./*.** Read data
29f0: 20 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d 66 69   from an tvfs-fi
2a00: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2a10: 74 20 74 76 66 73 52 65 61 64 28 0a 20 20 73 71  t tvfsRead(.  sq
2a20: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
2a30: 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42 75 66  e, .  void *zBuf
2a40: 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 0a  , .  int iAmt, .
2a50: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
2a60: 4f 66 73 74 0a 29 7b 0a 20 20 54 65 73 74 76 66  Ofst.){.  Testvf
2a70: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
2a80: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
2a90: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61  urn sqlite3OsRea
2aa0: 64 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66  d(p->pReal, zBuf
2ab0: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
2ac0: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64  }../*.** Write d
2ad0: 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73 2d 66  ata to an tvfs-f
2ae0: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
2af0: 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a 20 20  nt tvfsWrite(.  
2b00: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2b10: 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 76 6f  ile, .  const vo
2b20: 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74  id *zBuf, .  int
2b30: 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65   iAmt, .  sqlite
2b40: 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a  _int64 iOfst.){.
2b50: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2b60: 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46  E_OK;.  TestvfsF
2b70: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
2b80: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
2b90: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
2ba0: 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e  fs *)pFd->pVfs->
2bb0: 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28  pAppData;..  if(
2bc0: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
2bd0: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 57  ->mask&TESTVFS_W
2be0: 52 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  RITE_MASK ){.   
2bf0: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
2c00: 22 78 57 72 69 74 65 22 2c 20 0a 20 20 20 20 20  "xWrite", .     
2c10: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
2c20: 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61  Obj(pFd->zFilena
2c30: 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53  me, -1), pFd->pS
2c40: 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20  hmId, 0.    );. 
2c50: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
2c60: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  e(p, &rc);.  }..
2c70: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2c80: 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63  _OK && tvfsInjec
2c90: 74 46 75 6c 6c 65 72 72 28 70 29 20 29 7b 0a 20  tFullerr(p) ){. 
2ca0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46     rc = SQLITE_F
2cb0: 55 4c 4c 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  ULL;.  }.  if( r
2cc0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2cd0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
2ce0: 57 52 49 54 45 5f 4d 41 53 4b 20 26 26 20 74 76  WRITE_MASK && tv
2cf0: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29  fsInjectIoerr(p)
2d00: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
2d10: 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 20  ITE_IOERR;.  }. 
2d20: 20 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49   .  if( rc==SQLI
2d30: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
2d40: 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
2d50: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a 42 75  (pFd->pReal, zBu
2d60: 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b  f, iAmt, iOfst);
2d70: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
2d80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63  ;.}../*.** Trunc
2d90: 61 74 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ate an tvfs-file
2da0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2db0: 74 76 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c  tvfsTruncate(sql
2dc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
2dd0: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 73  , sqlite_int64 s
2de0: 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ize){.  int rc =
2df0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
2e00: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
2e10: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
2e20: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
2e30: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
2e40: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
2e50: 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70  .  if( p->pScrip
2e60: 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  t && p->mask&TES
2e70: 54 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41  TVFS_TRUNCATE_MA
2e80: 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78  SK ){.    tvfsEx
2e90: 65 63 54 63 6c 28 70 2c 20 22 78 54 72 75 6e 63  ecTcl(p, "xTrunc
2ea0: 61 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ate", .        T
2eb0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2ec0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
2ed0: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
2ee0: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74  , 0.    );.    t
2ef0: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
2f00: 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 0a 20 20   &rc);.  }.  .  
2f10: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2f20: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
2f30: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
2f40: 70 46 64 2d 3e 70 52 65 61 6c 2c 20 73 69 7a 65  pFd->pReal, size
2f50: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
2f60: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e  rc;.}../*.** Syn
2f70: 63 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  c an tvfs-file..
2f80: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2f90: 66 73 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 66  fsSync(sqlite3_f
2fa0: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
2fb0: 66 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20 72 63  flags){.  int rc
2fc0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
2fd0: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
2fe0: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
2ff0: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
3000: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
3010: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
3020: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
3030: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
3040: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
3050: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46   ){.    char *zF
3060: 6c 61 67 73 3b 0a 0a 20 20 20 20 73 77 69 74 63  lags;..    switc
3070: 68 28 20 66 6c 61 67 73 20 29 7b 0a 20 20 20 20  h( flags ){.    
3080: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59    case SQLITE_SY
3090: 4e 43 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20 20 20  NC_NORMAL:.     
30a0: 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72     zFlags = "nor
30b0: 6d 61 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72  mal";.        br
30c0: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
30d0: 53 51 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c  SQLITE_SYNC_FULL
30e0: 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73  :.        zFlags
30f0: 20 3d 20 22 66 75 6c 6c 22 3b 0a 20 20 20 20 20   = "full";.     
3100: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3110: 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43  case SQLITE_SYNC
3120: 5f 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53  _NORMAL|SQLITE_S
3130: 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20  YNC_DATAONLY:.  
3140: 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22        zFlags = "
3150: 6e 6f 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c 79 22  normal|dataonly"
3160: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
3170: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
3180: 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53 51 4c  TE_SYNC_FULL|SQL
3190: 49 54 45 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c  ITE_SYNC_DATAONL
31a0: 59 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67  Y:.        zFlag
31b0: 73 20 3d 20 22 66 75 6c 6c 7c 64 61 74 61 6f 6e  s = "full|dataon
31c0: 6c 79 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65  ly";.        bre
31d0: 61 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c  ak;.      defaul
31e0: 74 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  t:.        asser
31f0: 74 28 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  t(0);.    }..   
3200: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
3210: 22 78 53 79 6e 63 22 2c 20 0a 20 20 20 20 20 20  "xSync", .      
3220: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
3230: 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  bj(pFd->zFilenam
3240: 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68  e, -1), pFd->pSh
3250: 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c  mId,.        Tcl
3260: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 46  _NewStringObj(zF
3270: 6c 61 67 73 2c 20 2d 31 29 0a 20 20 20 20 29 3b  lags, -1).    );
3280: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
3290: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
32a0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
32b0: 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a  TE_OK && tvfsInj
32c0: 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 20  ectFullerr(p) ) 
32d0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c 4c  rc = SQLITE_FULL
32e0: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
32f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
3300: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
3310: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c 61  (pFd->pReal, fla
3320: 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  gs);.  }..  retu
3330: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
3340: 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 72 65  Return the curre
3350: 6e 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f 66 20  nt file-size of 
3360: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
3370: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3380: 46 69 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33  FileSize(sqlite3
3390: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71  _file *pFile, sq
33a0: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53 69 7a  lite_int64 *pSiz
33b0: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20  e){.  TestvfsFd 
33c0: 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64 28 70  *p = tvfsGetFd(p
33d0: 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e 20  File);.  return 
33e0: 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a  sqlite3OsFileSiz
33f0: 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69 7a  e(p->pReal, pSiz
3400: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63  e);.}../*.** Loc
3410: 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  k an tvfs-file..
3420: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3430: 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  fsLock(sqlite3_f
3440: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
3450: 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76 66  eLock){.  Testvf
3460: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
3470: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
3480: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63  urn sqlite3OsLoc
3490: 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63  k(p->pReal, eLoc
34a0: 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e 6c  k);.}../*.** Unl
34b0: 6f 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ock an tvfs-file
34c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
34d0: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
34e0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
34f0: 69 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65  int eLock){.  Te
3500: 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66  stvfsFd *p = tvf
3510: 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20  sGetFd(pFile);. 
3520: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
3530: 73 55 6e 6c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  sUnlock(p->pReal
3540: 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a  , eLock);.}../*.
3550: 2a 2a 20 43 68 65 63 6b 20 69 66 20 61 6e 6f 74  ** Check if anot
3560: 68 65 72 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  her file-handle 
3570: 68 6f 6c 64 73 20 61 20 52 45 53 45 52 56 45 44  holds a RESERVED
3580: 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 74 76 66 73   lock on an tvfs
3590: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
35a0: 20 69 6e 74 20 74 76 66 73 43 68 65 63 6b 52 65   int tvfsCheckRe
35b0: 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74  servedLock(sqlit
35c0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
35d0: 69 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20  int *pResOut){. 
35e0: 20 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20   TestvfsFd *p = 
35f0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
3600: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
3610: 65 33 4f 73 43 68 65 63 6b 52 65 73 65 72 76 65  e3OsCheckReserve
3620: 64 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20  dLock(p->pReal, 
3630: 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a  pResOut);.}../*.
3640: 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f 6c 20  ** File control 
3650: 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75 73 74  method. For cust
3660: 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e  om operations on
3670: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
3680: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
3690: 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c  sFileControl(sql
36a0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
36b0: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
36c0: 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76 66 73  pArg){.  Testvfs
36d0: 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46  Fd *p = tvfsGetF
36e0: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
36f0: 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65  rn sqlite3OsFile
3700: 43 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65 61 6c  Control(p->pReal
3710: 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d 0a 0a  , op, pArg);.}..
3720: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3730: 20 73 65 63 74 6f 72 2d 73 69 7a 65 20 69 6e 20   sector-size in 
3740: 62 79 74 65 73 20 66 6f 72 20 61 6e 20 74 76 66  bytes for an tvf
3750: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
3760: 63 20 69 6e 74 20 74 76 66 73 53 65 63 74 6f 72  c int tvfsSector
3770: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
3780: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73  e *pFile){.  Tes
3790: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
37a0: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
37b0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
37c0: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
37d0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
37e0: 20 69 66 28 20 70 2d 3e 69 53 65 63 74 6f 72 73   if( p->iSectors
37f0: 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65  ize>=0 ){.    re
3800: 74 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f 72 73  turn p->iSectors
3810: 69 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ize;.  }.  retur
3820: 6e 20 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f  n sqlite3OsSecto
3830: 72 53 69 7a 65 28 70 46 64 2d 3e 70 52 65 61 6c  rSize(pFd->pReal
3840: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
3850: 72 6e 20 74 68 65 20 64 65 76 69 63 65 20 63 68  rn the device ch
3860: 61 72 61 63 74 65 72 69 73 74 69 63 20 66 6c 61  aracteristic fla
3870: 67 73 20 73 75 70 70 6f 72 74 65 64 20 62 79 20  gs supported by 
3880: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
3890: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
38a0: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
38b0: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
38c0: 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65  le *pFile){.  Te
38d0: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
38e0: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
38f0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
3900: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
3910: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
3920: 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61    if( p->iDevcha
3930: 72 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  r>=0 ){.    retu
3940: 72 6e 20 70 2d 3e 69 44 65 76 63 68 61 72 3b 0a  rn p->iDevchar;.
3950: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c    }.  return sql
3960: 69 74 65 33 4f 73 44 65 76 69 63 65 43 68 61 72  ite3OsDeviceChar
3970: 61 63 74 65 72 69 73 74 69 63 73 28 70 46 64 2d  acteristics(pFd-
3980: 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  >pReal);.}../*.*
3990: 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73 20 66  * Open an tvfs f
39a0: 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73  ile handle..*/.s
39b0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 4f 70  tatic int tvfsOp
39c0: 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  en(.  sqlite3_vf
39d0: 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74  s *pVfs,.  const
39e0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20   char *zName,.  
39f0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
3a00: 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73  ile,.  int flags
3a10: 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61  ,.  int *pOutFla
3a20: 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  gs.){.  int rc;.
3a30: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
3a40: 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73 74  Testfile = (Test
3a50: 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  vfsFile *)pFile;
3a60: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
3a70: 64 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 49  d;.  Tcl_Obj *pI
3a80: 64 20 3d 20 30 3b 0a 20 20 54 65 73 74 76 66 73  d = 0;.  Testvfs
3a90: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
3aa0: 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  )pVfs->pAppData;
3ab0: 0a 0a 20 20 70 46 64 20 3d 20 28 54 65 73 74 76  ..  pFd = (Testv
3ac0: 66 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63 28 73  fsFd *)ckalloc(s
3ad0: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64 29  izeof(TestvfsFd)
3ae0: 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56 66   + PARENTVFS(pVf
3af0: 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20  s)->szOsFile);. 
3b00: 20 6d 65 6d 73 65 74 28 70 46 64 2c 20 30 2c 20   memset(pFd, 0, 
3b10: 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64  sizeof(TestvfsFd
3b20: 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56  ) + PARENTVFS(pV
3b30: 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a  fs)->szOsFile);.
3b40: 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30 3b    pFd->pShm = 0;
3b50: 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d  .  pFd->pShmId =
3b60: 20 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69 6c 65   0;.  pFd->zFile
3b70: 6e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20  name = zName;.  
3b80: 70 46 64 2d 3e 70 56 66 73 20 3d 20 70 56 66 73  pFd->pVfs = pVfs
3b90: 3b 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c 20 3d  ;.  pFd->pReal =
3ba0: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a   (sqlite3_file *
3bb0: 29 26 70 46 64 5b 31 5d 3b 0a 20 20 6d 65 6d 73  )&pFd[1];.  mems
3bc0: 65 74 28 70 54 65 73 74 66 69 6c 65 2c 20 30 2c  et(pTestfile, 0,
3bd0: 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46   sizeof(TestvfsF
3be0: 69 6c 65 29 29 3b 0a 20 20 70 54 65 73 74 66 69  ile));.  pTestfi
3bf0: 6c 65 2d 3e 70 46 64 20 3d 20 70 46 64 3b 0a 0a  le->pFd = pFd;..
3c00: 20 20 2f 2a 20 45 76 61 6c 75 61 74 65 20 74 68    /* Evaluate th
3c10: 65 20 54 63 6c 20 73 63 72 69 70 74 3a 20 0a 20  e Tcl script: . 
3c20: 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43 52 49 50   **.  **   SCRIP
3c30: 54 20 78 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45  T xOpen FILENAME
3c40: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 74 68  .  **.  ** If th
3c50: 65 20 73 63 72 69 70 74 20 72 65 74 75 72 6e 73  e script returns
3c60: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
3c70: 20 63 6f 64 65 20 6f 74 68 65 72 20 74 68 61 6e   code other than
3c80: 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 61 6e 0a 20   SQLITE_OK, an. 
3c90: 20 2a 2a 20 65 72 72 6f 72 20 69 73 20 72 65 74   ** error is ret
3ca0: 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c  urned to the cal
3cb0: 6c 65 72 2e 20 49 66 20 69 74 20 72 65 74 75 72  ler. If it retur
3cc0: 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 74 68  ns SQLITE_OK, th
3cd0: 65 20 6e 65 77 0a 20 20 2a 2a 20 63 6f 6e 6e 65  e new.  ** conne
3ce0: 63 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22  ction is named "
3cf0: 61 6e 6f 6e 22 2e 20 4f 74 68 65 72 77 69 73 65  anon". Otherwise
3d00: 2c 20 74 68 65 20 76 61 6c 75 65 20 72 65 74 75  , the value retu
3d10: 72 6e 65 64 20 62 79 20 74 68 65 0a 20 20 2a 2a  rned by the.  **
3d20: 20 73 63 72 69 70 74 20 69 73 20 75 73 65 64 20   script is used 
3d30: 61 73 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f  as the connectio
3d40: 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 54  n name..  */.  T
3d50: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70  cl_ResetResult(p
3d60: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69 66 28  ->interp);.  if(
3d70: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
3d80: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 4f  ->mask&TESTVFS_O
3d90: 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20  PEN_MASK ){.    
3da0: 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22  tvfsExecTcl(p, "
3db0: 78 4f 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77 53  xOpen", Tcl_NewS
3dc0: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46  tringObj(pFd->zF
3dd0: 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30 2c  ilename, -1), 0,
3de0: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66   0);.    if( tvf
3df0: 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26  sResultCode(p, &
3e00: 72 63 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  rc) ){.      if(
3e10: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3e20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
3e30: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 49 64  }else{.      pId
3e40: 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73   = Tcl_GetObjRes
3e50: 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a  ult(p->interp);.
3e60: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
3e70: 20 28 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46   (p->mask&TESTVF
3e80: 53 5f 4f 50 45 4e 5f 4d 41 53 4b 29 20 26 26 20  S_OPEN_MASK) && 
3e90: 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72   tvfsInjectIoerr
3ea0: 28 70 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c  (p) ) return SQL
3eb0: 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 69 66 28  ITE_IOERR;.  if(
3ec0: 20 74 76 66 73 49 6e 6a 65 63 74 43 61 6e 74 6f   tvfsInjectCanto
3ed0: 70 65 6e 65 72 72 28 70 29 20 29 20 72 65 74 75  penerr(p) ) retu
3ee0: 72 6e 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50  rn SQLITE_CANTOP
3ef0: 45 4e 3b 0a 20 20 69 66 28 20 74 76 66 73 49 6e  EN;.  if( tvfsIn
3f00: 6a 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29  jectFullerr(p) )
3f10: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 46   return SQLITE_F
3f20: 55 4c 4c 3b 0a 0a 20 20 69 66 28 20 21 70 49 64  ULL;..  if( !pId
3f30: 20 29 7b 0a 20 20 20 20 70 49 64 20 3d 20 54 63   ){.    pId = Tc
3f40: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
3f50: 61 6e 6f 6e 22 2c 20 2d 31 29 3b 0a 20 20 7d 0a  anon", -1);.  }.
3f60: 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75    Tcl_IncrRefCou
3f70: 6e 74 28 70 49 64 29 3b 0a 20 20 70 46 64 2d 3e  nt(pId);.  pFd->
3f80: 70 53 68 6d 49 64 20 3d 20 70 49 64 3b 0a 20 20  pShmId = pId;.  
3f90: 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28  Tcl_ResetResult(
3fa0: 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 0a 20 20 72  p->interp);..  r
3fb0: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  c = sqlite3OsOpe
3fc0: 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  n(PARENTVFS(pVfs
3fd0: 29 2c 20 7a 4e 61 6d 65 2c 20 70 46 64 2d 3e 70  ), zName, pFd->p
3fe0: 52 65 61 6c 2c 20 66 6c 61 67 73 2c 20 70 4f 75  Real, flags, pOu
3ff0: 74 46 6c 61 67 73 29 3b 0a 20 20 69 66 28 20 70  tFlags);.  if( p
4000: 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d 65 74 68  Fd->pReal->pMeth
4010: 6f 64 73 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ods ){.    sqlit
4020: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 70  e3_io_methods *p
4030: 4d 65 74 68 6f 64 73 3b 0a 20 20 20 20 69 6e 74  Methods;.    int
4040: 20 6e 42 79 74 65 3b 0a 0a 20 20 20 20 69 66 28   nByte;..    if(
4050: 20 70 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 3e   pVfs->iVersion>
4060: 31 20 29 7b 0a 20 20 20 20 20 20 6e 42 79 74 65  1 ){.      nByte
4070: 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65   = sizeof(sqlite
4080: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29 3b 0a 20  3_io_methods);. 
4090: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
40a0: 6e 42 79 74 65 20 3d 20 6f 66 66 73 65 74 6f 66  nByte = offsetof
40b0: 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68  (sqlite3_io_meth
40c0: 6f 64 73 2c 20 78 53 68 6d 4d 61 70 29 3b 0a 20  ods, xShmMap);. 
40d0: 20 20 20 7d 0a 0a 20 20 20 20 70 4d 65 74 68 6f     }..    pMetho
40e0: 64 73 20 3d 20 28 73 71 6c 69 74 65 33 5f 69 6f  ds = (sqlite3_io
40f0: 5f 6d 65 74 68 6f 64 73 20 2a 29 63 6b 61 6c 6c  _methods *)ckall
4100: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 6d  oc(nByte);.    m
4110: 65 6d 63 70 79 28 70 4d 65 74 68 6f 64 73 2c 20  emcpy(pMethods, 
4120: 26 74 76 66 73 5f 69 6f 5f 6d 65 74 68 6f 64 73  &tvfs_io_methods
4130: 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 4d  , nByte);.    pM
4140: 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69 6f 6e  ethods->iVersion
4150: 20 3d 20 70 56 66 73 2d 3e 69 56 65 72 73 69 6f   = pVfs->iVersio
4160: 6e 3b 0a 20 20 20 20 69 66 28 20 70 56 66 73 2d  n;.    if( pVfs-
4170: 3e 69 56 65 72 73 69 6f 6e 3e 31 20 26 26 20 28  >iVersion>1 && (
4180: 28 54 65 73 74 76 66 73 20 2a 29 70 56 66 73 2d  (Testvfs *)pVfs-
4190: 3e 70 41 70 70 44 61 74 61 29 2d 3e 69 73 4e 6f  >pAppData)->isNo
41a0: 73 68 6d 20 29 7b 0a 20 20 20 20 20 20 70 4d 65  shm ){.      pMe
41b0: 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e 6d 61 70  thods->xShmUnmap
41c0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74   = 0;.      pMet
41d0: 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63 6b 20 3d  hods->xShmLock =
41e0: 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74 68 6f   0;.      pMetho
41f0: 64 73 2d 3e 78 53 68 6d 42 61 72 72 69 65 72 20  ds->xShmBarrier 
4200: 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74 68  = 0;.      pMeth
4210: 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 20 3d 20 30  ods->xShmMap = 0
4220: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 46 69 6c  ;.    }.    pFil
4230: 65 2d 3e 70 4d 65 74 68 6f 64 73 20 3d 20 70 4d  e->pMethods = pM
4240: 65 74 68 6f 64 73 3b 0a 20 20 7d 0a 0a 20 20 72  ethods;.  }..  r
4250: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
4260: 2a 2a 20 44 65 6c 65 74 65 20 74 68 65 20 66 69  ** Delete the fi
4270: 6c 65 20 6c 6f 63 61 74 65 64 20 61 74 20 7a 50  le located at zP
4280: 61 74 68 2e 20 49 66 20 74 68 65 20 64 69 72 53  ath. If the dirS
4290: 79 6e 63 20 61 72 67 75 6d 65 6e 74 20 69 73 20  ync argument is 
42a0: 74 72 75 65 2c 0a 2a 2a 20 65 6e 73 75 72 65 20  true,.** ensure 
42b0: 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65 6d 20  the file-system 
42c0: 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73 20 61 72  modifications ar
42d0: 65 20 73 79 6e 63 65 64 20 74 6f 20 64 69 73 6b  e synced to disk
42e0: 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74 75 72   before.** retur
42f0: 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ning..*/.static 
4300: 69 6e 74 20 74 76 66 73 44 65 6c 65 74 65 28 73  int tvfsDelete(s
4310: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4320: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50  , const char *zP
4330: 61 74 68 2c 20 69 6e 74 20 64 69 72 53 79 6e 63  ath, int dirSync
4340: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
4350: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76  LITE_OK;.  Testv
4360: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
4370: 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74   *)pVfs->pAppDat
4380: 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  a;..  if( p->pSc
4390: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
43a0: 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d  TESTVFS_DELETE_M
43b0: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
43c0: 78 65 63 54 63 6c 28 70 2c 20 22 78 44 65 6c 65  xecTcl(p, "xDele
43d0: 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  te", .        Tc
43e0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a  l_NewStringObj(z
43f0: 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f 4e  Path, -1), Tcl_N
4400: 65 77 49 6e 74 4f 62 6a 28 64 69 72 53 79 6e 63  ewIntObj(dirSync
4410: 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20  ), 0.    );.    
4420: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
4430: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 69 66  , &rc);.  }.  if
4440: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4450: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
4460: 74 65 33 4f 73 44 65 6c 65 74 65 28 50 41 52 45  te3OsDelete(PARE
4470: 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61  NTVFS(pVfs), zPa
4480: 74 68 2c 20 64 69 72 53 79 6e 63 29 3b 0a 20 20  th, dirSync);.  
4490: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
44a0: 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 66 6f 72  ../*.** Test for
44b0: 20 61 63 63 65 73 73 20 70 65 72 6d 69 73 73 69   access permissi
44c0: 6f 6e 73 2e 20 52 65 74 75 72 6e 20 74 72 75 65  ons. Return true
44d0: 20 69 66 20 74 68 65 20 72 65 71 75 65 73 74 65   if the requeste
44e0: 64 20 70 65 72 6d 69 73 73 69 6f 6e 0a 2a 2a 20  d permission.** 
44f0: 69 73 20 61 76 61 69 6c 61 62 6c 65 2c 20 6f 72  is available, or
4500: 20 66 61 6c 73 65 20 6f 74 68 65 72 77 69 73 65   false otherwise
4510: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4520: 74 76 66 73 41 63 63 65 73 73 28 0a 20 20 73 71  tvfsAccess(.  sq
4530: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
4540: 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a   .  const char *
4550: 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74 20 66 6c  zPath, .  int fl
4560: 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70 52 65  ags, .  int *pRe
4570: 73 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74 76 66  sOut.){.  Testvf
4580: 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20  s *p = (Testvfs 
4590: 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  *)pVfs->pAppData
45a0: 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ;.  if( p->pScri
45b0: 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  pt && p->mask&TE
45c0: 53 54 56 46 53 5f 41 43 43 45 53 53 5f 4d 41 53  STVFS_ACCESS_MAS
45d0: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 3b  K ){.    int rc;
45e0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 72 67 20  .    char *zArg 
45f0: 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 66 6c 61  = 0;.    if( fla
4600: 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53  gs==SQLITE_ACCES
4610: 53 5f 45 58 49 53 54 53 20 29 20 7a 41 72 67 20  S_EXISTS ) zArg 
4620: 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53  = "SQLITE_ACCESS
4630: 5f 45 58 49 53 54 53 22 3b 0a 20 20 20 20 69 66  _EXISTS";.    if
4640: 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f  ( flags==SQLITE_
4650: 41 43 43 45 53 53 5f 52 45 41 44 57 52 49 54 45  ACCESS_READWRITE
4660: 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c 49 54   ) zArg = "SQLIT
4670: 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49  E_ACCESS_READWRI
4680: 54 45 22 3b 0a 20 20 20 20 69 66 28 20 66 6c 61  TE";.    if( fla
4690: 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43 45 53  gs==SQLITE_ACCES
46a0: 53 5f 52 45 41 44 20 29 20 7a 41 72 67 20 3d 20  S_READ ) zArg = 
46b0: 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 52  "SQLITE_ACCESS_R
46c0: 45 41 44 22 3b 0a 20 20 20 20 74 76 66 73 45 78  EAD";.    tvfsEx
46d0: 65 63 54 63 6c 28 70 2c 20 22 78 41 63 63 65 73  ecTcl(p, "xAcces
46e0: 73 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  s", .        Tcl
46f0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 50  _NewStringObj(zP
4700: 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f 4e 65  ath, -1), Tcl_Ne
4710: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 41 72 67 2c  wStringObj(zArg,
4720: 20 2d 31 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20   -1), 0.    );. 
4730: 20 20 20 69 66 28 20 74 76 66 73 52 65 73 75 6c     if( tvfsResul
4740: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20 29 7b  tCode(p, &rc) ){
4750: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
4760: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72  QLITE_OK ) retur
4770: 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  n rc;.    }else{
4780: 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 74 65 72  .      Tcl_Inter
4790: 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d 3e 69  p *interp = p->i
47a0: 6e 74 65 72 70 3b 0a 20 20 20 20 20 20 69 66 28  nterp;.      if(
47b0: 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f 47 65 74   TCL_OK==Tcl_Get
47c0: 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 30  BooleanFromObj(0
47d0: 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  , Tcl_GetObjResu
47e0: 6c 74 28 69 6e 74 65 72 70 29 2c 20 70 52 65 73  lt(interp), pRes
47f0: 4f 75 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20  Out) ){.        
4800: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4810: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
4820: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c    }.  return sql
4830: 69 74 65 33 4f 73 41 63 63 65 73 73 28 50 41 52  ite3OsAccess(PAR
4840: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50  ENTVFS(pVfs), zP
4850: 61 74 68 2c 20 66 6c 61 67 73 2c 20 70 52 65 73  ath, flags, pRes
4860: 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  Out);.}../*.** P
4870: 6f 70 75 6c 61 74 65 20 62 75 66 66 65 72 20 7a  opulate buffer z
4880: 4f 75 74 20 77 69 74 68 20 74 68 65 20 66 75 6c  Out with the ful
4890: 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61 74 68  l canonical path
48a0: 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f 6e 64 69  name correspondi
48b0: 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 70 61 74  ng.** to the pat
48c0: 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74 68 2e 20  hname in zPath. 
48d0: 7a 4f 75 74 20 69 73 20 67 75 61 72 61 6e 74 65  zOut is guarante
48e0: 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61  ed to point to a
48f0: 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66 20 61 74   buffer.** of at
4900: 20 6c 65 61 73 74 20 28 44 45 56 53 59 4d 5f 4d   least (DEVSYM_M
4910: 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31 29 20 62  AX_PATHNAME+1) b
4920: 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ytes..*/.static 
4930: 69 6e 74 20 74 76 66 73 46 75 6c 6c 50 61 74 68  int tvfsFullPath
4940: 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  name(.  sqlite3_
4950: 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20 63 6f  vfs *pVfs, .  co
4960: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c  nst char *zPath,
4970: 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20 0a 20   .  int nOut, . 
4980: 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29 7b 0a 20   char *zOut.){. 
4990: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
49a0: 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 50 41  sFullPathname(PA
49b0: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a  RENTVFS(pVfs), z
49c0: 50 61 74 68 2c 20 6e 4f 75 74 2c 20 7a 4f 75 74  Path, nOut, zOut
49d0: 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20 53 51  );.}..#ifndef SQ
49e0: 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45  LITE_OMIT_LOAD_E
49f0: 58 54 45 4e 53 49 4f 4e 0a 2f 2a 0a 2a 2a 20 4f  XTENSION./*.** O
4a00: 70 65 6e 20 74 68 65 20 64 79 6e 61 6d 69 63 20  pen the dynamic 
4a10: 6c 69 62 72 61 72 79 20 6c 6f 63 61 74 65 64 20  library located 
4a20: 61 74 20 7a 50 61 74 68 20 61 6e 64 20 72 65 74  at zPath and ret
4a30: 75 72 6e 20 61 20 68 61 6e 64 6c 65 2e 0a 2a 2f  urn a handle..*/
4a40: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76  .static void *tv
4a50: 66 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33  fsDlOpen(sqlite3
4a60: 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f 6e 73  _vfs *pVfs, cons
4a70: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 29 7b 0a  t char *zPath){.
4a80: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
4a90: 4f 73 44 6c 4f 70 65 6e 28 50 41 52 45 4e 54 56  OsDlOpen(PARENTV
4aa0: 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74 68 29  FS(pVfs), zPath)
4ab0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c  ;.}../*.** Popul
4ac0: 61 74 65 20 74 68 65 20 62 75 66 66 65 72 20 7a  ate the buffer z
4ad0: 45 72 72 4d 73 67 20 28 73 69 7a 65 20 6e 42 79  ErrMsg (size nBy
4ae0: 74 65 20 62 79 74 65 73 29 20 77 69 74 68 20 61  te bytes) with a
4af0: 20 68 75 6d 61 6e 20 72 65 61 64 61 62 6c 65 0a   human readable.
4b00: 2a 2a 20 75 74 66 2d 38 20 73 74 72 69 6e 67 20  ** utf-8 string 
4b10: 64 65 73 63 72 69 62 69 6e 67 20 74 68 65 20 6d  describing the m
4b20: 6f 73 74 20 72 65 63 65 6e 74 20 65 72 72 6f 72  ost recent error
4b30: 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 61 73 73   encountered ass
4b40: 6f 63 69 61 74 65 64 20 0a 2a 2a 20 77 69 74 68  ociated .** with
4b50: 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61 72 69   dynamic librari
4b60: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  es..*/.static vo
4b70: 69 64 20 74 76 66 73 44 6c 45 72 72 6f 72 28 73  id tvfsDlError(s
4b80: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4b90: 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61  , int nByte, cha
4ba0: 72 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20 20 73  r *zErrMsg){.  s
4bb0: 71 6c 69 74 65 33 4f 73 44 6c 45 72 72 6f 72 28  qlite3OsDlError(
4bc0: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
4bd0: 20 6e 42 79 74 65 2c 20 7a 45 72 72 4d 73 67 29   nByte, zErrMsg)
4be0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
4bf0: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  n a pointer to t
4c00: 68 65 20 73 79 6d 62 6f 6c 20 7a 53 79 6d 62 6f  he symbol zSymbo
4c10: 6c 20 69 6e 20 74 68 65 20 64 79 6e 61 6d 69 63  l in the dynamic
4c20: 20 6c 69 62 72 61 72 79 20 70 48 61 6e 64 6c 65   library pHandle
4c30: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4c40: 20 28 2a 74 76 66 73 44 6c 53 79 6d 28 73 71 6c   (*tvfsDlSym(sql
4c50: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4c60: 76 6f 69 64 20 2a 70 2c 20 63 6f 6e 73 74 20 63  void *p, const c
4c70: 68 61 72 20 2a 7a 53 79 6d 29 29 28 76 6f 69 64  har *zSym))(void
4c80: 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  ){.  return sqli
4c90: 74 65 33 4f 73 44 6c 53 79 6d 28 50 41 52 45 4e  te3OsDlSym(PAREN
4ca0: 54 56 46 53 28 70 56 66 73 29 2c 20 70 2c 20 7a  TVFS(pVfs), p, z
4cb0: 53 79 6d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  Sym);.}../*.** C
4cc0: 6c 6f 73 65 20 74 68 65 20 64 79 6e 61 6d 69 63  lose the dynamic
4cd0: 20 6c 69 62 72 61 72 79 20 68 61 6e 64 6c 65 20   library handle 
4ce0: 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74  pHandle..*/.stat
4cf0: 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c 43 6c  ic void tvfsDlCl
4d00: 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ose(sqlite3_vfs 
4d10: 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70 48 61  *pVfs, void *pHa
4d20: 6e 64 6c 65 29 7b 0a 20 20 73 71 6c 69 74 65 33  ndle){.  sqlite3
4d30: 4f 73 44 6c 43 6c 6f 73 65 28 50 41 52 45 4e 54  OsDlClose(PARENT
4d40: 56 46 53 28 70 56 66 73 29 2c 20 70 48 61 6e 64  VFS(pVfs), pHand
4d50: 6c 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  le);.}.#endif /*
4d60: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41   SQLITE_OMIT_LOA
4d70: 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 0a  D_EXTENSION */..
4d80: 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 74  /*.** Populate t
4d90: 68 65 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65  he buffer pointe
4da0: 64 20 74 6f 20 62 79 20 7a 42 75 66 4f 75 74 20  d to by zBufOut 
4db0: 77 69 74 68 20 6e 42 79 74 65 20 62 79 74 65 73  with nByte bytes
4dc0: 20 6f 66 20 0a 2a 2a 20 72 61 6e 64 6f 6d 20 64   of .** random d
4dd0: 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ata..*/.static i
4de0: 6e 74 20 74 76 66 73 52 61 6e 64 6f 6d 6e 65 73  nt tvfsRandomnes
4df0: 73 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  s(sqlite3_vfs *p
4e00: 56 66 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20  Vfs, int nByte, 
4e10: 63 68 61 72 20 2a 7a 42 75 66 4f 75 74 29 7b 0a  char *zBufOut){.
4e20: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
4e30: 4f 73 52 61 6e 64 6f 6d 6e 65 73 73 28 50 41 52  OsRandomness(PAR
4e40: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 6e 42  ENTVFS(pVfs), nB
4e50: 79 74 65 2c 20 7a 42 75 66 4f 75 74 29 3b 0a 7d  yte, zBufOut);.}
4e60: 0a 0a 2f 2a 0a 2a 2a 20 53 6c 65 65 70 20 66 6f  ../*.** Sleep fo
4e70: 72 20 6e 4d 69 63 72 6f 20 6d 69 63 72 6f 73 65  r nMicro microse
4e80: 63 6f 6e 64 73 2e 20 52 65 74 75 72 6e 20 74 68  conds. Return th
4e90: 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69 63 72  e number of micr
4ea0: 6f 73 65 63 6f 6e 64 73 20 0a 2a 2a 20 61 63 74  oseconds .** act
4eb0: 75 61 6c 6c 79 20 73 6c 65 70 74 2e 0a 2a 2f 0a  ually slept..*/.
4ec0: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
4ed0: 6c 65 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73  leep(sqlite3_vfs
4ee0: 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 4d 69 63   *pVfs, int nMic
4ef0: 72 6f 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  ro){.  return sq
4f00: 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 50 41 52  lite3OsSleep(PAR
4f10: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 6e 4d  ENTVFS(pVfs), nM
4f20: 69 63 72 6f 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  icro);.}../*.** 
4f30: 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 72 65  Return the curre
4f40: 6e 74 20 74 69 6d 65 20 61 73 20 61 20 4a 75 6c  nt time as a Jul
4f50: 69 61 6e 20 44 61 79 20 6e 75 6d 62 65 72 20 69  ian Day number i
4f60: 6e 20 2a 70 54 69 6d 65 4f 75 74 2e 0a 2a 2f 0a  n *pTimeOut..*/.
4f70: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43  static int tvfsC
4f80: 75 72 72 65 6e 74 54 69 6d 65 28 73 71 6c 69 74  urrentTime(sqlit
4f90: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 64 6f  e3_vfs *pVfs, do
4fa0: 75 62 6c 65 20 2a 70 54 69 6d 65 4f 75 74 29 7b  uble *pTimeOut){
4fb0: 0a 20 20 72 65 74 75 72 6e 20 50 41 52 45 4e 54  .  return PARENT
4fc0: 56 46 53 28 70 56 66 73 29 2d 3e 78 43 75 72 72  VFS(pVfs)->xCurr
4fd0: 65 6e 74 54 69 6d 65 28 50 41 52 45 4e 54 56 46  entTime(PARENTVF
4fe0: 53 28 70 56 66 73 29 2c 20 70 54 69 6d 65 4f 75  S(pVfs), pTimeOu
4ff0: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
5000: 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73 71  t tvfsShmOpen(sq
5010: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
5020: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  e){.  Testvfs *p
5030: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
5040: 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20  ITE_OK;         
5050: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
5060: 64 65 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 42  de */.  TestvfsB
5070: 75 66 66 65 72 20 2a 70 42 75 66 66 65 72 3b 20  uffer *pBuffer; 
5080: 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
5090: 72 20 74 6f 20 6f 70 65 6e 20 63 6f 6e 6e 65 63  r to open connec
50a0: 74 69 6f 6e 20 74 6f 20 2a 2f 0a 20 20 54 65 73  tion to */.  Tes
50b0: 74 76 66 73 46 64 20 2a 70 46 64 3b 20 20 20 20  tvfsFd *pFd;    
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
50d0: 54 68 65 20 74 65 73 74 76 66 73 20 66 69 6c 65  The testvfs file
50e0: 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 0a 20   structure */.. 
50f0: 20 70 46 64 20 3d 20 74 76 66 73 47 65 74 46 64   pFd = tvfsGetFd
5100: 28 70 46 69 6c 65 29 3b 0a 20 20 70 20 3d 20 28  (pFile);.  p = (
5110: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
5120: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
5130: 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e 70 53   assert( pFd->pS
5140: 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70 53 68  hmId && pFd->pSh
5150: 6d 3d 3d 30 20 26 26 20 70 46 64 2d 3e 70 4e 65  m==0 && pFd->pNe
5160: 78 74 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 45  xt==0 );..  /* E
5170: 76 61 6c 75 61 74 65 20 74 68 65 20 54 63 6c 20  valuate the Tcl 
5180: 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a 20 20  script: .  **.  
5190: 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53 68 6d  **   SCRIPT xShm
51a0: 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45 0a 20 20  Open FILENAME.  
51b0: 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65  */.  Tcl_ResetRe
51c0: 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b  sult(p->interp);
51d0: 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70  .  if( p->pScrip
51e0: 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  t && p->mask&TES
51f0: 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53  TVFS_SHMOPEN_MAS
5200: 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65  K ){.    tvfsExe
5210: 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4f 70 65  cTcl(p, "xShmOpe
5220: 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  n", Tcl_NewStrin
5230: 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e  gObj(pFd->zFilen
5240: 61 6d 65 2c 20 2d 31 29 2c 20 30 2c 20 30 29 3b  ame, -1), 0, 0);
5250: 0a 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73  .    if( tvfsRes
5260: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20  ultCode(p, &rc) 
5270: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  ){.      if( rc!
5280: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
5290: 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  urn rc;.    }.  
52a0: 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d  }..  assert( rc=
52b0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
52c0: 69 66 28 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54  if( p->mask&TEST
52d0: 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b  VFS_SHMOPEN_MASK
52e0: 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f   && tvfsInjectIo
52f0: 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72 65  err(p) ){.    re
5300: 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52  turn SQLITE_IOER
5310: 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 61  R;.  }..  /* Sea
5320: 72 63 68 20 66 6f 72 20 61 20 54 65 73 74 76 66  rch for a Testvf
5330: 73 42 75 66 66 65 72 2e 20 43 72 65 61 74 65 20  sBuffer. Create 
5340: 61 20 6e 65 77 20 6f 6e 65 20 69 66 20 72 65 71  a new one if req
5350: 75 69 72 65 64 2e 20 2a 2f 0a 20 20 66 6f 72 28  uired. */.  for(
5360: 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75 66 66  pBuffer=p->pBuff
5370: 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70 42 75  er; pBuffer; pBu
5380: 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e 70 4e  ffer=pBuffer->pN
5390: 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 30 3d  ext){.    if( 0=
53a0: 3d 73 74 72 63 6d 70 28 70 46 64 2d 3e 7a 46 69  =strcmp(pFd->zFi
53b0: 6c 65 6e 61 6d 65 2c 20 70 42 75 66 66 65 72 2d  lename, pBuffer-
53c0: 3e 7a 46 69 6c 65 29 20 29 20 62 72 65 61 6b 3b  >zFile) ) break;
53d0: 0a 20 20 7d 0a 20 20 69 66 28 20 21 70 42 75 66  .  }.  if( !pBuf
53e0: 66 65 72 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  fer ){.    int n
53f0: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 54 65  Byte = sizeof(Te
5400: 73 74 76 66 73 42 75 66 66 65 72 29 20 2b 20 73  stvfsBuffer) + s
5410: 74 72 6c 65 6e 28 70 46 64 2d 3e 7a 46 69 6c 65  trlen(pFd->zFile
5420: 6e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 20 20 70  name) + 1;.    p
5430: 42 75 66 66 65 72 20 3d 20 28 54 65 73 74 76 66  Buffer = (Testvf
5440: 73 42 75 66 66 65 72 20 2a 29 63 6b 61 6c 6c 6f  sBuffer *)ckallo
5450: 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 6d 65  c(nByte);.    me
5460: 6d 73 65 74 28 70 42 75 66 66 65 72 2c 20 30 2c  mset(pBuffer, 0,
5470: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70 42 75   nByte);.    pBu
5480: 66 66 65 72 2d 3e 7a 46 69 6c 65 20 3d 20 28 63  ffer->zFile = (c
5490: 68 61 72 20 2a 29 26 70 42 75 66 66 65 72 5b 31  har *)&pBuffer[1
54a0: 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28 70 42  ];.    strcpy(pB
54b0: 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20 70 46  uffer->zFile, pF
54c0: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  d->zFilename);. 
54d0: 20 20 20 70 42 75 66 66 65 72 2d 3e 70 4e 65 78     pBuffer->pNex
54e0: 74 20 3d 20 70 2d 3e 70 42 75 66 66 65 72 3b 0a  t = p->pBuffer;.
54f0: 20 20 20 20 70 2d 3e 70 42 75 66 66 65 72 20 3d      p->pBuffer =
5500: 20 70 42 75 66 66 65 72 3b 0a 20 20 7d 0a 0a 20   pBuffer;.  }.. 
5510: 20 2f 2a 20 43 6f 6e 6e 65 63 74 20 74 68 65 20   /* Connect the 
5520: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 74 6f  TestvfsBuffer to
5530: 20 74 68 65 20 6e 65 77 20 54 65 73 74 76 66 73   the new Testvfs
5540: 53 68 6d 20 68 61 6e 64 6c 65 20 61 6e 64 20 72  Shm handle and r
5550: 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 70 46 64 2d  eturn. */.  pFd-
5560: 3e 70 4e 65 78 74 20 3d 20 70 42 75 66 66 65 72  >pNext = pBuffer
5570: 2d 3e 70 46 69 6c 65 3b 0a 20 20 70 42 75 66 66  ->pFile;.  pBuff
5580: 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46 64 3b  er->pFile = pFd;
5590: 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 70  .  pFd->pShm = p
55a0: 42 75 66 66 65 72 3b 0a 20 20 72 65 74 75 72 6e  Buffer;.  return
55b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
55c0: 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 41  tatic void tvfsA
55d0: 6c 6c 6f 63 50 61 67 65 28 54 65 73 74 76 66 73  llocPage(Testvfs
55e0: 42 75 66 66 65 72 20 2a 70 2c 20 69 6e 74 20 69  Buffer *p, int i
55f0: 50 61 67 65 2c 20 69 6e 74 20 70 67 73 7a 29 7b  Page, int pgsz){
5600: 0a 20 20 61 73 73 65 72 74 28 20 69 50 61 67 65  .  assert( iPage
5610: 3c 54 45 53 54 56 46 53 5f 4d 41 58 5f 50 41 47  <TESTVFS_MAX_PAG
5620: 45 53 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 61  ES );.  if( p->a
5630: 50 61 67 65 5b 69 50 61 67 65 5d 3d 3d 30 20 29  Page[iPage]==0 )
5640: 7b 0a 20 20 20 20 70 2d 3e 61 50 61 67 65 5b 69  {.    p->aPage[i
5650: 50 61 67 65 5d 20 3d 20 28 75 38 20 2a 29 63 6b  Page] = (u8 *)ck
5660: 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20 20 20  alloc(pgsz);.   
5670: 20 6d 65 6d 73 65 74 28 70 2d 3e 61 50 61 67 65   memset(p->aPage
5680: 5b 69 50 61 67 65 5d 2c 20 30 2c 20 70 67 73 7a  [iPage], 0, pgsz
5690: 29 3b 0a 20 20 20 20 70 2d 3e 70 67 73 7a 20 3d  );.    p->pgsz =
56a0: 20 70 67 73 7a 3b 0a 20 20 7d 0a 7d 0a 0a 73 74   pgsz;.  }.}..st
56b0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
56c0: 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 66  Map(.  sqlite3_f
56d0: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20 20 20  ile *pFile,     
56e0: 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64 6c 65         /* Handle
56f0: 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62 61 73   open on databas
5700: 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  e file */.  int 
5710: 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  iPage,          
5720: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
5730: 61 67 65 20 74 6f 20 72 65 74 72 69 65 76 65 20  age to retrieve 
5740: 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 2c 20 20  */.  int pgsz,  
5750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5760: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
5770: 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74 20 69  pages */.  int i
5780: 73 57 72 69 74 65 2c 20 20 20 20 20 20 20 20 20  sWrite,         
5790: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
57a0: 75 65 20 74 6f 20 65 78 74 65 6e 64 20 66 69 6c  ue to extend fil
57b0: 65 20 69 66 20 6e 65 63 65 73 73 61 72 79 20 2a  e if necessary *
57c0: 2f 0a 20 20 76 6f 69 64 20 76 6f 6c 61 74 69 6c  /.  void volatil
57d0: 65 20 2a 2a 70 70 20 20 20 20 20 20 20 20 20 20  e **pp          
57e0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4d 61 70 70      /* OUT: Mapp
57f0: 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 29 7b 0a  ed memory */.){.
5800: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
5810: 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46  E_OK;.  TestvfsF
5820: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
5830: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
5840: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
5850: 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d  fs *)(pFd->pVfs-
5860: 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69  >pAppData);..  i
5870: 66 28 20 30 3d 3d 70 46 64 2d 3e 70 53 68 6d 20  f( 0==pFd->pShm 
5880: 29 7b 0a 20 20 20 20 72 63 20 3d 20 74 76 66 73  ){.    rc = tvfs
5890: 53 68 6d 4f 70 65 6e 28 70 46 69 6c 65 29 3b 0a  ShmOpen(pFile);.
58a0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
58b0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
58c0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
58d0: 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53    }..  if( p->pS
58e0: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
58f0: 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f  &TESTVFS_SHMMAP_
5900: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f  MASK ){.    Tcl_
5910: 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54 63 6c 5f  Obj *pArg = Tcl_
5920: 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 54 63  NewObj();.    Tc
5930: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70  l_IncrRefCount(p
5940: 41 72 67 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69  Arg);.    Tcl_Li
5950: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
5960: 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41  nt(p->interp, pA
5970: 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62  rg, Tcl_NewIntOb
5980: 6a 28 69 50 61 67 65 29 29 3b 0a 20 20 20 20 54  j(iPage));.    T
5990: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
59a0: 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72  Element(p->inter
59b0: 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77  p, pArg, Tcl_New
59c0: 49 6e 74 4f 62 6a 28 70 67 73 7a 29 29 3b 0a 20  IntObj(pgsz));. 
59d0: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
59e0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69  pendElement(p->i
59f0: 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c  nterp, pArg, Tcl
5a00: 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 73 57 72 69  _NewIntObj(isWri
5a10: 74 65 29 29 3b 0a 20 20 20 20 74 76 66 73 45 78  te));.    tvfsEx
5a20: 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4d 61  ecTcl(p, "xShmMa
5a30: 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  p", .        Tcl
5a40: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
5a50: 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20  d->pShm->zFile, 
5a60: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
5a70: 2c 20 70 41 72 67 0a 20 20 20 20 29 3b 0a 20 20  , pArg.    );.  
5a80: 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65    tvfsResultCode
5a90: 28 70 2c 20 26 72 63 29 3b 0a 20 20 20 20 54 63  (p, &rc);.    Tc
5aa0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
5ab0: 41 72 67 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  Arg);.  }.  if( 
5ac0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
5ad0: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
5ae0: 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 26 26 20  _SHMMAP_MASK && 
5af0: 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28  tvfsInjectIoerr(
5b00: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  p) ){.    rc = S
5b10: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d  QLITE_IOERR;.  }
5b20: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
5b30: 54 45 5f 4f 4b 20 26 26 20 69 73 57 72 69 74 65  TE_OK && isWrite
5b40: 20 26 26 20 21 70 46 64 2d 3e 70 53 68 6d 2d 3e   && !pFd->pShm->
5b50: 61 50 61 67 65 5b 69 50 61 67 65 5d 20 29 7b 0a  aPage[iPage] ){.
5b60: 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50 61 67      tvfsAllocPag
5b70: 65 28 70 46 64 2d 3e 70 53 68 6d 2c 20 69 50 61  e(pFd->pShm, iPa
5b80: 67 65 2c 20 70 67 73 7a 29 3b 0a 20 20 7d 0a 20  ge, pgsz);.  }. 
5b90: 20 2a 70 70 20 3d 20 28 76 6f 69 64 20 76 6f 6c   *pp = (void vol
5ba0: 61 74 69 6c 65 20 2a 29 70 46 64 2d 3e 70 53 68  atile *)pFd->pSh
5bb0: 6d 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 3b  m->aPage[iPage];
5bc0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5bd0: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  ...static int tv
5be0: 66 73 53 68 6d 4c 6f 63 6b 28 0a 20 20 73 71 6c  fsShmLock(.  sql
5bf0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
5c00: 2c 0a 20 20 69 6e 74 20 6f 66 73 74 2c 0a 20 20  ,.  int ofst,.  
5c10: 69 6e 74 20 6e 2c 0a 20 20 69 6e 74 20 66 6c 61  int n,.  int fla
5c20: 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  gs.){.  int rc =
5c30: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
5c40: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
5c50: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
5c60: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
5c70: 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64 2d  (Testvfs *)(pFd-
5c80: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29  >pVfs->pAppData)
5c90: 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b 0a 20  ;.  int nLock;. 
5ca0: 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 38 30 5d 3b   char zLock[80];
5cb0: 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ..  if( p->pScri
5cc0: 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  pt && p->mask&TE
5cd0: 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d 41  STVFS_SHMLOCK_MA
5ce0: 53 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  SK ){.    sqlite
5cf0: 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f  3_snprintf(sizeo
5d00: 66 28 7a 4c 6f 63 6b 29 2c 20 7a 4c 6f 63 6b 2c  f(zLock), zLock,
5d10: 20 22 25 64 20 25 64 22 2c 20 6f 66 73 74 2c 20   "%d %d", ofst, 
5d20: 6e 29 3b 0a 20 20 20 20 6e 4c 6f 63 6b 20 3d 20  n);.    nLock = 
5d30: 73 74 72 6c 65 6e 28 7a 4c 6f 63 6b 29 3b 0a 20  strlen(zLock);. 
5d40: 20 20 20 69 66 28 20 66 6c 61 67 73 20 26 20 53     if( flags & S
5d50: 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 29  QLITE_SHM_LOCK )
5d60: 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79 28 26  {.      strcpy(&
5d70: 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20  zLock[nLock], " 
5d80: 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d 65 6c 73  lock");.    }els
5d90: 65 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79 28  e{.      strcpy(
5da0: 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22  &zLock[nLock], "
5db0: 20 75 6e 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d   unlock");.    }
5dc0: 0a 20 20 20 20 6e 4c 6f 63 6b 20 2b 3d 20 73 74  .    nLock += st
5dd0: 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63  rlen(&zLock[nLoc
5de0: 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20 66 6c 61  k]);.    if( fla
5df0: 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f  gs & SQLITE_SHM_
5e00: 53 48 41 52 45 44 20 29 7b 0a 20 20 20 20 20 20  SHARED ){.      
5e10: 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c  strcpy(&zLock[nL
5e20: 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65 64 22 29  ock], " shared")
5e30: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
5e40: 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b     strcpy(&zLock
5e50: 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78 63 6c 75  [nLock], " exclu
5e60: 73 69 76 65 22 29 3b 0a 20 20 20 20 7d 0a 20 20  sive");.    }.  
5e70: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
5e80: 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 0a 20 20   "xShmLock", .  
5e90: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
5ea0: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d  ingObj(pFd->pShm
5eb0: 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46  ->zFile, -1), pF
5ec0: 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20 20 20 20  d->pShmId,.     
5ed0: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
5ee0: 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31 29 0a 20  Obj(zLock, -1). 
5ef0: 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73 52 65     );.    tvfsRe
5f00: 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29  sultCode(p, &rc)
5f10: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
5f20: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d  =SQLITE_OK && p-
5f30: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48  >mask&TESTVFS_SH
5f40: 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 26 26 20 74 76  MLOCK_MASK && tv
5f50: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29  fsInjectIoerr(p)
5f60: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
5f70: 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a  ITE_IOERR;.  }..
5f80: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
5f90: 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  _OK ){.    int i
5fa0: 73 4c 6f 63 6b 20 3d 20 28 66 6c 61 67 73 20 26  sLock = (flags &
5fb0: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b   SQLITE_SHM_LOCK
5fc0: 29 3b 0a 20 20 20 20 69 6e 74 20 69 73 45 78 63  );.    int isExc
5fd0: 6c 20 3d 20 28 66 6c 61 67 73 20 26 20 53 51 4c  l = (flags & SQL
5fe0: 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56  ITE_SHM_EXCLUSIV
5ff0: 45 29 3b 0a 20 20 20 20 75 33 32 20 6d 61 73 6b  E);.    u32 mask
6000: 20 3d 20 28 28 28 31 3c 3c 6e 29 2d 31 29 20 3c   = (((1<<n)-1) <
6010: 3c 20 6f 66 73 74 29 3b 0a 20 20 20 20 69 66 28  < ofst);.    if(
6020: 20 69 73 4c 6f 63 6b 20 29 7b 0a 20 20 20 20 20   isLock ){.     
6030: 20 54 65 73 74 76 66 73 46 64 20 2a 70 32 3b 0a   TestvfsFd *p2;.
6040: 20 20 20 20 20 20 66 6f 72 28 70 32 3d 70 46 64        for(p2=pFd
6050: 2d 3e 70 53 68 6d 2d 3e 70 46 69 6c 65 3b 20 70  ->pShm->pFile; p
6060: 32 3b 20 70 32 3d 70 32 2d 3e 70 4e 65 78 74 29  2; p2=p2->pNext)
6070: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 32  {.        if( p2
6080: 3d 3d 70 46 64 20 29 20 63 6f 6e 74 69 6e 75 65  ==pFd ) continue
6090: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 70  ;.        if( (p
60a0: 32 2d 3e 65 78 63 6c 6c 6f 63 6b 26 6d 61 73 6b  2->excllock&mask
60b0: 29 20 7c 7c 20 28 69 73 45 78 63 6c 20 26 26 20  ) || (isExcl && 
60c0: 70 32 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 26 6d  p2->sharedlock&m
60d0: 61 73 6b 29 20 29 7b 0a 20 20 20 20 20 20 20 20  ask) ){.        
60e0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55    rc = SQLITE_BU
60f0: 53 59 3b 0a 20 20 20 20 20 20 20 20 20 20 62 72  SY;.          br
6100: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  eak;.        }. 
6110: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
6120: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
6130: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 73  {.        if( is
6140: 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65 78 63  Excl )  pFd->exc
6150: 6c 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b 0a 20  llock |= mask;. 
6160: 20 20 20 20 20 20 20 69 66 28 20 21 69 73 45 78         if( !isEx
6170: 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72 65 64  cl ) pFd->shared
6180: 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b 0a 20 20  lock |= mask;.  
6190: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b      }.    }else{
61a0: 0a 20 20 20 20 20 20 69 66 28 20 69 73 45 78 63  .      if( isExc
61b0: 6c 20 29 20 20 70 46 64 2d 3e 65 78 63 6c 6c 6f  l )  pFd->excllo
61c0: 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b 0a 20  ck &= (~mask);. 
61d0: 20 20 20 20 20 69 66 28 20 21 69 73 45 78 63 6c       if( !isExcl
61e0: 20 29 20 70 46 64 2d 3e 73 68 61 72 65 64 6c 6f   ) pFd->sharedlo
61f0: 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b 0a 20  ck &= (~mask);. 
6200: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
6210: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
6220: 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72   void tvfsShmBar
6230: 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c  rier(sqlite3_fil
6240: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73  e *pFile){.  Tes
6250: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
6260: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
6270: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
6280: 54 65 73 74 76 66 73 20 2a 29 28 70 46 64 2d 3e  Testvfs *)(pFd->
6290: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29 3b  pVfs->pAppData);
62a0: 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ..  if( p->pScri
62b0: 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  pt && p->mask&TE
62c0: 53 54 56 46 53 5f 53 48 4d 42 41 52 52 49 45 52  STVFS_SHMBARRIER
62d0: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66  _MASK ){.    tvf
62e0: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68  sExecTcl(p, "xSh
62f0: 6d 42 61 72 72 69 65 72 22 2c 20 0a 20 20 20 20  mBarrier", .    
6300: 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e      Tcl_NewStrin
6310: 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d 2d 3e  gObj(pFd->pShm->
6320: 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46 64 2d  zFile, -1), pFd-
6330: 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20 20 20 29  >pShmId, 0.    )
6340: 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
6350: 69 6e 74 20 74 76 66 73 53 68 6d 55 6e 6d 61 70  int tvfsShmUnmap
6360: 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  (.  sqlite3_file
6370: 20 2a 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 64   *pFile,.  int d
6380: 65 6c 65 74 65 46 6c 61 67 0a 29 7b 0a 20 20 69  eleteFlag.){.  i
6390: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
63a0: 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  K;.  TestvfsFd *
63b0: 70 46 64 20 3d 20 74 76 66 73 47 65 74 46 64 28  pFd = tvfsGetFd(
63c0: 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66  pFile);.  Testvf
63d0: 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20  s *p = (Testvfs 
63e0: 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41  *)(pFd->pVfs->pA
63f0: 70 70 44 61 74 61 29 3b 0a 20 20 54 65 73 74 76  ppData);.  Testv
6400: 66 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65  fsBuffer *pBuffe
6410: 72 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b 0a 20  r = pFd->pShm;. 
6420: 20 54 65 73 74 76 66 73 46 64 20 2a 2a 70 70 46   TestvfsFd **ppF
6430: 64 3b 0a 0a 20 20 69 66 28 20 21 70 42 75 66 66  d;..  if( !pBuff
6440: 65 72 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  er ) return SQLI
6450: 54 45 5f 4f 4b 3b 0a 20 20 61 73 73 65 72 74 28  TE_OK;.  assert(
6460: 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26 26 20   pFd->pShmId && 
6470: 70 46 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a 20 20  pFd->pShm );..  
6480: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
6490: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
64a0: 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20  S_SHMCLOSE_MASK 
64b0: 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54  ){.    tvfsExecT
64c0: 63 6c 28 70 2c 20 22 78 53 68 6d 55 6e 6d 61 70  cl(p, "xShmUnmap
64d0: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
64e0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
64f0: 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d  ->pShm->zFile, -
6500: 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c  1), pFd->pShmId,
6510: 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76   0.    );.    tv
6520: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
6530: 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  &rc);.  }..  for
6540: 28 70 70 46 64 3d 26 70 42 75 66 66 65 72 2d 3e  (ppFd=&pBuffer->
6550: 70 46 69 6c 65 3b 20 2a 70 70 46 64 21 3d 70 46  pFile; *ppFd!=pF
6560: 64 3b 20 70 70 46 64 3d 26 28 28 2a 70 70 46 64  d; ppFd=&((*ppFd
6570: 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 61 73  )->pNext));.  as
6580: 73 65 72 74 28 20 28 2a 70 70 46 64 29 3d 3d 70  sert( (*ppFd)==p
6590: 46 64 20 29 3b 0a 20 20 2a 70 70 46 64 20 3d 20  Fd );.  *ppFd = 
65a0: 70 46 64 2d 3e 70 4e 65 78 74 3b 0a 20 20 70 46  pFd->pNext;.  pF
65b0: 64 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 0a 20  d->pNext = 0;.. 
65c0: 20 69 66 28 20 70 42 75 66 66 65 72 2d 3e 70 46   if( pBuffer->pF
65d0: 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e  ile==0 ){.    in
65e0: 74 20 69 3b 0a 20 20 20 20 54 65 73 74 76 66 73  t i;.    Testvfs
65f0: 42 75 66 66 65 72 20 2a 2a 70 70 3b 0a 20 20 20  Buffer **pp;.   
6600: 20 66 6f 72 28 70 70 3d 26 70 2d 3e 70 42 75 66   for(pp=&p->pBuf
6610: 66 65 72 3b 20 2a 70 70 21 3d 70 42 75 66 66 65  fer; *pp!=pBuffe
6620: 72 3b 20 70 70 3d 26 28 28 2a 70 70 29 2d 3e 70  r; pp=&((*pp)->p
6630: 4e 65 78 74 29 29 3b 0a 20 20 20 20 2a 70 70 20  Next));.    *pp 
6640: 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a  = (*pp)->pNext;.
6650: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 70 42 75      for(i=0; pBu
6660: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 3b 20  ffer->aPage[i]; 
6670: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6b 66 72  i++){.      ckfr
6680: 65 65 28 28 63 68 61 72 20 2a 29 70 42 75 66 66  ee((char *)pBuff
6690: 65 72 2d 3e 61 50 61 67 65 5b 69 5d 29 3b 0a 20  er->aPage[i]);. 
66a0: 20 20 20 7d 0a 20 20 20 20 63 6b 66 72 65 65 28     }.    ckfree(
66b0: 28 63 68 61 72 20 2a 29 70 42 75 66 66 65 72 29  (char *)pBuffer)
66c0: 3b 0a 20 20 7d 0a 20 20 70 46 64 2d 3e 70 53 68  ;.  }.  pFd->pSh
66d0: 6d 20 3d 20 30 3b 0a 0a 20 20 72 65 74 75 72 6e  m = 0;..  return
66e0: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
66f0: 6e 74 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63  nt testvfs_obj_c
6700: 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61  md(.  ClientData
6710: 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72   cd,.  Tcl_Inter
6720: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
6730: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
6740: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
6750: 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  {.  Testvfs *p =
6760: 20 28 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a   (Testvfs *)cd;.
6770: 0a 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20  .  enum DB_enum 
6780: 7b 20 0a 20 20 20 20 43 4d 44 5f 53 48 4d 2c 20  { .    CMD_SHM, 
6790: 43 4d 44 5f 44 45 4c 45 54 45 2c 20 43 4d 44 5f  CMD_DELETE, CMD_
67a0: 46 49 4c 54 45 52 2c 20 43 4d 44 5f 49 4f 45 52  FILTER, CMD_IOER
67b0: 52 2c 20 43 4d 44 5f 53 43 52 49 50 54 2c 20 0a  R, CMD_SCRIPT, .
67c0: 20 20 20 20 43 4d 44 5f 44 45 56 43 48 41 52 2c      CMD_DEVCHAR,
67d0: 20 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a 45 2c   CMD_SECTORSIZE,
67e0: 20 43 4d 44 5f 46 55 4c 4c 45 52 52 2c 20 43 4d   CMD_FULLERR, CM
67f0: 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 0a 20 20  D_CANTOPENERR.  
6800: 7d 3b 0a 20 20 73 74 72 75 63 74 20 54 65 73 74  };.  struct Test
6810: 76 66 73 53 75 62 63 6d 64 20 7b 0a 20 20 20 20  vfsSubcmd {.    
6820: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
6830: 20 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20 65 43   enum DB_enum eC
6840: 6d 64 3b 0a 20 20 7d 20 61 53 75 62 63 6d 64 5b  md;.  } aSubcmd[
6850: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 68 6d  ] = {.    { "shm
6860: 22 2c 20 20 20 20 20 20 20 20 20 43 4d 44 5f 53  ",         CMD_S
6870: 48 4d 20 20 20 20 20 20 20 20 20 7d 2c 0a 20 20  HM         },.  
6880: 20 20 7b 20 22 64 65 6c 65 74 65 22 2c 20 20 20    { "delete",   
6890: 20 20 20 43 4d 44 5f 44 45 4c 45 54 45 20 20 20     CMD_DELETE   
68a0: 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66 69 6c     },.    { "fil
68b0: 74 65 72 22 2c 20 20 20 20 20 20 43 4d 44 5f 46  ter",      CMD_F
68c0: 49 4c 54 45 52 20 20 20 20 20 20 7d 2c 0a 20 20  ILTER      },.  
68d0: 20 20 7b 20 22 69 6f 65 72 72 22 2c 20 20 20 20    { "ioerr",    
68e0: 20 20 20 43 4d 44 5f 49 4f 45 52 52 20 20 20 20     CMD_IOERR    
68f0: 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66 75 6c     },.    { "ful
6900: 6c 65 72 72 22 2c 20 20 20 20 20 43 4d 44 5f 46  lerr",     CMD_F
6910: 55 4c 4c 45 52 52 20 20 20 20 20 7d 2c 0a 20 20  ULLERR     },.  
6920: 20 20 7b 20 22 63 61 6e 74 6f 70 65 6e 65 72 72    { "cantopenerr
6930: 22 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45  ", CMD_CANTOPENE
6940: 52 52 20 7d 2c 0a 20 20 20 20 7b 20 22 73 63 72  RR },.    { "scr
6950: 69 70 74 22 2c 20 20 20 20 20 20 43 4d 44 5f 53  ipt",      CMD_S
6960: 43 52 49 50 54 20 20 20 20 20 20 7d 2c 0a 20 20  CRIPT      },.  
6970: 20 20 7b 20 22 64 65 76 63 68 61 72 22 2c 20 20    { "devchar",  
6980: 20 20 20 43 4d 44 5f 44 45 56 43 48 41 52 20 20     CMD_DEVCHAR  
6990: 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 73 65 63     },.    { "sec
69a0: 74 6f 72 73 69 7a 65 22 2c 20 20 43 4d 44 5f 53  torsize",  CMD_S
69b0: 45 43 54 4f 52 53 49 5a 45 20 20 7d 2c 0a 20 20  ECTORSIZE  },.  
69c0: 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 7d 3b 0a    { 0, 0 }.  };.
69d0: 20 20 69 6e 74 20 69 3b 0a 20 20 0a 20 20 69 66    int i;.  .  if
69e0: 28 20 6f 62 6a 63 3c 32 20 29 7b 0a 20 20 20 20  ( objc<2 ){.    
69f0: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
6a00: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
6a10: 2c 20 22 53 55 42 43 4f 4d 4d 41 4e 44 20 2e 2e  , "SUBCOMMAND ..
6a20: 2e 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  .");.    return 
6a30: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
6a40: 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 64 65   if( Tcl_GetInde
6a50: 78 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 0a  xFromObjStruct(.
6a60: 20 20 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20          interp, 
6a70: 6f 62 6a 76 5b 31 5d 2c 20 61 53 75 62 63 6d 64  objv[1], aSubcmd
6a80: 2c 20 73 69 7a 65 6f 66 28 61 53 75 62 63 6d 64  , sizeof(aSubcmd
6a90: 5b 30 5d 29 2c 20 22 73 75 62 63 6f 6d 6d 61 6e  [0]), "subcomman
6aa0: 64 22 2c 20 30 2c 20 26 69 29 20 0a 20 20 29 7b  d", 0, &i) .  ){
6ab0: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
6ac0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54 63 6c  ERROR;.  }.  Tcl
6ad0: 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74  _ResetResult(int
6ae0: 65 72 70 29 3b 0a 0a 20 20 73 77 69 74 63 68 28  erp);..  switch(
6af0: 20 61 53 75 62 63 6d 64 5b 69 5d 2e 65 43 6d 64   aSubcmd[i].eCmd
6b00: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 43 4d 44   ){.    case CMD
6b10: 5f 53 48 4d 3a 20 7b 0a 20 20 20 20 20 20 54 63  _SHM: {.      Tc
6b20: 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20 20 20  l_Obj *pObj;.   
6b30: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
6b40: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70  TestvfsBuffer *p
6b50: 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20 63 68  Buffer;.      ch
6b60: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
6b70: 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 26 26 20   if( objc!=3 && 
6b80: 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20 20 20  objc!=4 ){.     
6b90: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
6ba0: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
6bb0: 62 6a 76 2c 20 22 46 49 4c 45 20 3f 56 41 4c 55  bjv, "FILE ?VALU
6bc0: 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  E?");.        re
6bd0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
6be0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e        }.      zN
6bf0: 61 6d 65 20 3d 20 63 6b 61 6c 6c 6f 63 28 70 2d  ame = ckalloc(p-
6c00: 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61 74 68  >pParent->mxPath
6c10: 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70 2d 3e  name);.      p->
6c20: 70 50 61 72 65 6e 74 2d 3e 78 46 75 6c 6c 50 61  pParent->xFullPa
6c30: 74 68 6e 61 6d 65 28 0a 20 20 20 20 20 20 20 20  thname(.        
6c40: 20 20 70 2d 3e 70 50 61 72 65 6e 74 2c 20 54 63    p->pParent, Tc
6c50: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
6c60: 5b 32 5d 29 2c 20 0a 20 20 20 20 20 20 20 20 20  [2]), .         
6c70: 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50   p->pParent->mxP
6c80: 61 74 68 6e 61 6d 65 2c 20 7a 4e 61 6d 65 0a 20  athname, zName. 
6c90: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 66 6f       );.      fo
6ca0: 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75  r(pBuffer=p->pBu
6cb0: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70  ffer; pBuffer; p
6cc0: 42 75 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e  Buffer=pBuffer->
6cd0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20  pNext){.        
6ce0: 69 66 28 20 30 3d 3d 73 74 72 63 6d 70 28 70 42  if( 0==strcmp(pB
6cf0: 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20 7a 4e  uffer->zFile, zN
6d00: 61 6d 65 29 20 29 20 62 72 65 61 6b 3b 0a 20 20  ame) ) break;.  
6d10: 20 20 20 20 7d 0a 20 20 20 20 20 20 63 6b 66 72      }.      ckfr
6d20: 65 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20  ee(zName);.     
6d30: 20 69 66 28 20 21 70 42 75 66 66 65 72 20 29 7b   if( !pBuffer ){
6d40: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70  .        Tcl_App
6d50: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
6d60: 2c 20 22 6e 6f 20 73 75 63 68 20 66 69 6c 65 3a  , "no such file:
6d70: 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e   ", Tcl_GetStrin
6d80: 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a  g(objv[2]), 0);.
6d90: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
6da0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
6db0: 7d 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63  }.      if( objc
6dc0: 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==4 ){.        i
6dd0: 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20 75 38  nt n;.        u8
6de0: 20 2a 61 20 3d 20 54 63 6c 5f 47 65 74 42 79 74   *a = Tcl_GetByt
6df0: 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28 6f 62  eArrayFromObj(ob
6e00: 6a 76 5b 33 5d 2c 20 26 6e 29 3b 0a 20 20 20 20  jv[3], &n);.    
6e10: 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70      int pgsz = p
6e20: 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b 0a 20 20  Buffer->pgsz;.  
6e30: 20 20 20 20 20 20 69 66 28 20 70 67 73 7a 3d 3d        if( pgsz==
6e40: 30 20 29 20 70 67 73 7a 20 3d 20 36 35 35 33 36  0 ) pgsz = 65536
6e50: 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d  ;.        for(i=
6e60: 30 3b 20 69 2a 70 67 73 7a 3c 6e 3b 20 69 2b 2b  0; i*pgsz<n; i++
6e70: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  ){.          int
6e80: 20 6e 42 79 74 65 20 3d 20 70 67 73 7a 3b 0a 20   nByte = pgsz;. 
6e90: 20 20 20 20 20 20 20 20 20 74 76 66 73 41 6c 6c           tvfsAll
6ea0: 6f 63 50 61 67 65 28 70 42 75 66 66 65 72 2c 20  ocPage(pBuffer, 
6eb0: 69 2c 20 70 67 73 7a 29 3b 0a 20 20 20 20 20 20  i, pgsz);.      
6ec0: 20 20 20 20 69 66 28 20 6e 2d 69 2a 70 67 73 7a      if( n-i*pgsz
6ed0: 3c 70 67 73 7a 20 29 7b 0a 20 20 20 20 20 20 20  <pgsz ){.       
6ee0: 20 20 20 20 20 6e 42 79 74 65 20 3d 20 6e 3b 0a       nByte = n;.
6ef0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
6f00: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 42 75        memcpy(pBu
6f10: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20  ffer->aPage[i], 
6f20: 26 61 5b 69 2a 70 67 73 7a 5d 2c 20 6e 42 79 74  &a[i*pgsz], nByt
6f30: 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  e);.        }.  
6f40: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70 4f 62      }..      pOb
6f50: 6a 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29  j = Tcl_NewObj()
6f60: 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b  ;.      for(i=0;
6f70: 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b   pBuffer->aPage[
6f80: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  i]; i++){.      
6f90: 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70 42 75    int pgsz = pBu
6fa0: 66 66 65 72 2d 3e 70 67 73 7a 3b 0a 20 20 20 20  ffer->pgsz;.    
6fb0: 20 20 20 20 69 66 28 20 70 67 73 7a 3d 3d 30 20      if( pgsz==0 
6fc0: 29 20 70 67 73 7a 20 3d 20 36 35 35 33 36 3b 0a  ) pgsz = 65536;.
6fd0: 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65          Tcl_Appe
6fe0: 6e 64 4f 62 6a 54 6f 4f 62 6a 28 70 4f 62 6a 2c  ndObjToObj(pObj,
6ff0: 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72 72 61   Tcl_NewByteArra
7000: 79 4f 62 6a 28 70 42 75 66 66 65 72 2d 3e 61 50  yObj(pBuffer->aP
7010: 61 67 65 5b 69 5d 2c 20 70 67 73 7a 29 29 3b 0a  age[i], pgsz));.
7020: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63        }.      Tc
7030: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
7040: 6e 74 65 72 70 2c 20 70 4f 62 6a 29 3b 0a 20 20  nterp, pObj);.  
7050: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
7060: 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 46  ..    case CMD_F
7070: 49 4c 54 45 52 3a 20 7b 0a 20 20 20 20 20 20 73  ILTER: {.      s
7080: 74 61 74 69 63 20 73 74 72 75 63 74 20 56 66 73  tatic struct Vfs
7090: 4d 65 74 68 6f 64 20 7b 0a 20 20 20 20 20 20 20  Method {.       
70a0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
70b0: 20 20 20 20 20 20 69 6e 74 20 6d 61 73 6b 3b 0a        int mask;.
70c0: 20 20 20 20 20 20 7d 20 76 66 73 6d 65 74 68 6f        } vfsmetho
70d0: 64 20 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 20  d [] = {.       
70e0: 20 7b 20 22 78 53 68 6d 4f 70 65 6e 22 2c 20 20   { "xShmOpen",  
70f0: 20 20 54 45 53 54 56 46 53 5f 53 48 4d 4f 50 45    TESTVFS_SHMOPE
7100: 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20 20  N_MASK },.      
7110: 20 20 7b 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20    { "xShmLock", 
7120: 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f     TESTVFS_SHMLO
7130: 43 4b 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20 20  CK_MASK },.     
7140: 20 20 20 7b 20 22 78 53 68 6d 42 61 72 72 69 65     { "xShmBarrie
7150: 72 22 2c 20 54 45 53 54 56 46 53 5f 53 48 4d 42  r", TESTVFS_SHMB
7160: 41 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c 0a 20  ARRIER_MASK },. 
7170: 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 55 6e         { "xShmUn
7180: 6d 61 70 22 2c 20 20 20 54 45 53 54 56 46 53 5f  map",   TESTVFS_
7190: 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c  SHMCLOSE_MASK },
71a0: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d  .        { "xShm
71b0: 4d 61 70 22 2c 20 20 20 20 20 54 45 53 54 56 46  Map",     TESTVF
71c0: 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 7d 2c  S_SHMMAP_MASK },
71d0: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 79 6e  .        { "xSyn
71e0: 63 22 2c 20 20 20 20 20 20 20 54 45 53 54 56 46  c",       TESTVF
71f0: 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 7d 2c 0a 20  S_SYNC_MASK },. 
7200: 20 20 20 20 20 20 20 7b 20 22 78 44 65 6c 65 74         { "xDelet
7210: 65 22 2c 20 20 20 20 20 54 45 53 54 56 46 53 5f  e",     TESTVFS_
7220: 44 45 4c 45 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20  DELETE_MASK },. 
7230: 20 20 20 20 20 20 20 7b 20 22 78 57 72 69 74 65         { "xWrite
7240: 22 2c 20 20 20 20 20 20 54 45 53 54 56 46 53 5f  ",      TESTVFS_
7250: 57 52 49 54 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20  WRITE_MASK },.  
7260: 20 20 20 20 20 20 7b 20 22 78 54 72 75 6e 63 61        { "xTrunca
7270: 74 65 22 2c 20 20 20 54 45 53 54 56 46 53 5f 54  te",   TESTVFS_T
7280: 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 7d 2c 0a  RUNCATE_MASK },.
7290: 20 20 20 20 20 20 20 20 7b 20 22 78 4f 70 65 6e          { "xOpen
72a0: 22 2c 20 20 20 20 20 20 20 54 45 53 54 56 46 53  ",       TESTVFS
72b0: 5f 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20  _OPEN_MASK },.  
72c0: 20 20 20 20 20 20 7b 20 22 78 43 6c 6f 73 65 22        { "xClose"
72d0: 2c 20 20 20 20 20 20 54 45 53 54 56 46 53 5f 43  ,      TESTVFS_C
72e0: 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  LOSE_MASK },.   
72f0: 20 20 20 20 20 7b 20 22 78 41 63 63 65 73 73 22       { "xAccess"
7300: 2c 20 20 20 20 20 54 45 53 54 56 46 53 5f 41 43  ,     TESTVFS_AC
7310: 43 45 53 53 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  CESS_MASK },.   
7320: 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f     };.      Tcl_
7330: 4f 62 6a 20 2a 2a 61 70 45 6c 65 6d 20 3d 20 30  Obj **apElem = 0
7340: 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6c 65  ;.      int nEle
7350: 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  m = 0;.      int
7360: 20 69 3b 0a 20 20 20 20 20 20 69 6e 74 20 6d 61   i;.      int ma
7370: 73 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66  sk = 0;.      if
7380: 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20  ( objc!=3 ){.   
7390: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
73a0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
73b0: 20 6f 62 6a 76 2c 20 22 4c 49 53 54 22 29 3b 0a   objv, "LIST");.
73c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
73d0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
73e0: 7d 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f  }.      if( Tcl_
73f0: 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e  ListObjGetElemen
7400: 74 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  ts(interp, objv[
7410: 32 5d 2c 20 26 6e 45 6c 65 6d 2c 20 26 61 70 45  2], &nElem, &apE
7420: 6c 65 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  lem) ){.        
7430: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
7440: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
7450: 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28  Tcl_ResetResult(
7460: 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20 20 66  interp);.      f
7470: 6f 72 28 69 3d 30 3b 20 69 3c 6e 45 6c 65 6d 3b  or(i=0; i<nElem;
7480: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69   i++){.        i
7490: 6e 74 20 69 4d 65 74 68 6f 64 3b 0a 20 20 20 20  nt iMethod;.    
74a0: 20 20 20 20 63 68 61 72 20 2a 7a 45 6c 65 6d 20      char *zElem 
74b0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
74c0: 61 70 45 6c 65 6d 5b 69 5d 29 3b 0a 20 20 20 20  apElem[i]);.    
74d0: 20 20 20 20 66 6f 72 28 69 4d 65 74 68 6f 64 3d      for(iMethod=
74e0: 30 3b 20 69 4d 65 74 68 6f 64 3c 41 72 72 61 79  0; iMethod<Array
74f0: 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64 29 3b  Size(vfsmethod);
7500: 20 69 4d 65 74 68 6f 64 2b 2b 29 7b 0a 20 20 20   iMethod++){.   
7510: 20 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d         if( strcm
7520: 70 28 7a 45 6c 65 6d 2c 20 76 66 73 6d 65 74 68  p(zElem, vfsmeth
7530: 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e 7a 4e 61 6d  od[iMethod].zNam
7540: 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  e)==0 ){.       
7550: 20 20 20 20 20 6d 61 73 6b 20 7c 3d 20 76 66 73       mask |= vfs
7560: 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e  method[iMethod].
7570: 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20 20 20 20  mask;.          
7580: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
7590: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
75a0: 20 20 20 20 20 20 20 69 66 28 20 69 4d 65 74 68         if( iMeth
75b0: 6f 64 3d 3d 41 72 72 61 79 53 69 7a 65 28 76 66  od==ArraySize(vf
75c0: 73 6d 65 74 68 6f 64 29 20 29 7b 0a 20 20 20 20  smethod) ){.    
75d0: 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64        Tcl_Append
75e0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
75f0: 75 6e 6b 6e 6f 77 6e 20 6d 65 74 68 6f 64 3a 20  unknown method: 
7600: 22 2c 20 7a 45 6c 65 6d 2c 20 30 29 3b 0a 20 20  ", zElem, 0);.  
7610: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
7620: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
7630: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
7640: 20 20 70 2d 3e 6d 61 73 6b 20 3d 20 6d 61 73 6b    p->mask = mask
7650: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
7660: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43     }..    case C
7670: 4d 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20 20 20  MD_SCRIPT: {.   
7680: 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29     if( objc==3 )
7690: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42  {.        int nB
76a0: 79 74 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28  yte;.        if(
76b0: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 7b 0a 20   p->pScript ){. 
76c0: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 44 65 63           Tcl_Dec
76d0: 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63  rRefCount(p->pSc
76e0: 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 20  ript);.         
76f0: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
7700: 70 2d 3e 61 70 53 63 72 69 70 74 29 3b 0a 20 20  p->apScript);.  
7710: 20 20 20 20 20 20 20 20 70 2d 3e 61 70 53 63 72          p->apScr
7720: 69 70 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ipt = 0;.       
7730: 20 20 20 70 2d 3e 6e 53 63 72 69 70 74 20 3d 20     p->nScript = 
7740: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  0;.          p->
7750: 70 53 63 72 69 70 74 20 3d 20 30 3b 0a 20 20 20  pScript = 0;.   
7760: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 54       }.        T
7770: 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d  cl_GetStringFrom
7780: 4f 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26 6e 42  Obj(objv[2], &nB
7790: 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66  yte);.        if
77a0: 28 20 6e 42 79 74 65 3e 30 20 29 7b 0a 20 20 20  ( nByte>0 ){.   
77b0: 20 20 20 20 20 20 20 70 2d 3e 70 53 63 72 69 70         p->pScrip
77c0: 74 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61 74  t = Tcl_Duplicat
77d0: 65 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29 3b 0a 20  eObj(objv[2]);. 
77e0: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 49 6e 63           Tcl_Inc
77f0: 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63  rRefCount(p->pSc
7800: 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20 20 7d  ript);.        }
7810: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
7820: 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20   objc!=2 ){.    
7830: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
7840: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20  Args(interp, 2, 
7850: 6f 62 6a 76 2c 20 22 3f 53 43 52 49 50 54 3f 22  objv, "?SCRIPT?"
7860: 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  );.        retur
7870: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
7880: 20 20 20 7d 0a 0a 20 20 20 20 20 20 54 63 6c 5f     }..      Tcl_
7890: 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65  ResetResult(inte
78a0: 72 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  rp);.      if( p
78b0: 2d 3e 70 53 63 72 69 70 74 20 29 20 54 63 6c 5f  ->pScript ) Tcl_
78c0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
78d0: 65 72 70 2c 20 70 2d 3e 70 53 63 72 69 70 74 29  erp, p->pScript)
78e0: 3b 0a 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  ;..      break;.
78f0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 0a 20 20      }..    /*.  
7900: 20 20 2a 2a 20 54 45 53 54 56 46 53 20 69 6f 65    ** TESTVFS ioe
7910: 72 72 20 3f 49 46 41 49 4c 20 50 45 52 53 49 53  rr ?IFAIL PERSIS
7920: 54 3f 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  T?.    **.    **
7930: 20 20 20 57 68 65 72 65 20 49 46 41 49 4c 20 69     Where IFAIL i
7940: 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64  s an integer and
7950: 20 50 45 52 53 49 53 54 20 69 73 20 62 6f 6f 6c   PERSIST is bool
7960: 65 61 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ean..    */.    
7970: 63 61 73 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45  case CMD_CANTOPE
7980: 4e 45 52 52 3a 0a 20 20 20 20 63 61 73 65 20 43  NERR:.    case C
7990: 4d 44 5f 49 4f 45 52 52 3a 0a 20 20 20 20 63 61  MD_IOERR:.    ca
79a0: 73 65 20 43 4d 44 5f 46 55 4c 4c 45 52 52 3a 20  se CMD_FULLERR: 
79b0: 7b 0a 20 20 20 20 20 20 54 65 73 74 46 61 75 6c  {.      TestFaul
79c0: 74 49 6e 6a 65 63 74 20 2a 70 54 65 73 74 3b 0a  tInject *pTest;.
79d0: 20 20 20 20 20 20 69 6e 74 20 69 52 65 74 3b 0a        int iRet;.
79e0: 0a 20 20 20 20 20 20 73 77 69 74 63 68 28 20 61  .      switch( a
79f0: 53 75 62 63 6d 64 5b 69 5d 2e 65 43 6d 64 20 29  Subcmd[i].eCmd )
7a00: 7b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 43  {.        case C
7a10: 4d 44 5f 49 4f 45 52 52 3a 20 70 54 65 73 74 20  MD_IOERR: pTest 
7a20: 3d 20 26 70 2d 3e 69 6f 65 72 72 5f 65 72 72 3b  = &p->ioerr_err;
7a30: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
7a40: 63 61 73 65 20 43 4d 44 5f 46 55 4c 4c 45 52 52  case CMD_FULLERR
7a50: 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 66 75  : pTest = &p->fu
7a60: 6c 6c 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20  ll_err; break;. 
7a70: 20 20 20 20 20 20 20 63 61 73 65 20 43 4d 44 5f         case CMD_
7a80: 43 41 4e 54 4f 50 45 4e 45 52 52 3a 20 70 54 65  CANTOPENERR: pTe
7a90: 73 74 20 3d 20 26 70 2d 3e 63 61 6e 74 6f 70 65  st = &p->cantope
7aa0: 6e 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20 20  n_err; break;.  
7ab0: 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 20 61        default: a
7ac0: 73 73 65 72 74 28 30 29 3b 0a 20 20 20 20 20 20  ssert(0);.      
7ad0: 7d 0a 20 20 20 20 20 20 69 52 65 74 20 3d 20 70  }.      iRet = p
7ae0: 54 65 73 74 2d 3e 6e 46 61 69 6c 3b 0a 20 20 20  Test->nFail;.   
7af0: 20 20 20 70 54 65 73 74 2d 3e 6e 46 61 69 6c 20     pTest->nFail 
7b00: 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 65 73 74  = 0;.      pTest
7b10: 2d 3e 65 46 61 75 6c 74 20 3d 20 30 3b 0a 20 20  ->eFault = 0;.  
7b20: 20 20 20 20 70 54 65 73 74 2d 3e 69 43 6e 74 20      pTest->iCnt 
7b30: 3d 20 30 3b 0a 0a 20 20 20 20 20 20 69 66 28 20  = 0;..      if( 
7b40: 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20  objc==4 ){.     
7b50: 20 20 20 69 6e 74 20 69 43 6e 74 2c 20 69 50 65     int iCnt, iPe
7b60: 72 73 69 73 74 3b 0a 20 20 20 20 20 20 20 20 69  rsist;.        i
7b70: 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47  f( TCL_OK!=Tcl_G
7b80: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
7b90: 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69  erp, objv[2], &i
7ba0: 43 6e 74 29 0a 20 20 20 20 20 20 20 20 20 7c 7c  Cnt).         ||
7bb0: 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47 65 74   TCL_OK!=Tcl_Get
7bc0: 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69  BooleanFromObj(i
7bd0: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 33 5d 2c 20  nterp, objv[3], 
7be0: 26 69 50 65 72 73 69 73 74 29 0a 20 20 20 20 20  &iPersist).     
7bf0: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
7c00: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
7c10: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
7c20: 20 20 20 20 70 54 65 73 74 2d 3e 65 46 61 75 6c      pTest->eFaul
7c30: 74 20 3d 20 69 50 65 72 73 69 73 74 3f 46 41 55  t = iPersist?FAU
7c40: 4c 54 5f 49 4e 4a 45 43 54 5f 50 45 52 53 49 53  LT_INJECT_PERSIS
7c50: 54 45 4e 54 3a 46 41 55 4c 54 5f 49 4e 4a 45 43  TENT:FAULT_INJEC
7c60: 54 5f 54 52 41 4e 53 49 45 4e 54 3b 0a 20 20 20  T_TRANSIENT;.   
7c70: 20 20 20 20 20 70 54 65 73 74 2d 3e 69 43 6e 74       pTest->iCnt
7c80: 20 3d 20 69 43 6e 74 3b 0a 20 20 20 20 20 20 7d   = iCnt;.      }
7c90: 65 6c 73 65 20 69 66 28 20 6f 62 6a 63 21 3d 32  else if( objc!=2
7ca0: 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f   ){.        Tcl_
7cb0: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
7cc0: 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f  erp, 2, objv, "?
7cd0: 43 4e 54 20 50 45 52 53 49 53 54 3f 22 29 3b 0a  CNT PERSIST?");.
7ce0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
7cf0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
7d00: 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f  }.      Tcl_SetO
7d10: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
7d20: 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69   Tcl_NewIntObj(i
7d30: 52 65 74 29 29 3b 0a 20 20 20 20 20 20 62 72 65  Ret));.      bre
7d40: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
7d50: 61 73 65 20 43 4d 44 5f 44 45 4c 45 54 45 3a 20  ase CMD_DELETE: 
7d60: 7b 0a 20 20 20 20 20 20 54 63 6c 5f 44 65 6c 65  {.      Tcl_Dele
7d70: 74 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  teCommand(interp
7d80: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
7d90: 6f 62 6a 76 5b 30 5d 29 29 3b 0a 20 20 20 20 20  objv[0]));.     
7da0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
7db0: 20 20 20 63 61 73 65 20 43 4d 44 5f 44 45 56 43     case CMD_DEVC
7dc0: 48 41 52 3a 20 7b 0a 20 20 20 20 20 20 73 74 72  HAR: {.      str
7dd0: 75 63 74 20 44 65 76 69 63 65 46 6c 61 67 20 7b  uct DeviceFlag {
7de0: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a  .        char *z
7df0: 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 69 6e  Name;.        in
7e00: 74 20 69 56 61 6c 75 65 3b 0a 20 20 20 20 20 20  t iValue;.      
7e10: 7d 20 61 46 6c 61 67 5b 5d 20 3d 20 7b 0a 20 20  } aFlag[] = {.  
7e20: 20 20 20 20 20 20 7b 20 22 64 65 66 61 75 6c 74        { "default
7e30: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ",              
7e40: 20 2d 31 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b   -1 },.        {
7e50: 20 22 61 74 6f 6d 69 63 22 2c 20 20 20 20 20 20   "atomic",      
7e60: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7e70: 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 20 20 20  _IOCAP_ATOMIC   
7e80: 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20     },.        { 
7e90: 22 61 74 6f 6d 69 63 35 31 32 22 2c 20 20 20 20  "atomic512",    
7ea0: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7eb0: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 35 31 32 20  IOCAP_ATOMIC512 
7ec0: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22    },.        { "
7ed0: 61 74 6f 6d 69 63 31 6b 22 2c 20 20 20 20 20 20  atomic1k",      
7ee0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49          SQLITE_I
7ef0: 4f 43 41 50 5f 41 54 4f 4d 49 43 31 4b 20 20 20  OCAP_ATOMIC1K   
7f00: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61   },.        { "a
7f10: 74 6f 6d 69 63 32 6b 22 2c 20 20 20 20 20 20 20  tomic2k",       
7f20: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f         SQLITE_IO
7f30: 43 41 50 5f 41 54 4f 4d 49 43 32 4b 20 20 20 20  CAP_ATOMIC2K    
7f40: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74  },.        { "at
7f50: 6f 6d 69 63 34 6b 22 2c 20 20 20 20 20 20 20 20  omic4k",        
7f60: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
7f70: 41 50 5f 41 54 4f 4d 49 43 34 4b 20 20 20 20 7d  AP_ATOMIC4K    }
7f80: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f  ,.        { "ato
7f90: 6d 69 63 38 6b 22 2c 20 20 20 20 20 20 20 20 20  mic8k",         
7fa0: 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41       SQLITE_IOCA
7fb0: 50 5f 41 54 4f 4d 49 43 38 4b 20 20 20 20 7d 2c  P_ATOMIC8K    },
7fc0: 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d  .        { "atom
7fd0: 69 63 31 36 6b 22 2c 20 20 20 20 20 20 20 20 20  ic16k",         
7fe0: 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50      SQLITE_IOCAP
7ff0: 5f 41 54 4f 4d 49 43 31 36 4b 20 20 20 7d 2c 0a  _ATOMIC16K   },.
8000: 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69          { "atomi
8010: 63 33 32 6b 22 2c 20 20 20 20 20 20 20 20 20 20  c32k",          
8020: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
8030: 41 54 4f 4d 49 43 33 32 4b 20 20 20 7d 2c 0a 20  ATOMIC32K   },. 
8040: 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63         { "atomic
8050: 36 34 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20  64k",           
8060: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41    SQLITE_IOCAP_A
8070: 54 4f 4d 49 43 36 34 4b 20 20 20 7d 2c 0a 20 20  TOMIC64K   },.  
8080: 20 20 20 20 20 20 7b 20 22 73 65 71 75 65 6e 74        { "sequent
8090: 69 61 6c 22 2c 20 20 20 20 20 20 20 20 20 20 20  ial",           
80a0: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53 45   SQLITE_IOCAP_SE
80b0: 51 55 45 4e 54 49 41 4c 20 20 7d 2c 0a 20 20 20  QUENTIAL  },.   
80c0: 20 20 20 20 20 7b 20 22 73 61 66 65 5f 61 70 70       { "safe_app
80d0: 65 6e 64 22 2c 20 20 20 20 20 20 20 20 20 20 20  end",           
80e0: 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53 41 46  SQLITE_IOCAP_SAF
80f0: 45 5f 41 50 50 45 4e 44 20 7d 2c 0a 20 20 20 20  E_APPEND },.    
8100: 20 20 20 20 7b 20 22 75 6e 64 65 6c 65 74 61 62      { "undeletab
8110: 6c 65 5f 77 68 65 6e 5f 6f 70 65 6e 22 2c 20 53  le_when_open", S
8120: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 55 4e 44 45  QLITE_IOCAP_UNDE
8130: 4c 45 54 41 42 4c 45 5f 57 48 45 4e 5f 4f 50 45  LETABLE_WHEN_OPE
8140: 4e 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 30  N },.        { 0
8150: 2c 20 30 20 7d 0a 20 20 20 20 20 20 7d 3b 0a 20  , 0 }.      };. 
8160: 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 52       Tcl_Obj *pR
8170: 65 74 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 46  et;.      int iF
8180: 6c 61 67 3b 0a 0a 20 20 20 20 20 20 69 66 28 20  lag;..      if( 
8190: 6f 62 6a 63 3e 33 20 29 7b 0a 20 20 20 20 20 20  objc>3 ){.      
81a0: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
81b0: 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62  gs(interp, 2, ob
81c0: 6a 76 2c 20 22 3f 41 54 54 52 2d 4c 49 53 54 3f  jv, "?ATTR-LIST?
81d0: 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  ");.        retu
81e0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
81f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
8200: 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20  objc==3 ){.     
8210: 20 20 20 69 6e 74 20 6a 3b 0a 20 20 20 20 20 20     int j;.      
8220: 20 20 69 6e 74 20 69 4e 65 77 20 3d 20 30 3b 0a    int iNew = 0;.
8230: 20 20 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20          Tcl_Obj 
8240: 2a 2a 66 6c 61 67 73 20 3d 20 30 3b 0a 20 20 20  **flags = 0;.   
8250: 20 20 20 20 20 69 6e 74 20 6e 46 6c 61 67 73 20       int nFlags 
8260: 3d 20 30 3b 0a 0a 20 20 20 20 20 20 20 20 69 66  = 0;..        if
8270: 28 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74  ( Tcl_ListObjGet
8280: 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c  Elements(interp,
8290: 20 6f 62 6a 76 5b 32 5d 2c 20 26 6e 46 6c 61 67   objv[2], &nFlag
82a0: 73 2c 20 26 66 6c 61 67 73 29 20 29 7b 0a 20 20  s, &flags) ){.  
82b0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
82c0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
82d0: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 66 6f 72    }..        for
82e0: 28 6a 3d 30 3b 20 6a 3c 6e 46 6c 61 67 73 3b 20  (j=0; j<nFlags; 
82f0: 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20  j++){.          
8300: 69 6e 74 20 69 64 78 20 3d 20 30 3b 0a 20 20 20  int idx = 0;.   
8310: 20 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47         if( Tcl_G
8320: 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a 53 74  etIndexFromObjSt
8330: 72 75 63 74 28 69 6e 74 65 72 70 2c 20 66 6c 61  ruct(interp, fla
8340: 67 73 5b 6a 5d 2c 20 61 46 6c 61 67 2c 20 0a 20  gs[j], aFlag, . 
8350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73                 s
8360: 69 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d 29 2c  izeof(aFlag[0]),
8370: 20 22 66 6c 61 67 22 2c 20 30 2c 20 26 69 64 78   "flag", 0, &idx
8380: 29 20 0a 20 20 20 20 20 20 20 20 20 20 29 7b 0a  ) .          ){.
8390: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
83a0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
83b0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
83c0: 20 20 20 20 69 66 28 20 61 46 6c 61 67 5b 69 64      if( aFlag[id
83d0: 78 5d 2e 69 56 61 6c 75 65 3c 30 20 26 26 20 6e  x].iValue<0 && n
83e0: 46 6c 61 67 73 3e 31 20 29 7b 0a 20 20 20 20 20  Flags>1 ){.     
83f0: 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65 6e         Tcl_Appen
8400: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
8410: 22 62 61 64 20 66 6c 61 67 73 3a 20 22 2c 20 54  "bad flags: ", T
8420: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
8430: 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20 20 20  v[2]), 0);.     
8440: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43         return TC
8450: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20  L_ERROR;.       
8460: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69     }.          i
8470: 4e 65 77 20 7c 3d 20 61 46 6c 61 67 5b 69 64 78  New |= aFlag[idx
8480: 5d 2e 69 56 61 6c 75 65 3b 0a 20 20 20 20 20 20  ].iValue;.      
8490: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 70 2d 3e    }..        p->
84a0: 69 44 65 76 63 68 61 72 20 3d 20 69 4e 65 77 3b  iDevchar = iNew;
84b0: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
84c0: 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  pRet = Tcl_NewOb
84d0: 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69  j();.      for(i
84e0: 46 6c 61 67 3d 30 3b 20 69 46 6c 61 67 3c 73 69  Flag=0; iFlag<si
84f0: 7a 65 6f 66 28 61 46 6c 61 67 29 2f 73 69 7a 65  zeof(aFlag)/size
8500: 6f 66 28 61 46 6c 61 67 5b 30 5d 29 3b 20 69 46  of(aFlag[0]); iF
8510: 6c 61 67 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  lag++){.        
8520: 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61 72 20  if( p->iDevchar 
8530: 26 20 61 46 6c 61 67 5b 69 46 6c 61 67 5d 2e 69  & aFlag[iFlag].i
8540: 56 61 6c 75 65 20 29 7b 0a 20 20 20 20 20 20 20  Value ){.       
8550: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
8560: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 0a 20 20 20  pendElement(.   
8570: 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 65 72             inter
8580: 70 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e 65 77  p, pRet, Tcl_New
8590: 53 74 72 69 6e 67 4f 62 6a 28 61 46 6c 61 67 5b  StringObj(aFlag[
85a0: 69 46 6c 61 67 5d 2e 7a 4e 61 6d 65 2c 20 2d 31  iFlag].zName, -1
85b0: 29 0a 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20  ).          );. 
85c0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
85d0: 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74 4f 62  .      Tcl_SetOb
85e0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
85f0: 70 52 65 74 29 3b 0a 0a 20 20 20 20 20 20 62 72  pRet);..      br
8600: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
8610: 63 61 73 65 20 43 4d 44 5f 53 45 43 54 4f 52 53  case CMD_SECTORS
8620: 49 5a 45 3a 20 7b 0a 20 20 20 20 20 20 69 66 28  IZE: {.      if(
8630: 20 6f 62 6a 63 3e 33 20 29 7b 0a 20 20 20 20 20   objc>3 ){.     
8640: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
8650: 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f  rgs(interp, 2, o
8660: 62 6a 76 2c 20 22 3f 56 41 4c 55 45 3f 22 29 3b  bjv, "?VALUE?");
8670: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
8680: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
8690: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a   }.      if( obj
86a0: 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20  c==3 ){.        
86b0: 69 6e 74 20 69 4e 65 77 20 3d 20 30 3b 0a 20 20  int iNew = 0;.  
86c0: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
86d0: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
86e0: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 4e  rp, objv[2], &iN
86f0: 65 77 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ew) ){.         
8700: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8710: 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  R;.        }.   
8720: 20 20 20 20 20 70 2d 3e 69 53 65 63 74 6f 72 73       p->iSectors
8730: 69 7a 65 20 3d 20 69 4e 65 77 3b 0a 20 20 20 20  ize = iNew;.    
8740: 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65    }.      Tcl_Se
8750: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
8760: 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a  p, Tcl_NewIntObj
8770: 28 70 2d 3e 69 53 65 63 74 6f 72 73 69 7a 65 29  (p->iSectorsize)
8780: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
8790: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
87a0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73  urn TCL_OK;.}..s
87b0: 74 61 74 69 63 20 76 6f 69 64 20 74 65 73 74 76  tatic void testv
87c0: 66 73 5f 6f 62 6a 5f 64 65 6c 28 43 6c 69 65 6e  fs_obj_del(Clien
87d0: 74 44 61 74 61 20 63 64 29 7b 0a 20 20 54 65 73  tData cd){.  Tes
87e0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
87f0: 66 73 20 2a 29 63 64 3b 0a 20 20 69 66 28 20 70  fs *)cd;.  if( p
8800: 2d 3e 70 53 63 72 69 70 74 20 29 20 54 63 6c 5f  ->pScript ) Tcl_
8810: 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e  DecrRefCount(p->
8820: 70 53 63 72 69 70 74 29 3b 0a 20 20 73 71 6c 69  pScript);.  sqli
8830: 74 65 33 5f 76 66 73 5f 75 6e 72 65 67 69 73 74  te3_vfs_unregist
8840: 65 72 28 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63  er(p->pVfs);.  c
8850: 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 2d  kfree((char *)p-
8860: 3e 61 70 53 63 72 69 70 74 29 3b 0a 20 20 63 6b  >apScript);.  ck
8870: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 2d 3e  free((char *)p->
8880: 70 56 66 73 29 3b 0a 20 20 63 6b 66 72 65 65 28  pVfs);.  ckfree(
8890: 28 63 68 61 72 20 2a 29 70 29 3b 0a 7d 0a 0a 2f  (char *)p);.}../
88a0: 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 20 74 65 73  *.** Usage:  tes
88b0: 74 76 66 73 20 56 46 53 4e 41 4d 45 20 3f 53 57  tvfs VFSNAME ?SW
88c0: 49 54 43 48 45 53 3f 0a 2a 2a 0a 2a 2a 20 53 77  ITCHES?.**.** Sw
88d0: 69 74 63 68 65 73 20 61 72 65 3a 0a 2a 2a 0a 2a  itches are:.**.*
88e0: 2a 20 20 20 2d 6e 6f 73 68 6d 20 20 20 42 4f 4f  *   -noshm   BOO
88f0: 4c 45 41 4e 20 20 20 20 20 20 20 20 20 20 20 20  LEAN            
8900: 20 28 54 72 75 65 20 74 6f 20 6f 6d 69 74 20 73   (True to omit s
8910: 68 6d 20 6d 65 74 68 6f 64 73 2e 20 44 65 66 61  hm methods. Defa
8920: 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 20 20 20  ult false).**   
8930: 2d 64 65 66 61 75 6c 74 20 42 4f 4f 4c 45 41 4e  -default BOOLEAN
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 54 72               (Tr
8950: 75 65 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 76  ue to make the v
8960: 66 73 20 64 65 66 61 75 6c 74 2e 20 44 65 66 61  fs default. Defa
8970: 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 0a 2a 2a  ult false).**.**
8980: 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20 63 72   This command cr
8990: 65 61 74 65 73 20 74 77 6f 20 74 68 69 6e 67 73  eates two things
89a0: 20 77 68 65 6e 20 69 74 20 69 73 20 69 6e 76 6f   when it is invo
89b0: 6b 65 64 3a 20 61 6e 20 53 51 4c 69 74 65 20 56  ked: an SQLite V
89c0: 46 53 2c 20 61 6e 64 0a 2a 2a 20 61 20 54 63 6c  FS, and.** a Tcl
89d0: 20 63 6f 6d 6d 61 6e 64 2e 20 42 6f 74 68 20 61   command. Both a
89e0: 72 65 20 6e 61 6d 65 64 20 56 46 53 4e 41 4d 45  re named VFSNAME
89f0: 2e 20 54 68 65 20 56 46 53 20 69 73 20 69 6e 73  . The VFS is ins
8a00: 74 61 6c 6c 65 64 2e 20 49 74 20 69 73 20 6e 6f  talled. It is no
8a10: 74 0a 2a 2a 20 69 6e 73 74 61 6c 6c 65 64 20 61  t.** installed a
8a20: 73 20 74 68 65 20 64 65 66 61 75 6c 74 20 56 46  s the default VF
8a30: 53 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 56 46 53  S..**.** The VFS
8a40: 20 70 61 73 73 65 73 20 61 6c 6c 20 66 69 6c 65   passes all file
8a50: 20 49 2f 4f 20 63 61 6c 6c 73 20 74 68 72 6f 75   I/O calls throu
8a60: 67 68 20 74 6f 20 74 68 65 20 75 6e 64 65 72 6c  gh to the underl
8a70: 79 69 6e 67 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20  ying VFS..**.** 
8a80: 57 68 65 6e 65 76 65 72 20 74 68 65 20 78 53 68  Whenever the xSh
8a90: 6d 4d 61 70 20 6d 65 74 68 6f 64 20 6f 66 20 74  mMap method of t
8aa0: 68 65 20 56 46 53 0a 2a 2a 20 69 73 20 69 6e 76  he VFS.** is inv
8ab0: 6f 6b 65 64 2c 20 74 68 65 20 53 43 52 49 50 54  oked, the SCRIPT
8ac0: 20 69 73 20 65 78 65 63 75 74 65 64 20 61 73 20   is executed as 
8ad0: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
8ae0: 20 53 43 52 49 50 54 20 78 53 68 6d 4d 61 70 20   SCRIPT xShmMap 
8af0: 20 20 20 46 49 4c 45 4e 41 4d 45 20 49 44 0a 2a     FILENAME ID.*
8b00: 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20 72  *.** The value r
8b10: 65 74 75 72 6e 65 64 20 62 79 20 74 68 65 20 69  eturned by the i
8b20: 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20 53 43 52  nvocation of SCR
8b30: 49 50 54 20 61 62 6f 76 65 20 69 73 20 69 6e 74  IPT above is int
8b40: 65 72 70 72 65 74 65 64 20 61 73 0a 2a 2a 20 61  erpreted as.** a
8b50: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
8b60: 6f 64 65 20 61 6e 64 20 72 65 74 75 72 6e 65 64  ode and returned
8b70: 20 74 6f 20 53 51 4c 69 74 65 2e 20 45 69 74 68   to SQLite. Eith
8b80: 65 72 20 61 20 73 79 6d 62 6f 6c 69 63 20 0a 2a  er a symbolic .*
8b90: 2a 20 22 53 51 4c 49 54 45 5f 4f 4b 22 20 6f 72  * "SQLITE_OK" or
8ba0: 20 6e 75 6d 65 72 69 63 20 22 30 22 20 76 61 6c   numeric "0" val
8bb0: 75 65 20 6d 61 79 20 62 65 20 72 65 74 75 72 6e  ue may be return
8bc0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f  ed..**.** The co
8bd0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73 68  ntents of the sh
8be0: 61 72 65 64 2d 6d 65 6d 6f 72 79 20 62 75 66 66  ared-memory buff
8bf0: 65 72 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  er associated wi
8c00: 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c 65 0a  th a given file.
8c10: 2a 2a 20 6d 61 79 20 62 65 20 72 65 61 64 20 61  ** may be read a
8c20: 6e 64 20 73 65 74 20 75 73 69 6e 67 20 74 68 65  nd set using the
8c30: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6d 6d 61   following comma
8c40: 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 56 46 53 4e  nd:.**.**   VFSN
8c50: 41 4d 45 20 73 68 6d 20 46 49 4c 45 4e 41 4d 45  AME shm FILENAME
8c60: 20 3f 4e 45 57 56 41 4c 55 45 3f 0a 2a 2a 0a 2a   ?NEWVALUE?.**.*
8c70: 2a 20 57 68 65 6e 20 74 68 65 20 78 53 68 6d 4c  * When the xShmL
8c80: 6f 63 6b 20 6d 65 74 68 6f 64 20 69 73 20 69 6e  ock method is in
8c90: 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74 65 2c  voked by SQLite,
8ca0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73   the following s
8cb0: 63 72 69 70 74 20 69 73 0a 2a 2a 20 72 75 6e 3a  cript is.** run:
8cc0: 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50 54 20  .**.**   SCRIPT 
8cd0: 78 53 68 6d 4c 6f 63 6b 20 20 20 20 46 49 4c 45  xShmLock    FILE
8ce0: 4e 41 4d 45 20 49 44 20 4c 4f 43 4b 0a 2a 2a 0a  NAME ID LOCK.**.
8cf0: 2a 2a 20 77 68 65 72 65 20 4c 4f 43 4b 20 69 73  ** where LOCK is
8d00: 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 4f 46   of the form "OF
8d10: 46 53 45 54 20 4e 42 59 54 45 20 6c 6f 63 6b 2f  FSET NBYTE lock/
8d20: 75 6e 6c 6f 63 6b 20 73 68 61 72 65 64 2f 65 78  unlock shared/ex
8d30: 63 6c 75 73 69 76 65 22 0a 2a 2f 0a 73 74 61 74  clusive".*/.stat
8d40: 69 63 20 69 6e 74 20 74 65 73 74 76 66 73 5f 63  ic int testvfs_c
8d50: 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61  md(.  ClientData
8d60: 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72   cd,.  Tcl_Inter
8d70: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
8d80: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
8d90: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
8da0: 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c 69 74  {.  static sqlit
8db0: 65 33 5f 76 66 73 20 74 76 66 73 5f 76 66 73 20  e3_vfs tvfs_vfs 
8dc0: 3d 20 7b 0a 20 20 20 20 32 2c 20 20 20 20 20 20  = {.    2,      
8dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8de0: 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f        /* iVersio
8df0: 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  n */.    0,     
8e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e10: 20 20 20 20 20 20 20 2f 2a 20 73 7a 4f 73 46 69         /* szOsFi
8e20: 6c 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  le */.    0,    
8e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e40: 20 20 20 20 20 20 20 20 2f 2a 20 6d 78 50 61 74          /* mxPat
8e50: 68 6e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20  hname */.    0, 
8e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 4e             /* pN
8e80: 65 78 74 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ext */.    0,   
8e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ea0: 20 20 20 20 20 20 20 20 20 2f 2a 20 7a 4e 61 6d           /* zNam
8eb0: 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  e */.    0,     
8ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ed0: 20 20 20 20 20 20 20 2f 2a 20 70 41 70 70 44 61         /* pAppDa
8ee0: 74 61 20 2a 2f 0a 20 20 20 20 74 76 66 73 4f 70  ta */.    tvfsOp
8ef0: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
8f00: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
8f10: 20 2a 2f 0a 20 20 20 20 74 76 66 73 44 65 6c 65   */.    tvfsDele
8f20: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
8f30: 20 20 20 20 20 20 2f 2a 20 78 44 65 6c 65 74 65        /* xDelete
8f40: 20 2a 2f 0a 20 20 20 20 74 76 66 73 41 63 63 65   */.    tvfsAcce
8f50: 73 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ss,             
8f60: 20 20 20 20 20 20 2f 2a 20 78 41 63 63 65 73 73        /* xAccess
8f70: 20 2a 2f 0a 20 20 20 20 74 76 66 73 46 75 6c 6c   */.    tvfsFull
8f80: 50 61 74 68 6e 61 6d 65 2c 20 20 20 20 20 20 20  Pathname,       
8f90: 20 20 20 20 20 20 2f 2a 20 78 46 75 6c 6c 50 61        /* xFullPa
8fa0: 74 68 6e 61 6d 65 20 2a 2f 0a 23 69 66 6e 64 65  thname */.#ifnde
8fb0: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f  f SQLITE_OMIT_LO
8fc0: 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a 20 20 20  AD_EXTENSION.   
8fd0: 20 74 76 66 73 44 6c 4f 70 65 6e 2c 20 20 20 20   tvfsDlOpen,    
8fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8ff0: 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20 20  * xDlOpen */.   
9000: 20 74 76 66 73 44 6c 45 72 72 6f 72 2c 20 20 20   tvfsDlError,   
9010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9020: 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f 0a 20 20  * xDlError */.  
9030: 20 20 74 76 66 73 44 6c 53 79 6d 2c 20 20 20 20    tvfsDlSym,    
9040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9050: 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20 20 20  /* xDlSym */.   
9060: 20 74 76 66 73 44 6c 43 6c 6f 73 65 2c 20 20 20   tvfsDlClose,   
9070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9080: 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a 23 65  * xDlClose */.#e
9090: 6c 73 65 0a 20 20 20 20 30 2c 20 20 20 20 20 20  lse.    0,      
90a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90b0: 20 20 20 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e        /* xDlOpen
90c0: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
90d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90e0: 20 20 20 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f        /* xDlErro
90f0: 72 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  r */.    0,     
9100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9110: 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d         /* xDlSym
9120: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
9130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9140: 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73        /* xDlClos
9150: 65 20 2a 2f 0a 23 65 6e 64 69 66 20 2f 2a 20 53  e */.#endif /* S
9160: 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f  QLITE_OMIT_LOAD_
9170: 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 20 20 20  EXTENSION */.   
9180: 20 74 76 66 73 52 61 6e 64 6f 6d 6e 65 73 73 2c   tvfsRandomness,
9190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
91a0: 2a 20 78 52 61 6e 64 6f 6d 6e 65 73 73 20 2a 2f  * xRandomness */
91b0: 0a 20 20 20 20 74 76 66 73 53 6c 65 65 70 2c 20  .    tvfsSleep, 
91c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91d0: 20 20 20 2f 2a 20 78 53 6c 65 65 70 20 2a 2f 0a     /* xSleep */.
91e0: 20 20 20 20 74 76 66 73 43 75 72 72 65 6e 74 54      tvfsCurrentT
91f0: 69 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ime,            
9200: 20 20 2f 2a 20 78 43 75 72 72 65 6e 74 54 69 6d    /* xCurrentTim
9210: 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  e */.    0,     
9220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9230: 20 20 20 20 20 20 20 2f 2a 20 78 47 65 74 4c 61         /* xGetLa
9240: 73 74 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30  stError */.    0
9250: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9260: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9270: 78 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36  xCurrentTimeInt6
9280: 34 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 54 65 73  4 */.  };..  Tes
9290: 74 76 66 73 20 2a 70 3b 20 20 20 20 20 20 20 20  tvfs *p;        
92a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
92b0: 4e 65 77 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  New object */.  
92c0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
92d0: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
92e0: 2f 2a 20 4e 65 77 20 56 46 53 20 2a 2f 0a 20 20  /* New VFS */.  
92f0: 63 68 61 72 20 2a 7a 56 66 73 3b 0a 20 20 69 6e  char *zVfs;.  in
9300: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
9310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9320: 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
9330: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 74 20 70  to allocate at p
9340: 20 2a 2f 0a 0a 20 20 69 6e 74 20 69 3b 0a 20 20   */..  int i;.  
9350: 69 6e 74 20 69 73 4e 6f 73 68 6d 20 3d 20 30 3b  int isNoshm = 0;
9360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9370: 2f 2a 20 54 72 75 65 20 69 66 20 2d 6e 6f 73 68  /* True if -nosh
9380: 6d 20 69 73 20 70 61 73 73 65 64 20 2a 2f 0a 20  m is passed */. 
9390: 20 69 6e 74 20 69 73 44 65 66 61 75 6c 74 20 3d   int isDefault =
93a0: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
93b0: 20 2f 2a 20 54 72 75 65 20 69 66 20 2d 64 65 66   /* True if -def
93c0: 61 75 6c 74 20 69 73 20 70 61 73 73 65 64 20 2a  ault is passed *
93d0: 2f 0a 20 20 69 6e 74 20 73 7a 4f 73 46 69 6c 65  /.  int szOsFile
93e0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
93f0: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 70 61 73      /* Value pas
9400: 73 65 64 20 74 6f 20 2d 73 7a 6f 73 66 69 6c 65  sed to -szosfile
9410: 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 61 74 68   */.  int mxPath
9420: 6e 61 6d 65 20 3d 20 2d 31 3b 20 20 20 20 20 20  name = -1;      
9430: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 70        /* Value p
9440: 61 73 73 65 64 20 74 6f 20 2d 6d 78 70 61 74 68  assed to -mxpath
9450: 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 69 56  name */.  int iV
9460: 65 72 73 69 6f 6e 20 3d 20 32 3b 20 20 20 20 20  ersion = 2;     
9470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
9480: 75 65 20 70 61 73 73 65 64 20 74 6f 20 2d 69 76  ue passed to -iv
9490: 65 72 73 69 6f 6e 20 2a 2f 0a 0a 20 20 69 66 28  ersion */..  if(
94a0: 20 6f 62 6a 63 3c 32 20 7c 7c 20 30 21 3d 28 6f   objc<2 || 0!=(o
94b0: 62 6a 63 25 32 29 20 29 20 67 6f 74 6f 20 62 61  bjc%2) ) goto ba
94c0: 64 5f 61 72 67 73 3b 0a 20 20 66 6f 72 28 69 3d  d_args;.  for(i=
94d0: 32 3b 20 69 3c 6f 62 6a 63 3b 20 69 20 2b 3d 20  2; i<objc; i += 
94e0: 32 29 7b 0a 20 20 20 20 69 6e 74 20 6e 53 77 69  2){.    int nSwi
94f0: 74 63 68 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  tch;.    char *z
9500: 53 77 69 74 63 68 3b 0a 20 20 20 20 7a 53 77 69  Switch;.    zSwi
9510: 74 63 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  tch = Tcl_GetStr
9520: 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b  ingFromObj(objv[
9530: 69 5d 2c 20 26 6e 53 77 69 74 63 68 29 3b 20 0a  i], &nSwitch); .
9540: 0a 20 20 20 20 69 66 28 20 6e 53 77 69 74 63 68  .    if( nSwitch
9550: 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70  >2 && 0==strncmp
9560: 28 22 2d 6e 6f 73 68 6d 22 2c 20 7a 53 77 69 74  ("-noshm", zSwit
9570: 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a  ch, nSwitch) ){.
9580: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
9590: 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28  tBooleanFromObj(
95a0: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31  interp, objv[i+1
95b0: 5d 2c 20 26 69 73 4e 6f 73 68 6d 29 20 29 7b 0a  ], &isNoshm) ){.
95c0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
95d0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
95e0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  }.    }.    else
95f0: 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26   if( nSwitch>2 &
9600: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 64  & 0==strncmp("-d
9610: 65 66 61 75 6c 74 22 2c 20 7a 53 77 69 74 63 68  efault", zSwitch
9620: 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20  , nSwitch) ){.  
9630: 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 42      if( Tcl_GetB
9640: 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e  ooleanFromObj(in
9650: 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c  terp, objv[i+1],
9660: 20 26 69 73 44 65 66 61 75 6c 74 29 20 29 7b 0a   &isDefault) ){.
9670: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 54          return T
9680: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  CL_ERROR;.      
9690: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65  }.    }.    else
96a0: 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26   if( nSwitch>2 &
96b0: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 73  & 0==strncmp("-s
96c0: 7a 6f 73 66 69 6c 65 22 2c 20 7a 53 77 69 74 63  zosfile", zSwitc
96d0: 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20  h, nSwitch) ){. 
96e0: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74       if( Tcl_Get
96f0: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
9700: 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 73  p, objv[i+1], &s
9710: 7a 4f 73 46 69 6c 65 29 20 29 7b 0a 20 20 20 20  zOsFile) ){.    
9720: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
9730: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
9740: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
9750: 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d   nSwitch>2 && 0=
9760: 3d 73 74 72 6e 63 6d 70 28 22 2d 6d 78 70 61 74  =strncmp("-mxpat
9770: 68 6e 61 6d 65 22 2c 20 7a 53 77 69 74 63 68 2c  hname", zSwitch,
9780: 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20   nSwitch) ){.   
9790: 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e     if( Tcl_GetIn
97a0: 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  tFromObj(interp,
97b0: 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 6d 78 50   objv[i+1], &mxP
97c0: 61 74 68 6e 61 6d 65 29 20 29 7b 0a 20 20 20 20  athname) ){.    
97d0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
97e0: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20  RROR;.      }.  
97f0: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
9800: 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d   nSwitch>2 && 0=
9810: 3d 73 74 72 6e 63 6d 70 28 22 2d 69 76 65 72 73  =strncmp("-ivers
9820: 69 6f 6e 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e  ion", zSwitch, n
9830: 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20  Switch) ){.     
9840: 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46   if( Tcl_GetIntF
9850: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
9860: 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 56 65 72 73  bjv[i+1], &iVers
9870: 69 6f 6e 29 20 29 7b 0a 20 20 20 20 20 20 20 20  ion) ){.        
9880: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
9890: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
98a0: 20 20 20 20 65 6c 73 65 7b 0a 20 20 20 20 20 20      else{.      
98b0: 67 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b 0a 20  goto bad_args;. 
98c0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
98d0: 73 7a 4f 73 46 69 6c 65 3c 73 69 7a 65 6f 66 28  szOsFile<sizeof(
98e0: 54 65 73 74 76 66 73 46 69 6c 65 29 20 29 7b 0a  TestvfsFile) ){.
98f0: 20 20 20 20 73 7a 4f 73 46 69 6c 65 20 3d 20 73      szOsFile = s
9900: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 69 6c  izeof(TestvfsFil
9910: 65 29 3b 0a 20 20 7d 0a 0a 20 20 7a 56 66 73 20  e);.  }..  zVfs 
9920: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
9930: 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 6e 42 79 74  objv[1]);.  nByt
9940: 65 20 3d 20 73 69 7a 65 6f 66 28 54 65 73 74 76  e = sizeof(Testv
9950: 66 73 29 20 2b 20 73 74 72 6c 65 6e 28 7a 56 66  fs) + strlen(zVf
9960: 73 29 2b 31 3b 0a 20 20 70 20 3d 20 28 54 65 73  s)+1;.  p = (Tes
9970: 74 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63 28 6e  tvfs *)ckalloc(n
9980: 42 79 74 65 29 3b 0a 20 20 6d 65 6d 73 65 74 28  Byte);.  memset(
9990: 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20  p, 0, nByte);.  
99a0: 70 2d 3e 69 44 65 76 63 68 61 72 20 3d 20 2d 31  p->iDevchar = -1
99b0: 3b 0a 20 20 70 2d 3e 69 53 65 63 74 6f 72 73 69  ;.  p->iSectorsi
99c0: 7a 65 20 3d 20 2d 31 3b 0a 0a 20 20 2f 2a 20 43  ze = -1;..  /* C
99d0: 72 65 61 74 65 20 74 68 65 20 6e 65 77 20 6f 62  reate the new ob
99e0: 6a 65 63 74 20 63 6f 6d 6d 61 6e 64 20 62 65 66  ject command bef
99f0: 6f 72 65 20 71 75 65 72 79 69 6e 67 20 53 51 4c  ore querying SQL
9a00: 69 74 65 20 66 6f 72 20 61 20 64 65 66 61 75 6c  ite for a defaul
9a10: 74 20 56 46 53 0a 20 20 2a 2a 20 74 6f 20 75 73  t VFS.  ** to us
9a20: 65 20 66 6f 72 20 27 72 65 61 6c 27 20 49 4f 20  e for 'real' IO 
9a30: 6f 70 65 72 61 74 69 6f 6e 73 2e 20 54 68 69 73  operations. This
9a40: 20 69 73 20 62 65 63 61 75 73 65 20 63 72 65 61   is because crea
9a50: 74 69 6e 67 20 74 68 65 20 6e 65 77 20 56 46 53  ting the new VFS
9a60: 0a 20 20 2a 2a 20 6d 61 79 20 64 65 6c 65 74 65  .  ** may delete
9a70: 20 61 6e 20 65 78 69 73 74 69 6e 67 20 5b 74 65   an existing [te
9a80: 73 74 76 66 73 5d 20 56 46 53 20 6f 66 20 74 68  stvfs] VFS of th
9a90: 65 20 73 61 6d 65 20 6e 61 6d 65 2e 20 49 66 20  e same name. If 
9aa0: 73 75 63 68 20 61 20 56 46 53 0a 20 20 2a 2a 20  such a VFS.  ** 
9ab0: 69 73 20 63 75 72 72 65 6e 74 6c 79 20 74 68 65  is currently the
9ac0: 20 64 65 66 61 75 6c 74 2c 20 74 68 65 20 6e 65   default, the ne
9ad0: 77 20 5b 74 65 73 74 76 66 73 5d 20 6d 61 79 20  w [testvfs] may 
9ae0: 65 6e 64 20 75 70 20 63 61 6c 6c 69 6e 67 20 74  end up calling t
9af0: 68 65 20 0a 20 20 2a 2a 20 6d 65 74 68 6f 64 73  he .  ** methods
9b00: 20 6f 66 20 61 20 64 65 6c 65 74 65 64 20 6f 62   of a deleted ob
9b10: 6a 65 63 74 2e 0a 20 20 2a 2f 0a 20 20 54 63 6c  ject..  */.  Tcl
9b20: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
9b30: 64 28 69 6e 74 65 72 70 2c 20 7a 56 66 73 2c 20  d(interp, zVfs, 
9b40: 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63 6d 64 2c  testvfs_obj_cmd,
9b50: 20 70 2c 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f   p, testvfs_obj_
9b60: 64 65 6c 29 3b 0a 20 20 70 2d 3e 70 50 61 72 65  del);.  p->pPare
9b70: 6e 74 20 3d 20 73 71 6c 69 74 65 33 5f 76 66 73  nt = sqlite3_vfs
9b80: 5f 66 69 6e 64 28 30 29 3b 0a 20 20 70 2d 3e 69  _find(0);.  p->i
9b90: 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a  nterp = interp;.
9ba0: 0a 20 20 70 2d 3e 7a 4e 61 6d 65 20 3d 20 28 63  .  p->zName = (c
9bb0: 68 61 72 20 2a 29 26 70 5b 31 5d 3b 0a 20 20 6d  har *)&p[1];.  m
9bc0: 65 6d 63 70 79 28 70 2d 3e 7a 4e 61 6d 65 2c 20  emcpy(p->zName, 
9bd0: 7a 56 66 73 2c 20 73 74 72 6c 65 6e 28 7a 56 66  zVfs, strlen(zVf
9be0: 73 29 2b 31 29 3b 0a 0a 20 20 70 56 66 73 20 3d  s)+1);..  pVfs =
9bf0: 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 29   (sqlite3_vfs *)
9c00: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73  ckalloc(sizeof(s
9c10: 71 6c 69 74 65 33 5f 76 66 73 29 29 3b 0a 20 20  qlite3_vfs));.  
9c20: 6d 65 6d 63 70 79 28 70 56 66 73 2c 20 26 74 76  memcpy(pVfs, &tv
9c30: 66 73 5f 76 66 73 2c 20 73 69 7a 65 6f 66 28 73  fs_vfs, sizeof(s
9c40: 71 6c 69 74 65 33 5f 76 66 73 29 29 3b 0a 20 20  qlite3_vfs));.  
9c50: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 20 3d  pVfs->pAppData =
9c60: 20 28 76 6f 69 64 20 2a 29 70 3b 0a 20 20 70 56   (void *)p;.  pV
9c70: 66 73 2d 3e 69 56 65 72 73 69 6f 6e 20 3d 20 69  fs->iVersion = i
9c80: 56 65 72 73 69 6f 6e 3b 0a 20 20 70 56 66 73 2d  Version;.  pVfs-
9c90: 3e 7a 4e 61 6d 65 20 3d 20 70 2d 3e 7a 4e 61 6d  >zName = p->zNam
9ca0: 65 3b 0a 20 20 70 56 66 73 2d 3e 6d 78 50 61 74  e;.  pVfs->mxPat
9cb0: 68 6e 61 6d 65 20 3d 20 70 2d 3e 70 50 61 72 65  hname = p->pPare
9cc0: 6e 74 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 3b 0a  nt->mxPathname;.
9cd0: 20 20 69 66 28 20 6d 78 50 61 74 68 6e 61 6d 65    if( mxPathname
9ce0: 3e 3d 30 20 26 26 20 6d 78 50 61 74 68 6e 61 6d  >=0 && mxPathnam
9cf0: 65 3c 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e 61  e<pVfs->mxPathna
9d00: 6d 65 20 29 7b 0a 20 20 20 20 70 56 66 73 2d 3e  me ){.    pVfs->
9d10: 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20 6d 78 50  mxPathname = mxP
9d20: 61 74 68 6e 61 6d 65 3b 0a 20 20 7d 0a 20 20 70  athname;.  }.  p
9d30: 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20 3d 20  Vfs->szOsFile = 
9d40: 73 7a 4f 73 46 69 6c 65 3b 0a 20 20 70 2d 3e 70  szOsFile;.  p->p
9d50: 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 2d  Vfs = pVfs;.  p-
9d60: 3e 69 73 4e 6f 73 68 6d 20 3d 20 69 73 4e 6f 73  >isNoshm = isNos
9d70: 68 6d 3b 0a 20 20 70 2d 3e 6d 61 73 6b 20 3d 20  hm;.  p->mask = 
9d80: 54 45 53 54 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b  TESTVFS_ALL_MASK
9d90: 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  ;..  sqlite3_vfs
9da0: 5f 72 65 67 69 73 74 65 72 28 70 56 66 73 2c 20  _register(pVfs, 
9db0: 69 73 44 65 66 61 75 6c 74 29 3b 0a 0a 20 20 72  isDefault);..  r
9dc0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 0a 20  eturn TCL_OK;.. 
9dd0: 62 61 64 5f 61 72 67 73 3a 0a 20 20 54 63 6c 5f  bad_args:.  Tcl_
9de0: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
9df0: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 56  erp, 1, objv, "V
9e00: 46 53 4e 41 4d 45 20 3f 2d 6e 6f 73 68 6d 20 42  FSNAME ?-noshm B
9e10: 4f 4f 4c 3f 20 3f 2d 64 65 66 61 75 6c 74 20 42  OOL? ?-default B
9e20: 4f 4f 4c 3f 20 3f 2d 6d 78 70 61 74 68 6e 61 6d  OOL? ?-mxpathnam
9e30: 65 20 49 4e 54 3f 20 3f 2d 73 7a 6f 73 66 69 6c  e INT? ?-szosfil
9e40: 65 20 49 4e 54 3f 20 3f 2d 69 76 65 72 73 69 6f  e INT? ?-iversio
9e50: 6e 20 49 4e 54 3f 22 29 3b 0a 20 20 72 65 74 75  n INT?");.  retu
9e60: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a  rn TCL_ERROR;.}.
9e70: 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 76  .int Sqlitetestv
9e80: 66 73 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  fs_Init(Tcl_Inte
9e90: 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 54  rp *interp){.  T
9ea0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
9eb0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 74 65 73  and(interp, "tes
9ec0: 74 76 66 73 22 2c 20 74 65 73 74 76 66 73 5f 63  tvfs", testvfs_c
9ed0: 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20 72 65 74  md, 0, 0);.  ret
9ee0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23  urn TCL_OK;.}..#
9ef0: 65 6e 64 69 66 0a                                endif.