/ Hex Artifact Content
Login

Artifact 88ca1326c124cc81396dd3ad752018c0e68711df:


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 2f  s.mxPathname).*/
03e0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  ..#include "sqli
03f0: 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  te3.h".#include 
0400: 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 0a 74  "sqliteInt.h"..t
0410: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54 65  ypedef struct Te
0420: 73 74 76 66 73 20 54 65 73 74 76 66 73 3b 0a 74  stvfs Testvfs;.t
0430: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54 65  ypedef struct Te
0440: 73 74 76 66 73 53 68 6d 20 54 65 73 74 76 66 73  stvfsShm Testvfs
0450: 53 68 6d 3b 0a 74 79 70 65 64 65 66 20 73 74 72  Shm;.typedef str
0460: 75 63 74 20 54 65 73 74 76 66 73 42 75 66 66 65  uct TestvfsBuffe
0470: 72 20 54 65 73 74 76 66 73 42 75 66 66 65 72 3b  r TestvfsBuffer;
0480: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0490: 54 65 73 74 76 66 73 46 69 6c 65 20 54 65 73 74  TestvfsFile Test
04a0: 76 66 73 46 69 6c 65 3b 0a 74 79 70 65 64 65 66  vfsFile;.typedef
04b0: 20 73 74 72 75 63 74 20 54 65 73 74 76 66 73 46   struct TestvfsF
04c0: 64 20 54 65 73 74 76 66 73 46 64 3b 0a 0a 2f 2a  d TestvfsFd;../*
04d0: 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 66 69 6c 65  .** An open file
04e0: 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 72 75   handle..*/.stru
04f0: 63 74 20 54 65 73 74 76 66 73 46 69 6c 65 20 7b  ct TestvfsFile {
0500: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
0510: 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  base;           
0520: 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73     /* Base class
0530: 2e 20 20 4d 75 73 74 20 62 65 20 66 69 72 73 74  .  Must be first
0540: 20 2a 2f 0a 20 20 54 65 73 74 76 66 73 46 64 20   */.  TestvfsFd 
0550: 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
0560: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 64 61        /* File da
0570: 74 61 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65  ta */.};.#define
0580: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
0590: 29 20 28 28 28 54 65 73 74 76 66 73 46 69 6c 65  ) (((TestvfsFile
05a0: 20 2a 29 70 46 69 6c 65 29 2d 3e 70 46 64 29 0a   *)pFile)->pFd).
05b0: 0a 73 74 72 75 63 74 20 54 65 73 74 76 66 73 46  .struct TestvfsF
05c0: 64 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  d {.  sqlite3_vf
05d0: 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20 20 20  s *pVfs;        
05e0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56 46 53        /* The VFS
05f0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
0600: 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20 20 20   *zFilename;    
0610: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 6e 61 6d        /* Filenam
0620: 65 20 61 73 20 70 61 73 73 65 64 20 74 6f 20 78  e as passed to x
0630: 4f 70 65 6e 28 29 20 2a 2f 0a 20 20 73 71 6c 69  Open() */.  sqli
0640: 74 65 33 5f 66 69 6c 65 20 2a 70 52 65 61 6c 3b  te3_file *pReal;
0650: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0660: 68 65 20 72 65 61 6c 2c 20 75 6e 64 65 72 6c 79  he real, underly
0670: 69 6e 67 20 66 69 6c 65 20 64 65 73 63 72 69 70  ing file descrip
0680: 74 6f 72 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a  tor */.  Tcl_Obj
0690: 20 2a 70 53 68 6d 49 64 3b 20 20 20 20 20 20 20   *pShmId;       
06a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 61 72           /* Shar
06b0: 65 64 20 6d 65 6d 6f 72 79 20 69 64 20 66 6f 72  ed memory id for
06c0: 20 54 63 6c 20 63 61 6c 6c 62 61 63 6b 73 20 2a   Tcl callbacks *
06d0: 2f 0a 0a 20 20 54 65 73 74 76 66 73 42 75 66 66  /..  TestvfsBuff
06e0: 65 72 20 2a 70 53 68 6d 3b 20 20 20 20 20 20 20  er *pShm;       
06f0: 20 20 20 20 20 2f 2a 20 53 68 61 72 65 64 20 6d       /* Shared m
0700: 65 6d 6f 72 79 20 62 75 66 66 65 72 20 2a 2f 0a  emory buffer */.
0710: 20 20 75 33 32 20 65 78 63 6c 6c 6f 63 6b 3b 20    u32 excllock; 
0720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0730: 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 65 78 63    /* Mask of exc
0740: 6c 75 73 69 76 65 20 6c 6f 63 6b 73 20 2a 2f 0a  lusive locks */.
0750: 20 20 75 33 32 20 73 68 61 72 65 64 6c 6f 63 6b    u32 sharedlock
0760: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0770: 20 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 73 68 61    /* Mask of sha
0780: 72 65 64 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20 54  red locks */.  T
0790: 65 73 74 76 66 73 46 64 20 2a 70 4e 65 78 74 3b  estvfsFd *pNext;
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
07b0: 2a 20 4e 65 78 74 20 68 61 6e 64 6c 65 20 6f 70  * Next handle op
07c0: 65 6e 65 64 20 6f 6e 20 74 68 65 20 73 61 6d 65  ened on the same
07d0: 20 66 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64   file */.};...#d
07e0: 65 66 69 6e 65 20 46 41 55 4c 54 5f 49 4e 4a 45  efine FAULT_INJE
07f0: 43 54 5f 4e 4f 4e 45 20 20 20 20 20 20 20 30 0a  CT_NONE       0.
0800: 23 64 65 66 69 6e 65 20 46 41 55 4c 54 5f 49 4e  #define FAULT_IN
0810: 4a 45 43 54 5f 54 52 41 4e 53 49 45 4e 54 20 20  JECT_TRANSIENT  
0820: 31 0a 23 64 65 66 69 6e 65 20 46 41 55 4c 54 5f  1.#define FAULT_
0830: 49 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e  INJECT_PERSISTEN
0840: 54 20 32 0a 0a 74 79 70 65 64 65 66 20 73 74 72  T 2..typedef str
0850: 75 63 74 20 54 65 73 74 46 61 75 6c 74 49 6e 6a  uct TestFaultInj
0860: 65 63 74 20 54 65 73 74 46 61 75 6c 74 49 6e 6a  ect TestFaultInj
0870: 65 63 74 3b 0a 73 74 72 75 63 74 20 54 65 73 74  ect;.struct Test
0880: 46 61 75 6c 74 49 6e 6a 65 63 74 20 7b 0a 20 20  FaultInject {.  
0890: 69 6e 74 20 69 43 6e 74 3b 20 20 20 20 20 20 20  int iCnt;       
08a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08b0: 2f 2a 20 52 65 6d 61 69 6e 69 6e 67 20 63 61 6c  /* Remaining cal
08c0: 6c 73 20 62 65 66 6f 72 65 20 66 61 75 6c 74 20  ls before fault 
08d0: 69 6e 6a 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69  injection */.  i
08e0: 6e 74 20 65 46 61 75 6c 74 3b 20 20 20 20 20 20  nt eFault;      
08f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0900: 2a 20 41 20 46 41 55 4c 54 5f 49 4e 4a 45 43 54  * A FAULT_INJECT
0910: 5f 2a 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e  _* value */.  in
0920: 74 20 6e 46 61 69 6c 3b 20 20 20 20 20 20 20 20  t nFail;        
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0940: 20 4e 75 6d 62 65 72 20 6f 66 20 66 61 75 6c 74   Number of fault
0950: 73 20 69 6e 6a 65 63 74 65 64 20 2a 2f 0a 7d 3b  s injected */.};
0960: 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61  ../*.** An insta
0970: 6e 63 65 20 6f 66 20 74 68 69 73 20 73 74 72 75  nce of this stru
0980: 63 74 75 72 65 20 69 73 20 61 6c 6c 6f 63 61 74  cture is allocat
0990: 65 64 20 66 6f 72 20 65 61 63 68 20 56 46 53 20  ed for each VFS 
09a0: 63 72 65 61 74 65 64 2e 20 54 68 65 0a 2a 2a 20  created. The.** 
09b0: 73 71 6c 69 74 65 33 5f 76 66 73 2e 70 41 70 70  sqlite3_vfs.pApp
09c0: 44 61 74 61 20 66 69 65 6c 64 20 6f 66 20 74 68  Data field of th
09d0: 65 20 56 46 53 20 73 74 72 75 63 74 75 72 65 20  e VFS structure 
09e0: 72 65 67 69 73 74 65 72 65 64 20 77 69 74 68 20  registered with 
09f0: 53 51 4c 69 74 65 0a 2a 2a 20 69 73 20 73 65 74  SQLite.** is set
0a00: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 69 74 2e   to point to it.
0a10: 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73 74 76  .*/.struct Testv
0a20: 66 73 20 7b 0a 20 20 63 68 61 72 20 2a 7a 4e 61  fs {.  char *zNa
0a30: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
0a40: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
0a50: 66 20 74 68 69 73 20 56 46 53 20 2a 2f 0a 20 20  f this VFS */.  
0a60: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 50 61  sqlite3_vfs *pPa
0a70: 72 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20  rent;           
0a80: 2f 2a 20 54 68 65 20 56 46 53 20 74 6f 20 75 73  /* The VFS to us
0a90: 65 20 66 6f 72 20 66 69 6c 65 20 49 4f 20 2a 2f  e for file IO */
0aa0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
0ab0: 70 56 66 73 3b 20 20 20 20 20 20 20 20 20 20 20  pVfs;           
0ac0: 20 20 20 2f 2a 20 54 68 65 20 74 65 73 74 76 66     /* The testvf
0ad0: 73 20 72 65 67 69 73 74 65 72 65 64 20 77 69 74  s registered wit
0ae0: 68 20 53 51 4c 69 74 65 20 2a 2f 0a 20 20 54 63  h SQLite */.  Tc
0af0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
0b00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
0b10: 20 49 6e 74 65 72 70 72 65 74 65 72 20 74 6f 20   Interpreter to 
0b20: 72 75 6e 20 73 63 72 69 70 74 20 69 6e 20 2a 2f  run script in */
0b30: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72  .  Tcl_Obj *pScr
0b40: 69 70 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ipt;            
0b50: 20 20 20 2f 2a 20 53 63 72 69 70 74 20 74 6f 20     /* Script to 
0b60: 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74  execute */.  int
0b70: 20 6e 53 63 72 69 70 74 3b 20 20 20 20 20 20 20   nScript;       
0b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0b90: 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e  Number of elemen
0ba0: 74 73 20 69 6e 20 61 72 72 61 79 20 61 70 53 63  ts in array apSc
0bb0: 72 69 70 74 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  ript */.  Tcl_Ob
0bc0: 6a 20 2a 2a 61 70 53 63 72 69 70 74 3b 20 20 20  j **apScript;   
0bd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
0be0: 61 79 20 76 65 72 73 69 6f 6e 20 6f 66 20 70 53  ay version of pS
0bf0: 63 72 69 70 74 20 2a 2f 0a 20 20 54 65 73 74 76  cript */.  Testv
0c00: 66 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65  fsBuffer *pBuffe
0c10: 72 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69  r;         /* Li
0c20: 73 74 20 6f 66 20 73 68 61 72 65 64 20 62 75 66  st of shared buf
0c30: 66 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20 69 73  fers */.  int is
0c40: 4e 6f 73 68 6d 3b 0a 0a 20 20 69 6e 74 20 6d 61  Noshm;..  int ma
0c50: 73 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sk;             
0c60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 73            /* Mas
0c70: 6b 20 63 6f 6e 74 72 6f 6c 6c 69 6e 67 20 5b 73  k controlling [s
0c80: 63 72 69 70 74 5d 20 61 6e 64 20 5b 69 6f 65 72  cript] and [ioer
0c90: 72 5d 20 2a 2f 0a 0a 20 20 54 65 73 74 46 61 75  r] */..  TestFau
0ca0: 6c 74 49 6e 6a 65 63 74 20 69 6f 65 72 72 5f 65  ltInject ioerr_e
0cb0: 72 72 3b 0a 20 20 54 65 73 74 46 61 75 6c 74 49  rr;.  TestFaultI
0cc0: 6e 6a 65 63 74 20 66 75 6c 6c 5f 65 72 72 3b 0a  nject full_err;.
0cd0: 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63    TestFaultInjec
0ce0: 74 20 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 0a  t cantopen_err;.
0cf0: 0a 23 69 66 20 30 0a 20 20 69 6e 74 20 69 49 6f  .#if 0.  int iIo
0d00: 65 72 72 43 6e 74 3b 0a 20 20 69 6e 74 20 69 6f  errCnt;.  int io
0d10: 65 72 72 3b 0a 20 20 69 6e 74 20 6e 49 6f 65 72  err;.  int nIoer
0d20: 72 46 61 69 6c 3b 0a 20 20 69 6e 74 20 69 46 75  rFail;.  int iFu
0d30: 6c 6c 43 6e 74 3b 0a 20 20 69 6e 74 20 66 75 6c  llCnt;.  int ful
0d40: 6c 65 72 72 3b 0a 20 20 69 6e 74 20 6e 46 75 6c  lerr;.  int nFul
0d50: 6c 46 61 69 6c 3b 0a 23 65 6e 64 69 66 0a 0a 20  lFail;.#endif.. 
0d60: 20 69 6e 74 20 69 44 65 76 63 68 61 72 3b 0a 20   int iDevchar;. 
0d70: 20 69 6e 74 20 69 53 65 63 74 6f 72 73 69 7a 65   int iSectorsize
0d80: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  ;.};../*.** The 
0d90: 54 65 73 74 76 66 73 2e 6d 61 73 6b 20 76 61 72  Testvfs.mask var
0da0: 69 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20  iable is set to 
0db0: 61 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 20 6f 66  a combination of
0dc0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 2e 0a   the following..
0dd0: 2a 2a 20 49 66 20 61 20 62 69 74 20 69 73 20 63  ** If a bit is c
0de0: 6c 65 61 72 20 69 6e 20 54 65 73 74 76 66 73 2e  lear in Testvfs.
0df0: 6d 61 73 6b 2c 20 74 68 65 6e 20 63 61 6c 6c 73  mask, then calls
0e00: 20 6d 61 64 65 20 62 79 20 53 51 4c 69 74 65 20   made by SQLite 
0e10: 74 6f 20 74 68 65 20 0a 2a 2a 20 63 6f 72 72 65  to the .** corre
0e20: 73 70 6f 6e 64 69 6e 67 20 56 46 53 20 6d 65 74  sponding VFS met
0e30: 68 6f 64 20 69 73 20 69 67 6e 6f 72 65 64 20 66  hod is ignored f
0e40: 6f 72 20 70 75 72 70 6f 73 65 73 20 6f 66 3a 0a  or purposes of:.
0e50: 2a 2a 0a 2a 2a 20 20 20 2b 20 53 69 6d 75 6c 61  **.**   + Simula
0e60: 74 69 6e 67 20 49 4f 20 65 72 72 6f 72 73 2c 20  ting IO errors, 
0e70: 61 6e 64 0a 2a 2a 20 20 20 2b 20 49 6e 76 6f 6b  and.**   + Invok
0e80: 69 6e 67 20 74 68 65 20 54 63 6c 20 63 61 6c 6c  ing the Tcl call
0e90: 62 61 63 6b 20 73 63 72 69 70 74 2e 0a 2a 2f 0a  back script..*/.
0ea0: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
0eb0: 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 20 20 20  SHMOPEN_MASK    
0ec0: 30 78 30 30 30 30 30 30 30 31 0a 23 64 65 66 69  0x00000001.#defi
0ed0: 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f  ne TESTVFS_SHMLO
0ee0: 43 4b 5f 4d 41 53 4b 20 20 20 20 30 78 30 30 30  CK_MASK    0x000
0ef0: 30 30 30 31 30 0a 23 64 65 66 69 6e 65 20 54 45  00010.#define TE
0f00: 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53  STVFS_SHMMAP_MAS
0f10: 4b 20 20 20 20 20 30 78 30 30 30 30 30 30 32 30  K     0x00000020
0f20: 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53  .#define TESTVFS
0f30: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
0f40: 20 30 78 30 30 30 30 30 30 34 30 0a 23 64 65 66   0x00000040.#def
0f50: 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d 43  ine TESTVFS_SHMC
0f60: 4c 4f 53 45 5f 4d 41 53 4b 20 20 20 30 78 30 30  LOSE_MASK   0x00
0f70: 30 30 30 30 38 30 0a 0a 23 64 65 66 69 6e 65 20  000080..#define 
0f80: 54 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53  TESTVFS_OPEN_MAS
0f90: 4b 20 20 20 20 20 20 20 30 78 30 30 30 30 30 31  K       0x000001
0fa0: 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  00.#define TESTV
0fb0: 46 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 20 20 20  FS_SYNC_MASK    
0fc0: 20 20 20 30 78 30 30 30 30 30 32 30 30 0a 23 64     0x00000200.#d
0fd0: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 44 45  efine TESTVFS_DE
0fe0: 4c 45 54 45 5f 4d 41 53 4b 20 20 20 20 20 30 78  LETE_MASK     0x
0ff0: 30 30 30 30 30 34 30 30 0a 23 64 65 66 69 6e 65  00000400.#define
1000: 20 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d   TESTVFS_CLOSE_M
1010: 41 53 4b 20 20 20 20 20 20 30 78 30 30 30 30 30  ASK      0x00000
1020: 38 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54  800.#define TEST
1030: 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 20  VFS_WRITE_MASK  
1040: 20 20 20 20 30 78 30 30 30 30 31 30 30 30 0a 23      0x00001000.#
1050: 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 54  define TESTVFS_T
1060: 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 20 20 30  RUNCATE_MASK   0
1070: 78 30 30 30 30 32 30 30 30 0a 23 64 65 66 69 6e  x00002000.#defin
1080: 65 20 54 45 53 54 56 46 53 5f 41 43 43 45 53 53  e TESTVFS_ACCESS
1090: 5f 4d 41 53 4b 20 20 20 20 20 30 78 30 30 30 30  _MASK     0x0000
10a0: 34 30 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53  4000.#define TES
10b0: 54 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20 20 20  TVFS_ALL_MASK   
10c0: 20 20 20 20 20 30 78 30 30 30 30 37 46 46 46 0a       0x00007FFF.
10d0: 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  ..#define TESTVF
10e0: 53 5f 4d 41 58 5f 50 41 47 45 53 20 31 30 32 34  S_MAX_PAGES 1024
10f0: 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72 65 64  ../*.** A shared
1100: 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72 2e 20  -memory buffer. 
1110: 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f 66 20  There is one of 
1120: 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20 66 6f  these objects fo
1130: 72 20 65 61 63 68 20 73 68 61 72 65 64 0a 2a 2a  r each shared.**
1140: 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20 6f   memory region o
1150: 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e 74 73  pened by clients
1160: 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e 74 73  . If two clients
1170: 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65 20 66   open the same f
1180: 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20 61 72  ile,.** there ar
1190: 65 20 74 77 6f 20 54 65 73 74 76 66 73 46 69 6c  e two TestvfsFil
11a0: 65 20 73 74 72 75 63 74 75 72 65 73 20 62 75 74  e structures but
11b0: 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74 76 66   only one Testvf
11c0: 73 42 75 66 66 65 72 20 73 74 72 75 63 74 75 72  sBuffer structur
11d0: 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54 65 73  e..*/.struct Tes
11e0: 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20 20 63  tvfsBuffer {.  c
11f0: 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20 20 20  har *zFile;     
1200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1210: 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66 69 6c  * Associated fil
1220: 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20  e name */.  int 
1230: 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20  pgsz;           
1240: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1250: 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 75 38  age size */.  u8
1260: 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46 53 5f   *aPage[TESTVFS_
1270: 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20 2f 2a  MAX_PAGES];   /*
1280: 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c 6c 6f   Array of ckallo
1290: 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 54  c'd pages */.  T
12a0: 65 73 74 76 66 73 46 64 20 2a 70 46 69 6c 65 3b  estvfsFd *pFile;
12b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12c0: 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e 20 68  * List of open h
12d0: 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65 73 74  andles */.  Test
12e0: 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65 78 74  vfsBuffer *pNext
12f0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
1300: 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c 69  ext in linked li
1310: 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66 65 72  st of all buffer
1320: 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66 69 6e  s */.};...#defin
1330: 65 20 50 41 52 45 4e 54 56 46 53 28 78 29 20 28  e PARENTVFS(x) (
1340: 28 28 54 65 73 74 76 66 73 20 2a 29 28 28 78 29  ((Testvfs *)((x)
1350: 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e 70 50  ->pAppData))->pP
1360: 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e 65 20  arent)..#define 
1370: 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52 47 53  TESTVFS_MAX_ARGS
1380: 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68   12.../*.** Meth
1390: 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20  od declarations 
13a0: 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c 65 2e  for TestvfsFile.
13b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
13c0: 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  vfsClose(sqlite3
13d0: 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20  _file*);.static 
13e0: 69 6e 74 20 74 76 66 73 52 65 61 64 28 73 71 6c  int tvfsRead(sql
13f0: 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f 69 64  ite3_file*, void
1400: 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c  *, int iAmt, sql
1410: 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74  ite3_int64 iOfst
1420: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1430: 66 73 57 72 69 74 65 28 73 71 6c 69 74 65 33 5f  fsWrite(sqlite3_
1440: 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f 69 64  file*,const void
1450: 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71 6c 69  *,int iAmt, sqli
1460: 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73 74 29  te3_int64 iOfst)
1470: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ;.static int tvf
1480: 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  sTruncate(sqlite
1490: 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74 65 33  3_file*, sqlite3
14a0: 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a 73 74  _int64 size);.st
14b0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 79 6e  atic int tvfsSyn
14c0: 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  c(sqlite3_file*,
14d0: 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74 61   int flags);.sta
14e0: 74 69 63 20 69 6e 74 20 74 76 66 73 46 69 6c 65  tic int tvfsFile
14f0: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
1500: 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  e*, sqlite3_int6
1510: 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61 74 69  4 *pSize);.stati
1520: 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b 28 73  c int tvfsLock(s
1530: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e  qlite3_file*, in
1540: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
1550: 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74 65  vfsUnlock(sqlite
1560: 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a 73  3_file*, int);.s
1570: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 43 68  tatic int tvfsCh
1580: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28  eckReservedLock(
1590: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69  sqlite3_file*, i
15a0: 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  nt *);.static in
15b0: 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74 72 6f  t tvfsFileContro
15c0: 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  l(sqlite3_file*,
15d0: 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70   int op, void *p
15e0: 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  Arg);.static int
15f0: 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 28   tvfsSectorSize(
1600: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a  sqlite3_file*);.
1610: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44  static int tvfsD
1620: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
1630: 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69 6c  tics(sqlite3_fil
1640: 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68  e*);../*.** Meth
1650: 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20  od declarations 
1660: 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a 2a 2f  for tvfs_vfs..*/
1670: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
1680: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73  Open(sqlite3_vfs
1690: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2c  *, const char *,
16a0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20   sqlite3_file*, 
16b0: 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  int , int *);.st
16c0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65 6c  atic int tvfsDel
16d0: 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  ete(sqlite3_vfs*
16e0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
16f0: 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69 72  ame, int syncDir
1700: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1710: 66 73 41 63 63 65 73 73 28 73 71 6c 69 74 65 33  fsAccess(sqlite3
1720: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
1730: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66 6c  r *zName, int fl
1740: 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74 61  ags, int *);.sta
1750: 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c  tic int tvfsFull
1760: 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65 33  Pathname(sqlite3
1770: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
1780: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20 63  r *zName, int, c
1790: 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69 66 6e  har *zOut);.#ifn
17a0: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
17b0: 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a 73  LOAD_EXTENSION.s
17c0: 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76 66 73  tatic void *tvfs
17d0: 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76  DlOpen(sqlite3_v
17e0: 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  fs*, const char 
17f0: 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73 74 61  *zFilename);.sta
1800: 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c 45  tic void tvfsDlE
1810: 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66 73  rror(sqlite3_vfs
1820: 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68  *, int nByte, ch
1830: 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a 73 74  ar *zErrMsg);.st
1840: 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76 66 73  atic void (*tvfs
1850: 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f 76 66  DlSym(sqlite3_vf
1860: 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20  s*,void*, const 
1870: 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29 29 28  char *zSymbol))(
1880: 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76 6f  void);.static vo
1890: 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65 28 73  id tvfsDlClose(s
18a0: 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f 69  qlite3_vfs*, voi
18b0: 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20 53  d*);.#endif /* S
18c0: 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f  QLITE_OMIT_LOAD_
18d0: 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73 74 61  EXTENSION */.sta
18e0: 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e 64  tic int tvfsRand
18f0: 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f 76  omness(sqlite3_v
1900: 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20  fs*, int nByte, 
1910: 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74 61  char *zOut);.sta
1920: 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c 65 65  tic int tvfsSlee
1930: 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20  p(sqlite3_vfs*, 
1940: 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73  int microseconds
1950: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  );.static int tv
1960: 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71  fsCurrentTime(sq
1970: 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f 75 62  lite3_vfs*, doub
1980: 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20 69 6e  le*);..static in
1990: 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 73 71  t tvfsShmOpen(sq
19a0: 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a 73 74  lite3_file*);.st
19b0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
19c0: 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c  Lock(sqlite3_fil
19d0: 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 2c 20 69  e*, int , int, i
19e0: 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  nt);.static int 
19f0: 74 76 66 73 53 68 6d 4d 61 70 28 73 71 6c 69 74  tvfsShmMap(sqlit
1a00: 65 33 5f 66 69 6c 65 2a 2c 69 6e 74 2c 69 6e 74  e3_file*,int,int
1a10: 2c 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c 61 74  ,int, void volat
1a20: 69 6c 65 20 2a 2a 29 3b 0a 73 74 61 74 69 63 20  ile **);.static 
1a30: 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61 72 72  void tvfsShmBarr
1a40: 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ier(sqlite3_file
1a50: 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  *);.static int t
1a60: 76 66 73 53 68 6d 43 6c 6f 73 65 28 73 71 6c 69  vfsShmClose(sqli
1a70: 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b  te3_file*, int);
1a80: 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33  ..static sqlite3
1a90: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 74 76 66 73  _io_methods tvfs
1aa0: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 3d 20 7b 0a  _io_methods = {.
1ab0: 20 20 32 2c 20 20 20 20 20 20 20 20 20 20 20 20    2,            
1ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ad0: 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f    /* iVersion */
1ae0: 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20 20 20  .  tvfsClose,   
1af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b00: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a 2f 0a     /* xClose */.
1b10: 20 20 74 76 66 73 52 65 61 64 2c 20 20 20 20 20    tvfsRead,     
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b30: 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a 20 20    /* xRead */.  
1b40: 74 76 66 73 57 72 69 74 65 2c 20 20 20 20 20 20  tvfsWrite,      
1b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b60: 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20 20 74  /* xWrite */.  t
1b70: 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20 20 20  vfsTruncate,    
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b90: 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20  * xTruncate */. 
1ba0: 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20 20 20   tvfsSync,      
1bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bc0: 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 74   /* xSync */.  t
1bd0: 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20 20 20  vfsFileSize,    
1be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bf0: 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f 0a 20  * xFileSize */. 
1c00: 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20 20 20   tvfsLock,      
1c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c20: 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20 20 74   /* xLock */.  t
1c30: 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20 20 20  vfsUnlock,      
1c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1c50: 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20 20 74  * xUnlock */.  t
1c60: 76 66 73 43 68 65 63 6b 52 65 73 65 72 76 65 64  vfsCheckReserved
1c70: 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 2f  Lock,          /
1c80: 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76 65 64  * xCheckReserved
1c90: 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73 46 69  Lock */.  tvfsFi
1ca0: 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20 20 20  leControl,      
1cb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69            /* xFi
1cc0: 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20 20 74  leControl */.  t
1cd0: 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c 20 20  vfsSectorSize,  
1ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1cf0: 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20 2a 2f  * xSectorSize */
1d00: 0a 20 20 74 76 66 73 44 65 76 69 63 65 43 68 61  .  tvfsDeviceCha
1d10: 72 61 63 74 65 72 69 73 74 69 63 73 2c 20 20 20  racteristics,   
1d20: 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43 68 61     /* xDeviceCha
1d30: 72 61 63 74 65 72 69 73 74 69 63 73 20 2a 2f 0a  racteristics */.
1d40: 20 20 74 76 66 73 53 68 6d 4f 70 65 6e 2c 20 20    tvfsShmOpen,  
1d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d60: 20 20 2f 2a 20 78 53 68 6d 4f 70 65 6e 20 2a 2f    /* xShmOpen */
1d70: 0a 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c 20  .  tvfsShmLock, 
1d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d90: 20 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a     /* xShmLock *
1da0: 2f 0a 20 20 74 76 66 73 53 68 6d 4d 61 70 2c 20  /.  tvfsShmMap, 
1db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1dc0: 20 20 20 20 2f 2a 20 78 53 68 6d 4d 61 70 20 2a      /* xShmMap *
1dd0: 2f 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72 69  /.  tvfsShmBarri
1de0: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
1df0: 20 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69      /* xShmBarri
1e00: 65 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 43  er */.  tvfsShmC
1e10: 6c 6f 73 65 20 20 20 20 20 20 20 20 20 20 20 20  lose            
1e20: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 43          /* xShmC
1e30: 6c 6f 73 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74  lose */.};..stat
1e40: 69 63 20 69 6e 74 20 74 76 66 73 52 65 73 75 6c  ic int tvfsResul
1e50: 74 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a 70  tCode(Testvfs *p
1e60: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 73  , int *pRc){.  s
1e70: 74 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b 0a  truct errcode {.
1e80: 20 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a 20      int eCode;. 
1e90: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
1ea0: 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65 5b  Code;.  } aCode[
1eb0: 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c 49  ] = {.    { SQLI
1ec0: 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c 49  TE_OK,     "SQLI
1ed0: 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20 20  TE_OK"     },.  
1ee0: 20 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f 52    { SQLITE_ERROR
1ef0: 2c 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52  ,  "SQLITE_ERROR
1f00: 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  "  },.    { SQLI
1f10: 54 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c 49  TE_IOERR,  "SQLI
1f20: 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20 20  TE_IOERR"  },.  
1f30: 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45    { SQLITE_LOCKE
1f40: 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b 45  D, "SQLITE_LOCKE
1f50: 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49  D" },.    { SQLI
1f60: 54 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c 49  TE_BUSY,   "SQLI
1f70: 54 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20 20  TE_BUSY"   },.  
1f80: 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  };..  const char
1f90: 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20   *z;.  int i;.. 
1fa0: 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69   z = Tcl_GetStri
1fb0: 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  ngResult(p->inte
1fc0: 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  rp);.  for(i=0; 
1fd0: 69 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f 64  i<ArraySize(aCod
1fe0: 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  e); i++){.    if
1ff0: 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 61  ( 0==strcmp(z, a
2000: 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20 29  Code[i].zCode) )
2010: 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 61  {.      *pRc = a
2020: 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a 20  Code[i].eCode;. 
2030: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
2040: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
2050: 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 0;.}..static 
2060: 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 61  int tvfsInjectFa
2070: 75 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e 6a  ult(TestFaultInj
2080: 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ect *p){.  int r
2090: 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d  et = 0;.  if( p-
20a0: 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20 70  >eFault ){.    p
20b0: 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69 66  ->iCnt--;.    if
20c0: 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c 20  ( p->iCnt==0 || 
20d0: 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70 2d  (p->iCnt<0 && p-
20e0: 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f 49  >eFault==FAULT_I
20f0: 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e 54  NJECT_PERSISTENT
2100: 20 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20   ) ){.      ret 
2110: 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46  = 1;.      p->nF
2120: 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  ail++;.    }.  }
2130: 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d  .  return ret;.}
2140: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  ...static int tv
2150: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54 65  fsInjectIoerr(Te
2160: 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74  stvfs *p){.  ret
2170: 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61  urn tvfsInjectFa
2180: 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65 72  ult(&p->ioerr_er
2190: 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  r);.}..static in
21a0: 74 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c  t tvfsInjectFull
21b0: 65 72 72 28 54 65 73 74 76 66 73 20 2a 70 29 7b  err(Testvfs *p){
21c0: 0a 20 20 72 65 74 75 72 6e 20 74 76 66 73 49 6e  .  return tvfsIn
21d0: 6a 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66 75  jectFault(&p->fu
21e0: 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74 69  ll_err);.}.stati
21f0: 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74  c int tvfsInject
2200: 43 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73 74  Cantopenerr(Test
2210: 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  vfs *p){.  retur
2220: 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75 6c  n tvfsInjectFaul
2230: 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65  t(&p->cantopen_e
2240: 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20  rr);.}...static 
2250: 76 6f 69 64 20 74 76 66 73 45 78 65 63 54 63 6c  void tvfsExecTcl
2260: 28 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c 20  (.  Testvfs *p, 
2270: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2280: 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f 62  Method,.  Tcl_Ob
2290: 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f 4f  j *arg1,.  Tcl_O
22a0: 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c 5f  bj *arg2,.  Tcl_
22b0: 4f 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20 69  Obj *arg3.){.  i
22c0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
22d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
22e0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72  * Return code fr
22f0: 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28 29  om Tcl_EvalObj()
2300: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 3b 20   */.  int nArg; 
2310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2320: 20 20 20 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74        /* Element
2330: 73 20 69 6e 20 65 76 61 6c 27 64 20 6c 69 73 74  s in eval'd list
2340: 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70   */.  int nScrip
2350: 74 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 20  t;.  Tcl_Obj ** 
2360: 61 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  ap;..  assert( p
2370: 2d 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a 20 20  ->pScript );..  
2380: 69 66 28 20 21 70 2d 3e 61 70 53 63 72 69 70 74  if( !p->apScript
2390: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   ){.    int nByt
23a0: 65 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  e;.    int i;.  
23b0: 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63    if( TCL_OK!=Tc
23c0: 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d  l_ListObjGetElem
23d0: 65 6e 74 73 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ents(p->interp, 
23e0: 70 2d 3e 70 53 63 72 69 70 74 2c 20 26 6e 53 63  p->pScript, &nSc
23f0: 72 69 70 74 2c 20 26 61 70 29 20 29 7b 0a 20 20  ript, &ap) ){.  
2400: 20 20 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75      Tcl_Backgrou
2410: 6e 64 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72  ndError(p->inter
2420: 70 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 52 65  p);.      Tcl_Re
2430: 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  setResult(p->int
2440: 65 72 70 29 3b 0a 20 20 20 20 20 20 72 65 74 75  erp);.      retu
2450: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d  rn;.    }.    p-
2460: 3e 6e 53 63 72 69 70 74 20 3d 20 6e 53 63 72 69  >nScript = nScri
2470: 70 74 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20  pt;.    nByte = 
2480: 28 6e 53 63 72 69 70 74 2b 54 45 53 54 56 46 53  (nScript+TESTVFS
2490: 5f 4d 41 58 5f 41 52 47 53 29 2a 73 69 7a 65 6f  _MAX_ARGS)*sizeo
24a0: 66 28 54 63 6c 5f 4f 62 6a 20 2a 29 3b 0a 20 20  f(Tcl_Obj *);.  
24b0: 20 20 70 2d 3e 61 70 53 63 72 69 70 74 20 3d 20    p->apScript = 
24c0: 28 54 63 6c 5f 4f 62 6a 20 2a 2a 29 63 6b 61 6c  (Tcl_Obj **)ckal
24d0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
24e0: 6d 65 6d 73 65 74 28 70 2d 3e 61 70 53 63 72 69  memset(p->apScri
24f0: 70 74 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  pt, 0, nByte);. 
2500: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53     for(i=0; i<nS
2510: 63 72 69 70 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  cript; i++){.   
2520: 20 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 69     p->apScript[i
2530: 5d 20 3d 20 61 70 5b 69 5d 3b 0a 20 20 20 20 7d  ] = ap[i];.    }
2540: 0a 20 20 7d 0a 0a 20 20 70 2d 3e 61 70 53 63 72  .  }..  p->apScr
2550: 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 5d 20  ipt[p->nScript] 
2560: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
2570: 62 6a 28 7a 4d 65 74 68 6f 64 2c 20 2d 31 29 3b  bj(zMethod, -1);
2580: 0a 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 70  .  p->apScript[p
2590: 2d 3e 6e 53 63 72 69 70 74 2b 31 5d 20 3d 20 61  ->nScript+1] = a
25a0: 72 67 31 3b 0a 20 20 70 2d 3e 61 70 53 63 72 69  rg1;.  p->apScri
25b0: 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 2b 32 5d  pt[p->nScript+2]
25c0: 20 3d 20 61 72 67 32 3b 0a 20 20 70 2d 3e 61 70   = arg2;.  p->ap
25d0: 53 63 72 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70  Script[p->nScrip
25e0: 74 2b 33 5d 20 3d 20 61 72 67 33 3b 0a 0a 20 20  t+3] = arg3;..  
25f0: 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53 63 72  for(nArg=p->nScr
2600: 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69 70 74  ipt; p->apScript
2610: 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b 29 7b  [nArg]; nArg++){
2620: 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  .    Tcl_IncrRef
2630: 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72 69 70  Count(p->apScrip
2640: 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 7d 0a 0a 20  t[nArg]);.  }.. 
2650: 20 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62   rc = Tcl_EvalOb
2660: 6a 76 28 70 2d 3e 69 6e 74 65 72 70 2c 20 6e 41  jv(p->interp, nA
2670: 72 67 2c 20 70 2d 3e 61 70 53 63 72 69 70 74 2c  rg, p->apScript,
2680: 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c   TCL_EVAL_GLOBAL
2690: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c  );.  if( rc!=TCL
26a0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42  _OK ){.    Tcl_B
26b0: 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70  ackgroundError(p
26c0: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54  ->interp);.    T
26d0: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70  cl_ResetResult(p
26e0: 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 0a  ->interp);.  }..
26f0: 20 20 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53    for(nArg=p->nS
2700: 63 72 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69  cript; p->apScri
2710: 70 74 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b  pt[nArg]; nArg++
2720: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2730: 65 66 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72  efCount(p->apScr
2740: 69 70 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 20 20  ipt[nArg]);.    
2750: 70 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67  p->apScript[nArg
2760: 5d 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f  ] = 0;.  }.}.../
2770: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 74 76  *.** Close an tv
2780: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
2790: 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f 73 65  ic int tvfsClose
27a0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
27b0: 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b  File){.  int rc;
27c0: 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a  .  TestvfsFile *
27d0: 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73  pTestfile = (Tes
27e0: 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65  tvfsFile *)pFile
27f0: 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70  ;.  TestvfsFd *p
2800: 46 64 20 3d 20 70 54 65 73 74 66 69 6c 65 2d 3e  Fd = pTestfile->
2810: 70 46 64 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  pFd;.  Testvfs *
2820: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
2830: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
2840: 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  ta;..  if( p->pS
2850: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
2860: 26 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d  &TESTVFS_CLOSE_M
2870: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
2880: 78 65 63 54 63 6c 28 70 2c 20 22 78 43 6c 6f 73  xecTcl(p, "xClos
2890: 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c  e", .        Tcl
28a0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
28b0: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
28c0: 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20  ), pFd->pShmId, 
28d0: 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20  0.    );.  }..  
28e0: 69 66 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20  if( pFd->pShmId 
28f0: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52  ){.    Tcl_DecrR
2900: 65 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70 53 68  efCount(pFd->pSh
2910: 6d 49 64 29 3b 0a 20 20 20 20 70 46 64 2d 3e 70  mId);.    pFd->p
2920: 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  ShmId = 0;.  }. 
2930: 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d 65 74   if( pFile->pMet
2940: 68 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b 66 72  hods ){.    ckfr
2950: 65 65 28 28 63 68 61 72 20 2a 29 70 46 69 6c 65  ee((char *)pFile
2960: 2d 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20 20 7d  ->pMethods);.  }
2970: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
2980: 73 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52 65 61  sClose(pFd->pRea
2990: 6c 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68  l);.  ckfree((ch
29a0: 61 72 20 2a 29 70 46 64 29 3b 0a 20 20 70 54 65  ar *)pFd);.  pTe
29b0: 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 30 3b  stfile->pFd = 0;
29c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
29d0: 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61 74 61  ./*.** Read data
29e0: 20 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d 66 69   from an tvfs-fi
29f0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2a00: 74 20 74 76 66 73 52 65 61 64 28 0a 20 20 73 71  t tvfsRead(.  sq
2a10: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
2a20: 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42 75 66  e, .  void *zBuf
2a30: 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 0a  , .  int iAmt, .
2a40: 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69    sqlite_int64 i
2a50: 4f 66 73 74 0a 29 7b 0a 20 20 54 65 73 74 76 66  Ofst.){.  Testvf
2a60: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
2a70: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
2a80: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61  urn sqlite3OsRea
2a90: 64 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66  d(p->pReal, zBuf
2aa0: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
2ab0: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64  }../*.** Write d
2ac0: 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73 2d 66  ata to an tvfs-f
2ad0: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
2ae0: 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a 20 20  nt tvfsWrite(.  
2af0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2b00: 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 76 6f  ile, .  const vo
2b10: 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74  id *zBuf, .  int
2b20: 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65   iAmt, .  sqlite
2b30: 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a  _int64 iOfst.){.
2b40: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2b50: 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46  E_OK;.  TestvfsF
2b60: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
2b70: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
2b80: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
2b90: 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e  fs *)pFd->pVfs->
2ba0: 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28  pAppData;..  if(
2bb0: 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70   p->pScript && p
2bc0: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 57  ->mask&TESTVFS_W
2bd0: 52 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  RITE_MASK ){.   
2be0: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
2bf0: 22 78 57 72 69 74 65 22 2c 20 0a 20 20 20 20 20  "xWrite", .     
2c00: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
2c10: 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61  Obj(pFd->zFilena
2c20: 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53  me, -1), pFd->pS
2c30: 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20  hmId, 0.    );. 
2c40: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
2c50: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  e(p, &rc);.  }..
2c60: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2c70: 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63  _OK && tvfsInjec
2c80: 74 46 75 6c 6c 65 72 72 28 70 29 20 29 7b 0a 20  tFullerr(p) ){. 
2c90: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46     rc = SQLITE_F
2ca0: 55 4c 4c 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  ULL;.  }.  if( r
2cb0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
2cc0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
2cd0: 57 52 49 54 45 5f 4d 41 53 4b 20 26 26 20 74 76  WRITE_MASK && tv
2ce0: 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29  fsInjectIoerr(p)
2cf0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
2d00: 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 20  ITE_IOERR;.  }. 
2d10: 20 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49   .  if( rc==SQLI
2d20: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
2d30: 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
2d40: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a 42 75  (pFd->pReal, zBu
2d50: 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b  f, iAmt, iOfst);
2d60: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
2d70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63  ;.}../*.** Trunc
2d80: 61 74 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ate an tvfs-file
2d90: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2da0: 74 76 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c  tvfsTruncate(sql
2db0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
2dc0: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 73  , sqlite_int64 s
2dd0: 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  ize){.  int rc =
2de0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65   SQLITE_OK;.  Te
2df0: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
2e00: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
2e10: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
2e20: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
2e30: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
2e40: 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70  .  if( p->pScrip
2e50: 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53  t && p->mask&TES
2e60: 54 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41  TVFS_TRUNCATE_MA
2e70: 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78  SK ){.    tvfsEx
2e80: 65 63 54 63 6c 28 70 2c 20 22 78 54 72 75 6e 63  ecTcl(p, "xTrunc
2e90: 61 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ate", .        T
2ea0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2eb0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
2ec0: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
2ed0: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74  , 0.    );.    t
2ee0: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
2ef0: 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 0a 20 20   &rc);.  }.  .  
2f00: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2f10: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
2f20: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
2f30: 70 46 64 2d 3e 70 52 65 61 6c 2c 20 73 69 7a 65  pFd->pReal, size
2f40: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
2f50: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e  rc;.}../*.** Syn
2f60: 63 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  c an tvfs-file..
2f70: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
2f80: 66 73 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 66  fsSync(sqlite3_f
2f90: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
2fa0: 66 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20 72 63  flags){.  int rc
2fb0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
2fc0: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
2fd0: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
2fe0: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
2ff0: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
3000: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
3010: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
3020: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
3030: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
3040: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46   ){.    char *zF
3050: 6c 61 67 73 3b 0a 0a 20 20 20 20 73 77 69 74 63  lags;..    switc
3060: 68 28 20 66 6c 61 67 73 20 29 7b 0a 20 20 20 20  h( flags ){.    
3070: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59    case SQLITE_SY
3080: 4e 43 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20 20 20  NC_NORMAL:.     
3090: 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72     zFlags = "nor
30a0: 6d 61 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72  mal";.        br
30b0: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
30c0: 53 51 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c  SQLITE_SYNC_FULL
30d0: 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73  :.        zFlags
30e0: 20 3d 20 22 66 75 6c 6c 22 3b 0a 20 20 20 20 20   = "full";.     
30f0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3100: 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43  case SQLITE_SYNC
3110: 5f 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53  _NORMAL|SQLITE_S
3120: 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20  YNC_DATAONLY:.  
3130: 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22        zFlags = "
3140: 6e 6f 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c 79 22  normal|dataonly"
3150: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
3160: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
3170: 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53 51 4c  TE_SYNC_FULL|SQL
3180: 49 54 45 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c  ITE_SYNC_DATAONL
3190: 59 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67  Y:.        zFlag
31a0: 73 20 3d 20 22 66 75 6c 6c 7c 64 61 74 61 6f 6e  s = "full|dataon
31b0: 6c 79 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65  ly";.        bre
31c0: 61 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c  ak;.      defaul
31d0: 74 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  t:.        asser
31e0: 74 28 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  t(0);.    }..   
31f0: 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20   tvfsExecTcl(p, 
3200: 22 78 53 79 6e 63 22 2c 20 0a 20 20 20 20 20 20  "xSync", .      
3210: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
3220: 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  bj(pFd->zFilenam
3230: 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68  e, -1), pFd->pSh
3240: 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c  mId,.        Tcl
3250: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 46  _NewStringObj(zF
3260: 6c 61 67 73 2c 20 2d 31 29 0a 20 20 20 20 29 3b  lags, -1).    );
3270: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
3280: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
3290: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
32a0: 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a  TE_OK && tvfsInj
32b0: 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 20  ectFullerr(p) ) 
32c0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c 4c  rc = SQLITE_FULL
32d0: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
32e0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
32f0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
3300: 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c 61  (pFd->pReal, fla
3310: 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  gs);.  }..  retu
3320: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
3330: 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 72 65  Return the curre
3340: 6e 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f 66 20  nt file-size of 
3350: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
3360: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3370: 46 69 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33  FileSize(sqlite3
3380: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71  _file *pFile, sq
3390: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53 69 7a  lite_int64 *pSiz
33a0: 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20  e){.  TestvfsFd 
33b0: 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64 28 70  *p = tvfsGetFd(p
33c0: 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e 20  File);.  return 
33d0: 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a  sqlite3OsFileSiz
33e0: 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69 7a  e(p->pReal, pSiz
33f0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63  e);.}../*.** Loc
3400: 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  k an tvfs-file..
3410: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
3420: 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  fsLock(sqlite3_f
3430: 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20  ile *pFile, int 
3440: 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76 66  eLock){.  Testvf
3450: 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74  sFd *p = tvfsGet
3460: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  Fd(pFile);.  ret
3470: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63  urn sqlite3OsLoc
3480: 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63  k(p->pReal, eLoc
3490: 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e 6c  k);.}../*.** Unl
34a0: 6f 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ock an tvfs-file
34b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
34c0: 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  tvfsUnlock(sqlit
34d0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
34e0: 69 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65  int eLock){.  Te
34f0: 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66  stvfsFd *p = tvf
3500: 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20  sGetFd(pFile);. 
3510: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
3520: 73 55 6e 6c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  sUnlock(p->pReal
3530: 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a  , eLock);.}../*.
3540: 2a 2a 20 43 68 65 63 6b 20 69 66 20 61 6e 6f 74  ** Check if anot
3550: 68 65 72 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  her file-handle 
3560: 68 6f 6c 64 73 20 61 20 52 45 53 45 52 56 45 44  holds a RESERVED
3570: 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 74 76 66 73   lock on an tvfs
3580: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
3590: 20 69 6e 74 20 74 76 66 73 43 68 65 63 6b 52 65   int tvfsCheckRe
35a0: 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74  servedLock(sqlit
35b0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
35c0: 69 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20  int *pResOut){. 
35d0: 20 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20   TestvfsFd *p = 
35e0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
35f0: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
3600: 65 33 4f 73 43 68 65 63 6b 52 65 73 65 72 76 65  e3OsCheckReserve
3610: 64 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20  dLock(p->pReal, 
3620: 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a  pResOut);.}../*.
3630: 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f 6c 20  ** File control 
3640: 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75 73 74  method. For cust
3650: 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e  om operations on
3660: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
3670: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
3680: 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c  sFileControl(sql
3690: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
36a0: 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a  , int op, void *
36b0: 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76 66 73  pArg){.  Testvfs
36c0: 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46  Fd *p = tvfsGetF
36d0: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
36e0: 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65  rn sqlite3OsFile
36f0: 43 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65 61 6c  Control(p->pReal
3700: 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d 0a 0a  , op, pArg);.}..
3710: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
3720: 20 73 65 63 74 6f 72 2d 73 69 7a 65 20 69 6e 20   sector-size in 
3730: 62 79 74 65 73 20 66 6f 72 20 61 6e 20 74 76 66  bytes for an tvf
3740: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
3750: 63 20 69 6e 74 20 74 76 66 73 53 65 63 74 6f 72  c int tvfsSector
3760: 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  Size(sqlite3_fil
3770: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73  e *pFile){.  Tes
3780: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
3790: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
37a0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
37b0: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
37c0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
37d0: 20 69 66 28 20 70 2d 3e 69 53 65 63 74 6f 72 73   if( p->iSectors
37e0: 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65  ize>=0 ){.    re
37f0: 74 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f 72 73  turn p->iSectors
3800: 69 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ize;.  }.  retur
3810: 6e 20 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f  n sqlite3OsSecto
3820: 72 53 69 7a 65 28 70 46 64 2d 3e 70 52 65 61 6c  rSize(pFd->pReal
3830: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
3840: 72 6e 20 74 68 65 20 64 65 76 69 63 65 20 63 68  rn the device ch
3850: 61 72 61 63 74 65 72 69 73 74 69 63 20 66 6c 61  aracteristic fla
3860: 67 73 20 73 75 70 70 6f 72 74 65 64 20 62 79 20  gs supported by 
3870: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
3880: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3890: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
38a0: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
38b0: 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65  le *pFile){.  Te
38c0: 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74  stvfsFd *pFd = t
38d0: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
38e0: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20  .  Testvfs *p = 
38f0: 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e  (Testvfs *)pFd->
3900: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
3910: 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61    if( p->iDevcha
3920: 72 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  r>=0 ){.    retu
3930: 72 6e 20 70 2d 3e 69 44 65 76 63 68 61 72 3b 0a  rn p->iDevchar;.
3940: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c    }.  return sql
3950: 69 74 65 33 4f 73 44 65 76 69 63 65 43 68 61 72  ite3OsDeviceChar
3960: 61 63 74 65 72 69 73 74 69 63 73 28 70 46 64 2d  acteristics(pFd-
3970: 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  >pReal);.}../*.*
3980: 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73 20 66  * Open an tvfs f
3990: 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73  ile handle..*/.s
39a0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 4f 70  tatic int tvfsOp
39b0: 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  en(.  sqlite3_vf
39c0: 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74  s *pVfs,.  const
39d0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20   char *zName,.  
39e0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
39f0: 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73  ile,.  int flags
3a00: 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61  ,.  int *pOutFla
3a10: 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  gs.){.  int rc;.
3a20: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
3a30: 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73 74  Testfile = (Test
3a40: 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  vfsFile *)pFile;
3a50: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
3a60: 64 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 49  d;.  Tcl_Obj *pI
3a70: 64 20 3d 20 30 3b 0a 20 20 54 65 73 74 76 66 73  d = 0;.  Testvfs
3a80: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
3a90: 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  )pVfs->pAppData;
3aa0: 0a 0a 20 20 70 46 64 20 3d 20 28 54 65 73 74 76  ..  pFd = (Testv
3ab0: 66 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63 28 73  fsFd *)ckalloc(s
3ac0: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64 29  izeof(TestvfsFd)
3ad0: 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56 66   + PARENTVFS(pVf
3ae0: 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20  s)->szOsFile);. 
3af0: 20 6d 65 6d 73 65 74 28 70 46 64 2c 20 30 2c 20   memset(pFd, 0, 
3b00: 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64  sizeof(TestvfsFd
3b10: 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56  ) + PARENTVFS(pV
3b20: 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a  fs)->szOsFile);.
3b30: 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30 3b    pFd->pShm = 0;
3b40: 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d  .  pFd->pShmId =
3b50: 20 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69 6c 65   0;.  pFd->zFile
3b60: 6e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20  name = zName;.  
3b70: 70 46 64 2d 3e 70 56 66 73 20 3d 20 70 56 66 73  pFd->pVfs = pVfs
3b80: 3b 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c 20 3d  ;.  pFd->pReal =
3b90: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a   (sqlite3_file *
3ba0: 29 26 70 46 64 5b 31 5d 3b 0a 20 20 70 54 65 73  )&pFd[1];.  pTes
3bb0: 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 70 46 64  tfile->pFd = pFd
3bc0: 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61 74 65  ;..  /* Evaluate
3bd0: 20 74 68 65 20 54 63 6c 20 73 63 72 69 70 74 3a   the Tcl script:
3be0: 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43   .  **.  **   SC
3bf0: 52 49 50 54 20 78 4f 70 65 6e 20 46 49 4c 45 4e  RIPT xOpen FILEN
3c00: 41 4d 45 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66  AME.  **.  ** If
3c10: 20 74 68 65 20 73 63 72 69 70 74 20 72 65 74 75   the script retu
3c20: 72 6e 73 20 61 6e 20 53 51 4c 69 74 65 20 65 72  rns an SQLite er
3c30: 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 20 74  ror code other t
3c40: 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 61  han SQLITE_OK, a
3c50: 6e 0a 20 20 2a 2a 20 65 72 72 6f 72 20 69 73 20  n.  ** error is 
3c60: 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20  returned to the 
3c70: 63 61 6c 6c 65 72 2e 20 49 66 20 69 74 20 72 65  caller. If it re
3c80: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2c  turns SQLITE_OK,
3c90: 20 74 68 65 20 6e 65 77 0a 20 20 2a 2a 20 63 6f   the new.  ** co
3ca0: 6e 6e 65 63 74 69 6f 6e 20 69 73 20 6e 61 6d 65  nnection is name
3cb0: 64 20 22 61 6e 6f 6e 22 2e 20 4f 74 68 65 72 77  d "anon". Otherw
3cc0: 69 73 65 2c 20 74 68 65 20 76 61 6c 75 65 20 72  ise, the value r
3cd0: 65 74 75 72 6e 65 64 20 62 79 20 74 68 65 0a 20  eturned by the. 
3ce0: 20 2a 2a 20 73 63 72 69 70 74 20 69 73 20 75 73   ** script is us
3cf0: 65 64 20 61 73 20 74 68 65 20 63 6f 6e 6e 65 63  ed as the connec
3d00: 74 69 6f 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a  tion name..  */.
3d10: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
3d20: 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20  t(p->interp);.  
3d30: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26  if( p->pScript &
3d40: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
3d50: 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20  S_OPEN_MASK ){. 
3d60: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
3d70: 2c 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c 5f 4e  , "xOpen", Tcl_N
3d80: 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d  ewStringObj(pFd-
3d90: 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c  >zFilename, -1),
3da0: 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20   0, 0);.    if( 
3db0: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
3dc0: 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20  , &rc) ){.      
3dd0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
3de0: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  K ) return rc;. 
3df0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3e00: 70 49 64 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a  pId = Tcl_GetObj
3e10: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
3e20: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
3e30: 69 66 28 20 28 70 2d 3e 6d 61 73 6b 26 54 45 53  if( (p->mask&TES
3e40: 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 29 20  TVFS_OPEN_MASK) 
3e50: 26 26 20 20 74 76 66 73 49 6e 6a 65 63 74 49 6f  &&  tvfsInjectIo
3e60: 65 72 72 28 70 29 20 29 20 72 65 74 75 72 6e 20  err(p) ) return 
3e70: 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20  SQLITE_IOERR;.  
3e80: 69 66 28 20 74 76 66 73 49 6e 6a 65 63 74 43 61  if( tvfsInjectCa
3e90: 6e 74 6f 70 65 6e 65 72 72 28 70 29 20 29 20 72  ntopenerr(p) ) r
3ea0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 41 4e  eturn SQLITE_CAN
3eb0: 54 4f 50 45 4e 3b 0a 20 20 69 66 28 20 74 76 66  TOPEN;.  if( tvf
3ec0: 73 49 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28 70  sInjectFullerr(p
3ed0: 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ) ) return SQLIT
3ee0: 45 5f 46 55 4c 4c 3b 0a 0a 20 20 69 66 28 20 21  E_FULL;..  if( !
3ef0: 70 49 64 20 29 7b 0a 20 20 20 20 70 49 64 20 3d  pId ){.    pId =
3f00: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3f10: 6a 28 22 61 6e 6f 6e 22 2c 20 2d 31 29 3b 0a 20  j("anon", -1);. 
3f20: 20 7d 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66   }.  Tcl_IncrRef
3f30: 43 6f 75 6e 74 28 70 49 64 29 3b 0a 20 20 70 46  Count(pId);.  pF
3f40: 64 2d 3e 70 53 68 6d 49 64 20 3d 20 70 49 64 3b  d->pShmId = pId;
3f50: 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75  .  Tcl_ResetResu
3f60: 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 0a  lt(p->interp);..
3f70: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
3f80: 4f 70 65 6e 28 50 41 52 45 4e 54 56 46 53 28 70  Open(PARENTVFS(p
3f90: 56 66 73 29 2c 20 7a 4e 61 6d 65 2c 20 70 46 64  Vfs), zName, pFd
3fa0: 2d 3e 70 52 65 61 6c 2c 20 66 6c 61 67 73 2c 20  ->pReal, flags, 
3fb0: 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 69 66  pOutFlags);.  if
3fc0: 28 20 70 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d  ( pFd->pReal->pM
3fd0: 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 73 71  ethods ){.    sq
3fe0: 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73  lite3_io_methods
3ff0: 20 2a 70 4d 65 74 68 6f 64 73 3b 0a 20 20 20 20   *pMethods;.    
4000: 69 6e 74 20 6e 42 79 74 65 3b 0a 0a 20 20 20 20  int nByte;..    
4010: 69 66 28 20 70 56 66 73 2d 3e 69 56 65 72 73 69  if( pVfs->iVersi
4020: 6f 6e 3e 31 20 29 7b 0a 20 20 20 20 20 20 6e 42  on>1 ){.      nB
4030: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c  yte = sizeof(sql
4040: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29  ite3_io_methods)
4050: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
4060: 20 20 20 6e 42 79 74 65 20 3d 20 6f 66 66 73 65     nByte = offse
4070: 74 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  tof(sqlite3_io_m
4080: 65 74 68 6f 64 73 2c 20 78 53 68 6d 4f 70 65 6e  ethods, xShmOpen
4090: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4d  );.    }..    pM
40a0: 65 74 68 6f 64 73 20 3d 20 28 73 71 6c 69 74 65  ethods = (sqlite
40b0: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 29 63  3_io_methods *)c
40c0: 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  kalloc(nByte);. 
40d0: 20 20 20 6d 65 6d 63 70 79 28 70 4d 65 74 68 6f     memcpy(pMetho
40e0: 64 73 2c 20 26 74 76 66 73 5f 69 6f 5f 6d 65 74  ds, &tvfs_io_met
40f0: 68 6f 64 73 2c 20 6e 42 79 74 65 29 3b 0a 20 20  hods, nByte);.  
4100: 20 20 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72    pMethods->iVer
4110: 73 69 6f 6e 20 3d 20 70 56 66 73 2d 3e 69 56 65  sion = pVfs->iVe
4120: 72 73 69 6f 6e 3b 0a 20 20 20 20 69 66 28 20 70  rsion;.    if( p
4130: 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 31 20  Vfs->iVersion>1 
4140: 26 26 20 28 28 54 65 73 74 76 66 73 20 2a 29 70  && ((Testvfs *)p
4150: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29 2d 3e  Vfs->pAppData)->
4160: 69 73 4e 6f 73 68 6d 20 29 7b 0a 20 20 20 20 20  isNoshm ){.     
4170: 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4f   pMethods->xShmO
4180: 70 65 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  pen = 0;.      p
4190: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 43 6c 6f  Methods->xShmClo
41a0: 73 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d  se = 0;.      pM
41b0: 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63 6b  ethods->xShmLock
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 42 61 72 72 69 65  hods->xShmBarrie
41e0: 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65  r = 0;.      pMe
41f0: 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 20 3d  thods->xShmMap =
4200: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 46   0;.    }.    pF
4210: 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 20 3d 20  ile->pMethods = 
4220: 70 4d 65 74 68 6f 64 73 3b 0a 20 20 7d 0a 0a 20  pMethods;.  }.. 
4230: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
4240: 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 74 68 65 20  *.** Delete the 
4250: 66 69 6c 65 20 6c 6f 63 61 74 65 64 20 61 74 20  file located at 
4260: 7a 50 61 74 68 2e 20 49 66 20 74 68 65 20 64 69  zPath. If the di
4270: 72 53 79 6e 63 20 61 72 67 75 6d 65 6e 74 20 69  rSync argument i
4280: 73 20 74 72 75 65 2c 0a 2a 2a 20 65 6e 73 75 72  s true,.** ensur
4290: 65 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65  e the file-syste
42a0: 6d 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73 20  m modifications 
42b0: 61 72 65 20 73 79 6e 63 65 64 20 74 6f 20 64 69  are synced to di
42c0: 73 6b 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74  sk before.** ret
42d0: 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  urning..*/.stati
42e0: 63 20 69 6e 74 20 74 76 66 73 44 65 6c 65 74 65  c int tvfsDelete
42f0: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
4300: 66 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  fs, const char *
4310: 7a 50 61 74 68 2c 20 69 6e 74 20 64 69 72 53 79  zPath, int dirSy
4320: 6e 63 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  nc){.  int rc = 
4330: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73  SQLITE_OK;.  Tes
4340: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
4350: 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44  fs *)pVfs->pAppD
4360: 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70  ata;..  if( p->p
4370: 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73  Script && p->mas
4380: 6b 26 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45  k&TESTVFS_DELETE
4390: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66  _MASK ){.    tvf
43a0: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 44 65  sExecTcl(p, "xDe
43b0: 6c 65 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20  lete", .        
43c0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
43d0: 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c  (zPath, -1), Tcl
43e0: 5f 4e 65 77 49 6e 74 4f 62 6a 28 64 69 72 53 79  _NewIntObj(dirSy
43f0: 6e 63 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20  nc), 0.    );.  
4400: 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65    tvfsResultCode
4410: 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20  (p, &rc);.  }.  
4420: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4430: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
4440: 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28 50 41  lite3OsDelete(PA
4450: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a  RENTVFS(pVfs), z
4460: 50 61 74 68 2c 20 64 69 72 53 79 6e 63 29 3b 0a  Path, dirSync);.
4470: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
4480: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 66  .}../*.** Test f
4490: 6f 72 20 61 63 63 65 73 73 20 70 65 72 6d 69 73  or access permis
44a0: 73 69 6f 6e 73 2e 20 52 65 74 75 72 6e 20 74 72  sions. Return tr
44b0: 75 65 20 69 66 20 74 68 65 20 72 65 71 75 65 73  ue if the reques
44c0: 74 65 64 20 70 65 72 6d 69 73 73 69 6f 6e 0a 2a  ted permission.*
44d0: 2a 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2c 20  * is available, 
44e0: 6f 72 20 66 61 6c 73 65 20 6f 74 68 65 72 77 69  or false otherwi
44f0: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
4500: 74 20 74 76 66 73 41 63 63 65 73 73 28 0a 20 20  t tvfsAccess(.  
4510: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4520: 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  s, .  const char
4530: 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74 20   *zPath, .  int 
4540: 66 6c 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70  flags, .  int *p
4550: 52 65 73 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74  ResOut.){.  Test
4560: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
4570: 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61  s *)pVfs->pAppDa
4580: 74 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  ta;.  if( p->pSc
4590: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
45a0: 54 45 53 54 56 46 53 5f 41 43 43 45 53 53 5f 4d  TESTVFS_ACCESS_M
45b0: 41 53 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  ASK ){.    int r
45c0: 63 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 72  c;.    char *zAr
45d0: 67 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 66  g = 0;.    if( f
45e0: 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43  lags==SQLITE_ACC
45f0: 45 53 53 5f 45 58 49 53 54 53 20 29 20 7a 41 72  ESS_EXISTS ) zAr
4600: 67 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45  g = "SQLITE_ACCE
4610: 53 53 5f 45 58 49 53 54 53 22 3b 0a 20 20 20 20  SS_EXISTS";.    
4620: 69 66 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54  if( flags==SQLIT
4630: 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49  E_ACCESS_READWRI
4640: 54 45 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c  TE ) zArg = "SQL
4650: 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57  ITE_ACCESS_READW
4660: 52 49 54 45 22 3b 0a 20 20 20 20 69 66 28 20 66  RITE";.    if( f
4670: 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43  lags==SQLITE_ACC
4680: 45 53 53 5f 52 45 41 44 20 29 20 7a 41 72 67 20  ESS_READ ) zArg 
4690: 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53  = "SQLITE_ACCESS
46a0: 5f 52 45 41 44 22 3b 0a 20 20 20 20 74 76 66 73  _READ";.    tvfs
46b0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 41 63 63  ExecTcl(p, "xAcc
46c0: 65 73 73 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ess", .        T
46d0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
46e0: 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f  zPath, -1), Tcl_
46f0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 41 72  NewStringObj(zAr
4700: 67 2c 20 2d 31 29 2c 20 30 0a 20 20 20 20 29 3b  g, -1), 0.    );
4710: 0a 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73  .    if( tvfsRes
4720: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20  ultCode(p, &rc) 
4730: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  ){.      if( rc!
4740: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
4750: 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73  urn rc;.    }els
4760: 65 7b 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 74  e{.      Tcl_Int
4770: 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d  erp *interp = p-
4780: 3e 69 6e 74 65 72 70 3b 0a 20 20 20 20 20 20 69  >interp;.      i
4790: 66 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f 47  f( TCL_OK==Tcl_G
47a0: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
47b0: 28 30 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  (0, Tcl_GetObjRe
47c0: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 70 52  sult(interp), pR
47d0: 65 73 4f 75 74 29 20 29 7b 0a 20 20 20 20 20 20  esOut) ){.      
47e0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
47f0: 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OK;.      }.    
4800: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  }.  }.  return s
4810: 71 6c 69 74 65 33 4f 73 41 63 63 65 73 73 28 50  qlite3OsAccess(P
4820: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4830: 7a 50 61 74 68 2c 20 66 6c 61 67 73 2c 20 70 52  zPath, flags, pR
4840: 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  esOut);.}../*.**
4850: 20 50 6f 70 75 6c 61 74 65 20 62 75 66 66 65 72   Populate buffer
4860: 20 7a 4f 75 74 20 77 69 74 68 20 74 68 65 20 66   zOut with the f
4870: 75 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61  ull canonical pa
4880: 74 68 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f 6e  thname correspon
4890: 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 70  ding.** to the p
48a0: 61 74 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74 68  athname in zPath
48b0: 2e 20 7a 4f 75 74 20 69 73 20 67 75 61 72 61 6e  . zOut is guaran
48c0: 74 65 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f  teed to point to
48d0: 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66 20   a buffer.** of 
48e0: 61 74 20 6c 65 61 73 74 20 28 44 45 56 53 59 4d  at least (DEVSYM
48f0: 5f 4d 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31 29  _MAX_PATHNAME+1)
4900: 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   bytes..*/.stati
4910: 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c 50 61  c int tvfsFullPa
4920: 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74 65  thname(.  sqlite
4930: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20  3_vfs *pVfs, .  
4940: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74  const char *zPat
4950: 68 2c 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20  h, .  int nOut, 
4960: 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29 7b  .  char *zOut.){
4970: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
4980: 33 4f 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  3OsFullPathname(
4990: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
49a0: 20 7a 50 61 74 68 2c 20 6e 4f 75 74 2c 20 7a 4f   zPath, nOut, zO
49b0: 75 74 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20  ut);.}..#ifndef 
49c0: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
49d0: 5f 45 58 54 45 4e 53 49 4f 4e 0a 2f 2a 0a 2a 2a  _EXTENSION./*.**
49e0: 20 4f 70 65 6e 20 74 68 65 20 64 79 6e 61 6d 69   Open the dynami
49f0: 63 20 6c 69 62 72 61 72 79 20 6c 6f 63 61 74 65  c library locate
4a00: 64 20 61 74 20 7a 50 61 74 68 20 61 6e 64 20 72  d at zPath and r
4a10: 65 74 75 72 6e 20 61 20 68 61 6e 64 6c 65 2e 0a  eturn a handle..
4a20: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
4a30: 74 76 66 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74  tvfsDlOpen(sqlit
4a40: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f  e3_vfs *pVfs, co
4a50: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 29  nst char *zPath)
4a60: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
4a70: 65 33 4f 73 44 6c 4f 70 65 6e 28 50 41 52 45 4e  e3OsDlOpen(PAREN
4a80: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74  TVFS(pVfs), zPat
4a90: 68 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70  h);.}../*.** Pop
4aa0: 75 6c 61 74 65 20 74 68 65 20 62 75 66 66 65 72  ulate the buffer
4ab0: 20 7a 45 72 72 4d 73 67 20 28 73 69 7a 65 20 6e   zErrMsg (size n
4ac0: 42 79 74 65 20 62 79 74 65 73 29 20 77 69 74 68  Byte bytes) with
4ad0: 20 61 20 68 75 6d 61 6e 20 72 65 61 64 61 62 6c   a human readabl
4ae0: 65 0a 2a 2a 20 75 74 66 2d 38 20 73 74 72 69 6e  e.** utf-8 strin
4af0: 67 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65  g describing the
4b00: 20 6d 6f 73 74 20 72 65 63 65 6e 74 20 65 72 72   most recent err
4b10: 6f 72 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 61  or encountered a
4b20: 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a 20 77 69  ssociated .** wi
4b30: 74 68 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61  th dynamic libra
4b40: 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ries..*/.static 
4b50: 76 6f 69 64 20 74 76 66 73 44 6c 45 72 72 6f 72  void tvfsDlError
4b60: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
4b70: 66 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  fs, int nByte, c
4b80: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20  har *zErrMsg){. 
4b90: 20 73 71 6c 69 74 65 33 4f 73 44 6c 45 72 72 6f   sqlite3OsDlErro
4ba0: 72 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  r(PARENTVFS(pVfs
4bb0: 29 2c 20 6e 42 79 74 65 2c 20 7a 45 72 72 4d 73  ), nByte, zErrMs
4bc0: 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  g);.}../*.** Ret
4bd0: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
4be0: 20 74 68 65 20 73 79 6d 62 6f 6c 20 7a 53 79 6d   the symbol zSym
4bf0: 62 6f 6c 20 69 6e 20 74 68 65 20 64 79 6e 61 6d  bol in the dynam
4c00: 69 63 20 6c 69 62 72 61 72 79 20 70 48 61 6e 64  ic library pHand
4c10: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
4c20: 69 64 20 28 2a 74 76 66 73 44 6c 53 79 6d 28 73  id (*tvfsDlSym(s
4c30: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4c40: 2c 20 76 6f 69 64 20 2a 70 2c 20 63 6f 6e 73 74  , void *p, const
4c50: 20 63 68 61 72 20 2a 7a 53 79 6d 29 29 28 76 6f   char *zSym))(vo
4c60: 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  id){.  return sq
4c70: 6c 69 74 65 33 4f 73 44 6c 53 79 6d 28 50 41 52  lite3OsDlSym(PAR
4c80: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 2c  ENTVFS(pVfs), p,
4c90: 20 7a 53 79 6d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   zSym);.}../*.**
4ca0: 20 43 6c 6f 73 65 20 74 68 65 20 64 79 6e 61 6d   Close the dynam
4cb0: 69 63 20 6c 69 62 72 61 72 79 20 68 61 6e 64 6c  ic library handl
4cc0: 65 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  e pHandle..*/.st
4cd0: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
4ce0: 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 66  Close(sqlite3_vf
4cf0: 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70  s *pVfs, void *p
4d00: 48 61 6e 64 6c 65 29 7b 0a 20 20 73 71 6c 69 74  Handle){.  sqlit
4d10: 65 33 4f 73 44 6c 43 6c 6f 73 65 28 50 41 52 45  e3OsDlClose(PARE
4d20: 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 48 61  NTVFS(pVfs), pHa
4d30: 6e 64 6c 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 20  ndle);.}.#endif 
4d40: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  /* SQLITE_OMIT_L
4d50: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f  OAD_EXTENSION */
4d60: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65  ../*.** Populate
4d70: 20 74 68 65 20 62 75 66 66 65 72 20 70 6f 69 6e   the buffer poin
4d80: 74 65 64 20 74 6f 20 62 79 20 7a 42 75 66 4f 75  ted to by zBufOu
4d90: 74 20 77 69 74 68 20 6e 42 79 74 65 20 62 79 74  t with nByte byt
4da0: 65 73 20 6f 66 20 0a 2a 2a 20 72 61 6e 64 6f 6d  es of .** random
4db0: 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63   data..*/.static
4dc0: 20 69 6e 74 20 74 76 66 73 52 61 6e 64 6f 6d 6e   int tvfsRandomn
4dd0: 65 73 73 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ess(sqlite3_vfs 
4de0: 2a 70 56 66 73 2c 20 69 6e 74 20 6e 42 79 74 65  *pVfs, int nByte
4df0: 2c 20 63 68 61 72 20 2a 7a 42 75 66 4f 75 74 29  , char *zBufOut)
4e00: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
4e10: 65 33 4f 73 52 61 6e 64 6f 6d 6e 65 73 73 28 50  e3OsRandomness(P
4e20: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4e30: 6e 42 79 74 65 2c 20 7a 42 75 66 4f 75 74 29 3b  nByte, zBufOut);
4e40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6c 65 65 70 20  .}../*.** Sleep 
4e50: 66 6f 72 20 6e 4d 69 63 72 6f 20 6d 69 63 72 6f  for nMicro micro
4e60: 73 65 63 6f 6e 64 73 2e 20 52 65 74 75 72 6e 20  seconds. Return 
4e70: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69  the number of mi
4e80: 63 72 6f 73 65 63 6f 6e 64 73 20 0a 2a 2a 20 61  croseconds .** a
4e90: 63 74 75 61 6c 6c 79 20 73 6c 65 70 74 2e 0a 2a  ctually slept..*
4ea0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
4eb0: 73 53 6c 65 65 70 28 73 71 6c 69 74 65 33 5f 76  sSleep(sqlite3_v
4ec0: 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 4d  fs *pVfs, int nM
4ed0: 69 63 72 6f 29 7b 0a 20 20 72 65 74 75 72 6e 20  icro){.  return 
4ee0: 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 50  sqlite3OsSleep(P
4ef0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4f00: 6e 4d 69 63 72 6f 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  nMicro);.}../*.*
4f10: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72  * Return the cur
4f20: 72 65 6e 74 20 74 69 6d 65 20 61 73 20 61 20 4a  rent time as a J
4f30: 75 6c 69 61 6e 20 44 61 79 20 6e 75 6d 62 65 72  ulian Day number
4f40: 20 69 6e 20 2a 70 54 69 6d 65 4f 75 74 2e 0a 2a   in *pTimeOut..*
4f50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
4f60: 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71 6c  sCurrentTime(sql
4f70: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4f80: 64 6f 75 62 6c 65 20 2a 70 54 69 6d 65 4f 75 74  double *pTimeOut
4f90: 29 7b 0a 20 20 72 65 74 75 72 6e 20 50 41 52 45  ){.  return PARE
4fa0: 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 78 43 75  NTVFS(pVfs)->xCu
4fb0: 72 72 65 6e 74 54 69 6d 65 28 50 41 52 45 4e 54  rrentTime(PARENT
4fc0: 56 46 53 28 70 56 66 73 29 2c 20 70 54 69 6d 65  VFS(pVfs), pTime
4fd0: 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  Out);.}..static 
4fe0: 69 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28  int tvfsShmOpen(
4ff0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
5000: 69 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 20  ile){.  Testvfs 
5010: 2a 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  *p;.  int rc = S
5020: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
5030: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
5040: 63 6f 64 65 20 2a 2f 0a 20 20 54 65 73 74 76 66  code */.  Testvf
5050: 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  sBuffer *pBuffer
5060: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66  ;         /* Buf
5070: 66 65 72 20 74 6f 20 6f 70 65 6e 20 63 6f 6e 6e  fer to open conn
5080: 65 63 74 69 6f 6e 20 74 6f 20 2a 2f 0a 20 20 54  ection to */.  T
5090: 65 73 74 76 66 73 46 64 20 2a 70 46 64 3b 20 20  estvfsFd *pFd;  
50a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
50b0: 2a 20 54 68 65 20 74 65 73 74 76 66 73 20 66 69  * The testvfs fi
50c0: 6c 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  le structure */.
50d0: 0a 20 20 70 46 64 20 3d 20 74 76 66 73 47 65 74  .  pFd = tvfsGet
50e0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 70 20 3d  Fd(pFile);.  p =
50f0: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
5100: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
5110: 0a 20 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e  .  assert( pFd->
5120: 70 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70  pShmId && pFd->p
5130: 53 68 6d 3d 3d 30 20 26 26 20 70 46 64 2d 3e 70  Shm==0 && pFd->p
5140: 4e 65 78 74 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a  Next==0 );..  /*
5150: 20 45 76 61 6c 75 61 74 65 20 74 68 65 20 54 63   Evaluate the Tc
5160: 6c 20 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a  l script: .  **.
5170: 20 20 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53    **   SCRIPT xS
5180: 68 6d 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45 0a  hmOpen FILENAME.
5190: 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74    */.  Tcl_Reset
51a0: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
51b0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  );.  if( p->pScr
51c0: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
51d0: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
51e0: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
51f0: 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4f  xecTcl(p, "xShmO
5200: 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pen", Tcl_NewStr
5210: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c  ingObj(pFd->zFil
5220: 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30 2c 20 30  ename, -1), 0, 0
5230: 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52  );.    if( tvfsR
5240: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
5250: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72  ) ){.      if( r
5260: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
5270: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
5280: 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72    }..  assert( r
5290: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
52a0: 20 20 69 66 28 20 70 2d 3e 6d 61 73 6b 26 54 45    if( p->mask&TE
52b0: 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41  STVFS_SHMOPEN_MA
52c0: 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74  SK && tvfsInject
52d0: 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20  Ioerr(p) ){.    
52e0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
52f0: 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  ERR;.  }..  /* S
5300: 65 61 72 63 68 20 66 6f 72 20 61 20 54 65 73 74  earch for a Test
5310: 76 66 73 42 75 66 66 65 72 2e 20 43 72 65 61 74  vfsBuffer. Creat
5320: 65 20 61 20 6e 65 77 20 6f 6e 65 20 69 66 20 72  e a new one if r
5330: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 66 6f  equired. */.  fo
5340: 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75  r(pBuffer=p->pBu
5350: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70  ffer; pBuffer; p
5360: 42 75 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e  Buffer=pBuffer->
5370: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
5380: 30 3d 3d 73 74 72 63 6d 70 28 70 46 64 2d 3e 7a  0==strcmp(pFd->z
5390: 46 69 6c 65 6e 61 6d 65 2c 20 70 42 75 66 66 65  Filename, pBuffe
53a0: 72 2d 3e 7a 46 69 6c 65 29 20 29 20 62 72 65 61  r->zFile) ) brea
53b0: 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 21 70 42  k;.  }.  if( !pB
53c0: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 69 6e 74  uffer ){.    int
53d0: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
53e0: 54 65 73 74 76 66 73 42 75 66 66 65 72 29 20 2b  TestvfsBuffer) +
53f0: 20 73 74 72 6c 65 6e 28 70 46 64 2d 3e 7a 46 69   strlen(pFd->zFi
5400: 6c 65 6e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 20  lename) + 1;.   
5410: 20 70 42 75 66 66 65 72 20 3d 20 28 54 65 73 74   pBuffer = (Test
5420: 76 66 73 42 75 66 66 65 72 20 2a 29 63 6b 61 6c  vfsBuffer *)ckal
5430: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
5440: 6d 65 6d 73 65 74 28 70 42 75 66 66 65 72 2c 20  memset(pBuffer, 
5450: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  0, nByte);.    p
5460: 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 20 3d 20  Buffer->zFile = 
5470: 28 63 68 61 72 20 2a 29 26 70 42 75 66 66 65 72  (char *)&pBuffer
5480: 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28  [1];.    strcpy(
5490: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
54a0: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b  pFd->zFilename);
54b0: 0a 20 20 20 20 70 42 75 66 66 65 72 2d 3e 70 4e  .    pBuffer->pN
54c0: 65 78 74 20 3d 20 70 2d 3e 70 42 75 66 66 65 72  ext = p->pBuffer
54d0: 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66 66 65 72  ;.    p->pBuffer
54e0: 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 7d 0a   = pBuffer;.  }.
54f0: 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74 20 74 68  .  /* Connect th
5500: 65 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e TestvfsBuffer 
5510: 74 6f 20 74 68 65 20 6e 65 77 20 54 65 73 74 76  to the new Testv
5520: 66 73 53 68 6d 20 68 61 6e 64 6c 65 20 61 6e 64  fsShm handle and
5530: 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 70 46   return. */.  pF
5540: 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42 75 66 66  d->pNext = pBuff
5550: 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20 70 42 75  er->pFile;.  pBu
5560: 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46  ffer->pFile = pF
5570: 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d  d;.  pFd->pShm =
5580: 20 70 42 75 66 66 65 72 3b 0a 20 20 72 65 74 75   pBuffer;.  retu
5590: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
55a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66  .static void tvf
55b0: 73 41 6c 6c 6f 63 50 61 67 65 28 54 65 73 74 76  sAllocPage(Testv
55c0: 66 73 42 75 66 66 65 72 20 2a 70 2c 20 69 6e 74  fsBuffer *p, int
55d0: 20 69 50 61 67 65 2c 20 69 6e 74 20 70 67 73 7a   iPage, int pgsz
55e0: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61  ){.  assert( iPa
55f0: 67 65 3c 54 45 53 54 56 46 53 5f 4d 41 58 5f 50  ge<TESTVFS_MAX_P
5600: 41 47 45 53 20 29 3b 0a 20 20 69 66 28 20 70 2d  AGES );.  if( p-
5610: 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 3d 3d 30  >aPage[iPage]==0
5620: 20 29 7b 0a 20 20 20 20 70 2d 3e 61 50 61 67 65   ){.    p->aPage
5630: 5b 69 50 61 67 65 5d 20 3d 20 28 75 38 20 2a 29  [iPage] = (u8 *)
5640: 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20  ckalloc(pgsz);. 
5650: 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 61 50 61     memset(p->aPa
5660: 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c 20 70 67  ge[iPage], 0, pg
5670: 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70 67 73 7a  sz);.    p->pgsz
5680: 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a 7d 0a 0a   = pgsz;.  }.}..
5690: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
56a0: 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33  hmMap(.  sqlite3
56b0: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20  _file *pFile,   
56c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64           /* Hand
56d0: 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62  le open on datab
56e0: 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  ase file */.  in
56f0: 74 20 69 50 61 67 65 2c 20 20 20 20 20 20 20 20  t iPage,        
5700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5710: 20 50 61 67 65 20 74 6f 20 72 65 74 72 69 65 76   Page to retriev
5720: 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 2c  e */.  int pgsz,
5730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5740: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
5750: 66 20 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74  f pages */.  int
5760: 20 69 73 57 72 69 74 65 2c 20 20 20 20 20 20 20   isWrite,       
5770: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5780: 54 72 75 65 20 74 6f 20 65 78 74 65 6e 64 20 66  True to extend f
5790: 69 6c 65 20 69 66 20 6e 65 63 65 73 73 61 72 79  ile if necessary
57a0: 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f 6c 61 74   */.  void volat
57b0: 69 6c 65 20 2a 2a 70 70 20 20 20 20 20 20 20 20  ile **pp        
57c0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4d 61        /* OUT: Ma
57d0: 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 29  pped memory */.)
57e0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
57f0: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
5800: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
5810: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
5820: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
5830: 74 76 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66  tvfs *)(pFd->pVf
5840: 73 2d 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20  s->pAppData);.. 
5850: 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20   if( p->pScript 
5860: 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56  && p->mask&TESTV
5870: 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 29  FS_SHMMAP_MASK )
5880: 7b 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  {.    Tcl_Obj *p
5890: 41 72 67 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  Arg = Tcl_NewObj
58a0: 28 29 3b 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72  ();.    Tcl_Incr
58b0: 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a  RefCount(pArg);.
58c0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
58d0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e  ppendElement(p->
58e0: 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54 63  interp, pArg, Tc
58f0: 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 50 61 67  l_NewIntObj(iPag
5900: 65 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73  e));.    Tcl_Lis
5910: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
5920: 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41 72  t(p->interp, pAr
5930: 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a  g, Tcl_NewIntObj
5940: 28 70 67 73 7a 29 29 3b 0a 20 20 20 20 54 63 6c  (pgsz));.    Tcl
5950: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
5960: 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c  ement(p->interp,
5970: 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e   pArg, Tcl_NewIn
5980: 74 4f 62 6a 28 69 73 57 72 69 74 65 29 29 3b 0a  tObj(isWrite));.
5990: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
59a0: 70 2c 20 22 78 53 68 6d 4d 61 70 22 2c 20 0a 20  p, "xShmMap", . 
59b0: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
59c0: 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68  ringObj(pFd->pSh
59d0: 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70  m->zFile, -1), p
59e0: 46 64 2d 3e 70 53 68 6d 49 64 2c 20 70 41 72 67  Fd->pShmId, pArg
59f0: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
5a00: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
5a10: 63 29 3b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72  c);.    Tcl_Decr
5a20: 52 65 66 43 6f 75 6e 74 28 70 41 72 67 29 3b 0a  RefCount(pArg);.
5a30: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
5a40: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61  LITE_OK && p->ma
5a50: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41  sk&TESTVFS_SHMMA
5a60: 50 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e  P_MASK && tvfsIn
5a70: 6a 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a  jectIoerr(p) ){.
5a80: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
5a90: 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69 66  IOERR;.  }..  if
5aa0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5ab0: 26 26 20 69 73 57 72 69 74 65 20 26 26 20 21 70  && isWrite && !p
5ac0: 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65 5b  Fd->pShm->aPage[
5ad0: 69 50 61 67 65 5d 20 29 7b 0a 20 20 20 20 74 76  iPage] ){.    tv
5ae0: 66 73 41 6c 6c 6f 63 50 61 67 65 28 70 46 64 2d  fsAllocPage(pFd-
5af0: 3e 70 53 68 6d 2c 20 69 50 61 67 65 2c 20 70 67  >pShm, iPage, pg
5b00: 73 7a 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d  sz);.  }.  *pp =
5b10: 20 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20   (void volatile 
5b20: 2a 29 70 46 64 2d 3e 70 53 68 6d 2d 3e 61 50 61  *)pFd->pShm->aPa
5b30: 67 65 5b 69 50 61 67 65 5d 3b 0a 0a 20 20 72 65  ge[iPage];..  re
5b40: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74 61  turn rc;.}...sta
5b50: 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d 4c  tic int tvfsShmL
5b60: 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 66  ock(.  sqlite3_f
5b70: 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69 6e  ile *pFile,.  in
5b80: 74 20 6f 66 73 74 2c 0a 20 20 69 6e 74 20 6e 2c  t ofst,.  int n,
5b90: 0a 20 20 69 6e 74 20 66 6c 61 67 73 0a 29 7b 0a  .  int flags.){.
5ba0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
5bb0: 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46  E_OK;.  TestvfsF
5bc0: 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74  d *pFd = tvfsGet
5bd0: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73  Fd(pFile);.  Tes
5be0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
5bf0: 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d  fs *)(pFd->pVfs-
5c00: 3e 70 41 70 70 44 61 74 61 29 3b 0a 20 20 69 6e  >pAppData);.  in
5c10: 74 20 6e 4c 6f 63 6b 3b 0a 20 20 63 68 61 72 20  t nLock;.  char 
5c20: 7a 4c 6f 63 6b 5b 38 30 5d 3b 0a 0a 20 20 69 66  zLock[80];..  if
5c30: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
5c40: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
5c50: 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 29 7b 0a  SHMLOCK_MASK ){.
5c60: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72      sqlite3_snpr
5c70: 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4c 6f 63  intf(sizeof(zLoc
5c80: 6b 29 2c 20 7a 4c 6f 63 6b 2c 20 22 25 64 20 25  k), zLock, "%d %
5c90: 64 22 2c 20 6f 66 73 74 2c 20 6e 29 3b 0a 20 20  d", ofst, n);.  
5ca0: 20 20 6e 4c 6f 63 6b 20 3d 20 73 74 72 6c 65 6e    nLock = strlen
5cb0: 28 7a 4c 6f 63 6b 29 3b 0a 20 20 20 20 69 66 28  (zLock);.    if(
5cc0: 20 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f   flags & SQLITE_
5cd0: 53 48 4d 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  SHM_LOCK ){.    
5ce0: 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b    strcpy(&zLock[
5cf0: 6e 4c 6f 63 6b 5d 2c 20 22 20 6c 6f 63 6b 22 29  nLock], " lock")
5d00: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
5d10: 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b     strcpy(&zLock
5d20: 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 75 6e 6c 6f 63  [nLock], " unloc
5d30: 6b 22 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e  k");.    }.    n
5d40: 4c 6f 63 6b 20 2b 3d 20 73 74 72 6c 65 6e 28 26  Lock += strlen(&
5d50: 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 29 3b 0a 20  zLock[nLock]);. 
5d60: 20 20 20 69 66 28 20 66 6c 61 67 73 20 26 20 53     if( flags & S
5d70: 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44  QLITE_SHM_SHARED
5d80: 20 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79   ){.      strcpy
5d90: 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20  (&zLock[nLock], 
5da0: 22 20 73 68 61 72 65 64 22 29 3b 0a 20 20 20 20  " shared");.    
5db0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 74 72  }else{.      str
5dc0: 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b  cpy(&zLock[nLock
5dd0: 5d 2c 20 22 20 65 78 63 6c 75 73 69 76 65 22 29  ], " exclusive")
5de0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 74 76 66 73  ;.    }.    tvfs
5df0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d  ExecTcl(p, "xShm
5e00: 4c 6f 63 6b 22 2c 20 0a 20 20 20 20 20 20 20 20  Lock", .        
5e10: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5e20: 28 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c  (pFd->pShm->zFil
5e30: 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68  e, -1), pFd->pSh
5e40: 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c  mId,.        Tcl
5e50: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 4c  _NewStringObj(zL
5e60: 6f 63 6b 2c 20 2d 31 29 0a 20 20 20 20 29 3b 0a  ock, -1).    );.
5e70: 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f      tvfsResultCo
5e80: 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a  de(p, &rc);.  }.
5e90: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
5ea0: 45 5f 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26  E_OK && p->mask&
5eb0: 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f  TESTVFS_SHMLOCK_
5ec0: 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65  MASK && tvfsInje
5ed0: 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20  ctIoerr(p) ){.  
5ee0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f    rc = SQLITE_IO
5ef0: 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  ERR;.  }..  if( 
5f00: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
5f10: 0a 20 20 20 20 69 6e 74 20 69 73 4c 6f 63 6b 20  .    int isLock 
5f20: 3d 20 28 66 6c 61 67 73 20 26 20 53 51 4c 49 54  = (flags & SQLIT
5f30: 45 5f 53 48 4d 5f 4c 4f 43 4b 29 3b 0a 20 20 20  E_SHM_LOCK);.   
5f40: 20 69 6e 74 20 69 73 45 78 63 6c 20 3d 20 28 66   int isExcl = (f
5f50: 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48  lags & SQLITE_SH
5f60: 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20  M_EXCLUSIVE);.  
5f70: 20 20 75 33 32 20 6d 61 73 6b 20 3d 20 28 28 28    u32 mask = (((
5f80: 31 3c 3c 6e 29 2d 31 29 20 3c 3c 20 6f 66 73 74  1<<n)-1) << ofst
5f90: 29 3b 0a 20 20 20 20 69 66 28 20 69 73 4c 6f 63  );.    if( isLoc
5fa0: 6b 20 29 7b 0a 20 20 20 20 20 20 54 65 73 74 76  k ){.      Testv
5fb0: 66 73 46 64 20 2a 70 32 3b 0a 20 20 20 20 20 20  fsFd *p2;.      
5fc0: 66 6f 72 28 70 32 3d 70 46 64 2d 3e 70 53 68 6d  for(p2=pFd->pShm
5fd0: 2d 3e 70 46 69 6c 65 3b 20 70 32 3b 20 70 32 3d  ->pFile; p2; p2=
5fe0: 70 32 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  p2->pNext){.    
5ff0: 20 20 20 20 69 66 28 20 70 32 3d 3d 70 46 64 20      if( p2==pFd 
6000: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
6010: 20 20 20 20 69 66 28 20 28 70 32 2d 3e 65 78 63      if( (p2->exc
6020: 6c 6c 6f 63 6b 26 6d 61 73 6b 29 20 7c 7c 20 28  llock&mask) || (
6030: 69 73 45 78 63 6c 20 26 26 20 70 32 2d 3e 73 68  isExcl && p2->sh
6040: 61 72 65 64 6c 6f 63 6b 26 6d 61 73 6b 29 20 29  aredlock&mask) )
6050: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
6060: 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20   SQLITE_BUSY;.  
6070: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
6080: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
6090: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
60a0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
60b0: 20 20 20 20 69 66 28 20 69 73 45 78 63 6c 20 29      if( isExcl )
60c0: 20 20 70 46 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20    pFd->excllock 
60d0: 7c 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20  |= mask;.       
60e0: 20 69 66 28 20 21 69 73 45 78 63 6c 20 29 20 70   if( !isExcl ) p
60f0: 46 64 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 20 7c  Fd->sharedlock |
6100: 3d 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 7d 0a  = mask;.      }.
6110: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
6120: 20 69 66 28 20 69 73 45 78 63 6c 20 29 20 20 70   if( isExcl )  p
6130: 46 64 2d 3e 65 78 63 6c 6c 6f 63 6b 20 26 3d 20  Fd->excllock &= 
6140: 28 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 20 20 69  (~mask);.      i
6150: 66 28 20 21 69 73 45 78 63 6c 20 29 20 70 46 64  f( !isExcl ) pFd
6160: 2d 3e 73 68 61 72 65 64 6c 6f 63 6b 20 26 3d 20  ->sharedlock &= 
6170: 28 7e 6d 61 73 6b 29 3b 0a 20 20 20 20 7d 0a 20  (~mask);.    }. 
6180: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
6190: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
61a0: 74 76 66 73 53 68 6d 42 61 72 72 69 65 72 28 73  tvfsShmBarrier(s
61b0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
61c0: 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64  le){.  TestvfsFd
61d0: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
61e0: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
61f0: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
6200: 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e  s *)(pFd->pVfs->
6210: 70 41 70 70 44 61 74 61 29 3b 0a 0a 20 20 69 66  pAppData);..  if
6220: 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20  ( p->pScript && 
6230: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
6240: 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b 20  SHMBARRIER_MASK 
6250: 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65 63 54  ){.    tvfsExecT
6260: 63 6c 28 70 2c 20 22 78 53 68 6d 42 61 72 72 69  cl(p, "xShmBarri
6270: 65 72 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  er", .        Tc
6280: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
6290: 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c  Fd->pShm->zFile,
62a0: 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49   -1), pFd->pShmI
62b0: 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  d, 0.    );.  }.
62c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  }..static int tv
62d0: 66 73 53 68 6d 43 6c 6f 73 65 28 0a 20 20 73 71  fsShmClose(.  sq
62e0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
62f0: 65 2c 0a 20 20 69 6e 74 20 64 65 6c 65 74 65 46  e,.  int deleteF
6300: 6c 61 67 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  lag.){.  int rc 
6310: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54  = SQLITE_OK;.  T
6320: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
6330: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
6340: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
6350: 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64   (Testvfs *)(pFd
6360: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
6370: 29 3b 0a 20 20 54 65 73 74 76 66 73 42 75 66 66  );.  TestvfsBuff
6380: 65 72 20 2a 70 42 75 66 66 65 72 20 3d 20 70 46  er *pBuffer = pF
6390: 64 2d 3e 70 53 68 6d 3b 0a 20 20 54 65 73 74 76  d->pShm;.  Testv
63a0: 66 73 46 64 20 2a 2a 70 70 46 64 3b 0a 0a 20 20  fsFd **ppFd;..  
63b0: 61 73 73 65 72 74 28 20 70 46 64 2d 3e 70 53 68  assert( pFd->pSh
63c0: 6d 49 64 20 26 26 20 70 46 64 2d 3e 70 53 68 6d  mId && pFd->pShm
63d0: 20 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53   );..  if( p->pS
63e0: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
63f0: 26 54 45 53 54 56 46 53 5f 53 48 4d 43 4c 4f 53  &TESTVFS_SHMCLOS
6400: 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76  E_MASK ){.    tv
6410: 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53  fsExecTcl(p, "xS
6420: 68 6d 43 6c 6f 73 65 22 2c 20 0a 20 20 20 20 20  hmClose", .     
6430: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
6440: 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a  Obj(pFd->pShm->z
6450: 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e  File, -1), pFd->
6460: 70 53 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b  pShmId, 0.    );
6470: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
6480: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
6490: 0a 0a 20 20 66 6f 72 28 70 70 46 64 3d 26 70 42  ..  for(ppFd=&pB
64a0: 75 66 66 65 72 2d 3e 70 46 69 6c 65 3b 20 2a 70  uffer->pFile; *p
64b0: 70 46 64 21 3d 70 46 64 3b 20 70 70 46 64 3d 26  pFd!=pFd; ppFd=&
64c0: 28 28 2a 70 70 46 64 29 2d 3e 70 4e 65 78 74 29  ((*ppFd)->pNext)
64d0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28 2a 70  );.  assert( (*p
64e0: 70 46 64 29 3d 3d 70 46 64 20 29 3b 0a 20 20 2a  pFd)==pFd );.  *
64f0: 70 70 46 64 20 3d 20 70 46 64 2d 3e 70 4e 65 78  ppFd = pFd->pNex
6500: 74 3b 0a 0a 20 20 69 66 28 20 70 42 75 66 66 65  t;..  if( pBuffe
6510: 72 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  r->pFile==0 ){. 
6520: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 54 65     int i;.    Te
6530: 73 74 76 66 73 42 75 66 66 65 72 20 2a 2a 70 70  stvfsBuffer **pp
6540: 3b 0a 20 20 20 20 66 6f 72 28 70 70 3d 26 70 2d  ;.    for(pp=&p-
6550: 3e 70 42 75 66 66 65 72 3b 20 2a 70 70 21 3d 70  >pBuffer; *pp!=p
6560: 42 75 66 66 65 72 3b 20 70 70 3d 26 28 28 2a 70  Buffer; pp=&((*p
6570: 70 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20  p)->pNext));.   
6580: 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e   *pp = (*pp)->pN
6590: 65 78 74 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  ext;.    for(i=0
65a0: 3b 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65  ; pBuffer->aPage
65b0: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
65c0: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
65d0: 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69  pBuffer->aPage[i
65e0: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 6b  ]);.    }.    ck
65f0: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 42 75  free((char *)pBu
6600: 66 66 65 72 29 3b 0a 20 20 7d 0a 20 20 70 46 64  ffer);.  }.  pFd
6610: 2d 3e 70 53 68 6d 20 3d 20 30 3b 0a 0a 20 20 72  ->pShm = 0;..  r
6620: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
6630: 74 69 63 20 69 6e 74 20 74 65 73 74 76 66 73 5f  tic int testvfs_
6640: 6f 62 6a 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e  obj_cmd(.  Clien
6650: 74 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f  tData cd,.  Tcl_
6660: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
6670: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
6680: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
6690: 76 5b 5d 0a 29 7b 0a 20 20 54 65 73 74 76 66 73  v[].){.  Testvfs
66a0: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
66b0: 29 63 64 3b 0a 0a 20 20 65 6e 75 6d 20 44 42 5f  )cd;..  enum DB_
66c0: 65 6e 75 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f  enum { .    CMD_
66d0: 53 48 4d 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c  SHM, CMD_DELETE,
66e0: 20 43 4d 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44   CMD_FILTER, CMD
66f0: 5f 49 4f 45 52 52 2c 20 43 4d 44 5f 53 43 52 49  _IOERR, CMD_SCRI
6700: 50 54 2c 20 0a 20 20 20 20 43 4d 44 5f 44 45 56  PT, .    CMD_DEV
6710: 43 48 41 52 2c 20 43 4d 44 5f 53 45 43 54 4f 52  CHAR, CMD_SECTOR
6720: 53 49 5a 45 2c 20 43 4d 44 5f 46 55 4c 4c 45 52  SIZE, CMD_FULLER
6730: 52 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45  R, CMD_CANTOPENE
6740: 52 52 0a 20 20 7d 3b 0a 20 20 73 74 72 75 63 74  RR.  };.  struct
6750: 20 54 65 73 74 76 66 73 53 75 62 63 6d 64 20 7b   TestvfsSubcmd {
6760: 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  .    char *zName
6770: 3b 0a 20 20 20 20 65 6e 75 6d 20 44 42 5f 65 6e  ;.    enum DB_en
6780: 75 6d 20 65 43 6d 64 3b 0a 20 20 7d 20 61 53 75  um eCmd;.  } aSu
6790: 62 63 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b  bcmd[] = {.    {
67a0: 20 22 73 68 6d 22 2c 20 20 20 20 20 20 20 20 20   "shm",         
67b0: 43 4d 44 5f 53 48 4d 20 20 20 20 20 20 20 20 20  CMD_SHM         
67c0: 7d 2c 0a 20 20 20 20 7b 20 22 64 65 6c 65 74 65  },.    { "delete
67d0: 22 2c 20 20 20 20 20 20 43 4d 44 5f 44 45 4c 45  ",      CMD_DELE
67e0: 54 45 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  TE      },.    {
67f0: 20 22 66 69 6c 74 65 72 22 2c 20 20 20 20 20 20   "filter",      
6800: 43 4d 44 5f 46 49 4c 54 45 52 20 20 20 20 20 20  CMD_FILTER      
6810: 7d 2c 0a 20 20 20 20 7b 20 22 69 6f 65 72 72 22  },.    { "ioerr"
6820: 2c 20 20 20 20 20 20 20 43 4d 44 5f 49 4f 45 52  ,       CMD_IOER
6830: 52 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  R       },.    {
6840: 20 22 66 75 6c 6c 65 72 72 22 2c 20 20 20 20 20   "fullerr",     
6850: 43 4d 44 5f 46 55 4c 4c 45 52 52 20 20 20 20 20  CMD_FULLERR     
6860: 7d 2c 0a 20 20 20 20 7b 20 22 63 61 6e 74 6f 70  },.    { "cantop
6870: 65 6e 65 72 72 22 2c 20 43 4d 44 5f 43 41 4e 54  enerr", CMD_CANT
6880: 4f 50 45 4e 45 52 52 20 7d 2c 0a 20 20 20 20 7b  OPENERR },.    {
6890: 20 22 73 63 72 69 70 74 22 2c 20 20 20 20 20 20   "script",      
68a0: 43 4d 44 5f 53 43 52 49 50 54 20 20 20 20 20 20  CMD_SCRIPT      
68b0: 7d 2c 0a 20 20 20 20 7b 20 22 64 65 76 63 68 61  },.    { "devcha
68c0: 72 22 2c 20 20 20 20 20 43 4d 44 5f 44 45 56 43  r",     CMD_DEVC
68d0: 48 41 52 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  HAR     },.    {
68e0: 20 22 73 65 63 74 6f 72 73 69 7a 65 22 2c 20 20   "sectorsize",  
68f0: 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a 45 20 20  CMD_SECTORSIZE  
6900: 7d 2c 0a 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a  },.    { 0, 0 }.
6910: 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20    };.  int i;.  
6920: 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20 29 7b  .  if( objc<2 ){
6930: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
6940: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
6950: 20 6f 62 6a 76 2c 20 22 53 55 42 43 4f 4d 4d 41   objv, "SUBCOMMA
6960: 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 65  ND ...");.    re
6970: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
6980: 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65    }.  if( Tcl_Ge
6990: 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a 53 74 72  tIndexFromObjStr
69a0: 75 63 74 28 0a 20 20 20 20 20 20 20 20 69 6e 74  uct(.        int
69b0: 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 61 53  erp, objv[1], aS
69c0: 75 62 63 6d 64 2c 20 73 69 7a 65 6f 66 28 61 53  ubcmd, sizeof(aS
69d0: 75 62 63 6d 64 5b 30 5d 29 2c 20 22 73 75 62 63  ubcmd[0]), "subc
69e0: 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69 29 20  ommand", 0, &i) 
69f0: 0a 20 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  .  ){.    return
6a00: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
6a10: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
6a20: 74 28 69 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77  t(interp);..  sw
6a30: 69 74 63 68 28 20 61 53 75 62 63 6d 64 5b 69 5d  itch( aSubcmd[i]
6a40: 2e 65 43 6d 64 20 29 7b 0a 20 20 20 20 63 61 73  .eCmd ){.    cas
6a50: 65 20 43 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20  e CMD_SHM: {.   
6a60: 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a     Tcl_Obj *pObj
6a70: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  ;.      int i;. 
6a80: 20 20 20 20 20 54 65 73 74 76 66 73 42 75 66 66       TestvfsBuff
6a90: 65 72 20 2a 70 42 75 66 66 65 72 3b 0a 20 20 20  er *pBuffer;.   
6aa0: 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a     char *zName;.
6ab0: 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21 3d        if( objc!=
6ac0: 33 20 26 26 20 6f 62 6a 63 21 3d 34 20 29 7b 0a  3 && objc!=4 ){.
6ad0: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
6ae0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
6af0: 20 32 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45 20   2, objv, "FILE 
6b00: 3f 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20  ?VALUE?");.     
6b10: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
6b20: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
6b30: 20 20 20 7a 4e 61 6d 65 20 3d 20 63 6b 61 6c 6c     zName = ckall
6b40: 6f 63 28 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d  oc(p->pParent->m
6b50: 78 50 61 74 68 6e 61 6d 65 29 3b 0a 20 20 20 20  xPathname);.    
6b60: 20 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46    p->pParent->xF
6b70: 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 20  ullPathname(.   
6b80: 20 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e         p->pParen
6b90: 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  t, Tcl_GetString
6ba0: 28 6f 62 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20  (objv[2]), .    
6bb0: 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74        p->pParent
6bc0: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e  ->mxPathname, zN
6bd0: 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ame.      );.   
6be0: 20 20 20 66 6f 72 28 70 42 75 66 66 65 72 3d 70     for(pBuffer=p
6bf0: 2d 3e 70 42 75 66 66 65 72 3b 20 70 42 75 66 66  ->pBuffer; pBuff
6c00: 65 72 3b 20 70 42 75 66 66 65 72 3d 70 42 75 66  er; pBuffer=pBuf
6c10: 66 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  fer->pNext){.   
6c20: 20 20 20 20 20 69 66 28 20 30 3d 3d 73 74 72 63       if( 0==strc
6c30: 6d 70 28 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c  mp(pBuffer->zFil
6c40: 65 2c 20 7a 4e 61 6d 65 29 20 29 20 62 72 65 61  e, zName) ) brea
6c50: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  k;.      }.     
6c60: 20 63 6b 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a   ckfree(zName);.
6c70: 20 20 20 20 20 20 69 66 28 20 21 70 42 75 66 66        if( !pBuff
6c80: 65 72 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63  er ){.        Tc
6c90: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
6ca0: 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68 20  nterp, "no such 
6cb0: 66 69 6c 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74  file: ", Tcl_Get
6cc0: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c  String(objv[2]),
6cd0: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74   0);.        ret
6ce0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
6cf0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
6d00: 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20   objc==4 ){.    
6d10: 20 20 20 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20      int n;.     
6d20: 20 20 20 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47     u8 *a = Tcl_G
6d30: 65 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f  etByteArrayFromO
6d40: 62 6a 28 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b  bj(objv[3], &n);
6d50: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 70 67 73  .        int pgs
6d60: 7a 20 3d 20 70 42 75 66 66 65 72 2d 3e 70 67 73  z = pBuffer->pgs
6d70: 7a 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  z;.        if( p
6d80: 67 73 7a 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20  gsz==0 ) pgsz = 
6d90: 33 32 37 36 38 3b 0a 20 20 20 20 20 20 20 20 66  32768;.        f
6da0: 6f 72 28 69 3d 30 3b 20 69 2a 70 67 73 7a 3c 6e  or(i=0; i*pgsz<n
6db0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
6dc0: 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 70 67    int nByte = pg
6dd0: 73 7a 3b 0a 20 20 20 20 20 20 20 20 20 20 74 76  sz;.          tv
6de0: 66 73 41 6c 6c 6f 63 50 61 67 65 28 70 42 75 66  fsAllocPage(pBuf
6df0: 66 65 72 2c 20 69 2c 20 70 67 73 7a 29 3b 0a 20  fer, i, pgsz);. 
6e00: 20 20 20 20 20 20 20 20 20 69 66 28 20 6e 2d 69           if( n-i
6e10: 2a 70 67 73 7a 3c 70 67 73 7a 20 29 7b 0a 20 20  *pgsz<pgsz ){.  
6e20: 20 20 20 20 20 20 20 20 20 20 6e 42 79 74 65 20            nByte 
6e30: 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = n;.          }
6e40: 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
6e50: 79 28 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65  y(pBuffer->aPage
6e60: 5b 69 5d 2c 20 26 61 5b 69 2a 70 67 73 7a 5d 2c  [i], &a[i*pgsz],
6e70: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20   nByte);.       
6e80: 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20   }.      }..    
6e90: 20 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77    pObj = Tcl_New
6ea0: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f 72  Obj();.      for
6eb0: 28 69 3d 30 3b 20 70 42 75 66 66 65 72 2d 3e 61  (i=0; pBuffer->a
6ec0: 50 61 67 65 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  Page[i]; i++){. 
6ed0: 20 20 20 20 20 20 20 69 6e 74 20 70 67 73 7a 20         int pgsz 
6ee0: 3d 20 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b  = pBuffer->pgsz;
6ef0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 67 73  .        if( pgs
6f00: 7a 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20 33 32  z==0 ) pgsz = 32
6f10: 37 36 38 3b 0a 20 20 20 20 20 20 20 20 54 63 6c  768;.        Tcl
6f20: 5f 41 70 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28  _AppendObjToObj(
6f30: 70 4f 62 6a 2c 20 54 63 6c 5f 4e 65 77 42 79 74  pObj, Tcl_NewByt
6f40: 65 41 72 72 61 79 4f 62 6a 28 70 42 75 66 66 65  eArrayObj(pBuffe
6f50: 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20 70 67 73  r->aPage[i], pgs
6f60: 7a 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  z));.      }.   
6f70: 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73     Tcl_SetObjRes
6f80: 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 4f 62 6a  ult(interp, pObj
6f90: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
6fa0: 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20      }..    case 
6fb0: 43 4d 44 5f 46 49 4c 54 45 52 3a 20 7b 0a 20 20  CMD_FILTER: {.  
6fc0: 20 20 20 20 73 74 61 74 69 63 20 73 74 72 75 63      static struc
6fd0: 74 20 56 66 73 4d 65 74 68 6f 64 20 7b 0a 20 20  t VfsMethod {.  
6fe0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d        char *zNam
6ff0: 65 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6d  e;.        int m
7000: 61 73 6b 3b 0a 20 20 20 20 20 20 7d 20 76 66 73  ask;.      } vfs
7010: 6d 65 74 68 6f 64 20 5b 5d 20 3d 20 7b 0a 20 20  method [] = {.  
7020: 20 20 20 20 20 20 7b 20 22 78 53 68 6d 4f 70 65        { "xShmOpe
7030: 6e 22 2c 20 20 20 20 54 45 53 54 56 46 53 5f 53  n",    TESTVFS_S
7040: 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20  HMOPEN_MASK },. 
7050: 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 4c 6f         { "xShmLo
7060: 63 6b 22 2c 20 20 20 20 54 45 53 54 56 46 53 5f  ck",    TESTVFS_
7070: 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 7d 2c 0a  SHMLOCK_MASK },.
7080: 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 42          { "xShmB
7090: 61 72 72 69 65 72 22 2c 20 54 45 53 54 56 46 53  arrier", TESTVFS
70a0: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
70b0: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
70c0: 53 68 6d 43 6c 6f 73 65 22 2c 20 20 20 54 45 53  ShmClose",   TES
70d0: 54 56 46 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41  TVFS_SHMCLOSE_MA
70e0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
70f0: 22 78 53 68 6d 4d 61 70 22 2c 20 20 20 20 20 54  "xShmMap",     T
7100: 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41  ESTVFS_SHMMAP_MA
7110: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
7120: 22 78 53 79 6e 63 22 2c 20 20 20 20 20 20 20 54  "xSync",       T
7130: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
7140: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
7150: 44 65 6c 65 74 65 22 2c 20 20 20 20 20 54 45 53  Delete",     TES
7160: 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d 41 53 4b  TVFS_DELETE_MASK
7170: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
7180: 57 72 69 74 65 22 2c 20 20 20 20 20 20 54 45 53  Write",      TES
7190: 54 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20  TVFS_WRITE_MASK 
71a0: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 54  },.        { "xT
71b0: 72 75 6e 63 61 74 65 22 2c 20 20 20 54 45 53 54  runcate",   TEST
71c0: 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53  VFS_TRUNCATE_MAS
71d0: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
71e0: 78 4f 70 65 6e 22 2c 20 20 20 20 20 20 20 54 45  xOpen",       TE
71f0: 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20  STVFS_OPEN_MASK 
7200: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 43  },.        { "xC
7210: 6c 6f 73 65 22 2c 20 20 20 20 20 20 54 45 53 54  lose",      TEST
7220: 56 46 53 5f 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d  VFS_CLOSE_MASK }
7230: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 41 63  ,.        { "xAc
7240: 63 65 73 73 22 2c 20 20 20 20 20 54 45 53 54 56  cess",     TESTV
7250: 46 53 5f 41 43 43 45 53 53 5f 4d 41 53 4b 20 7d  FS_ACCESS_MASK }
7260: 2c 0a 20 20 20 20 20 20 7d 3b 0a 20 20 20 20 20  ,.      };.     
7270: 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70 45 6c 65   Tcl_Obj **apEle
7280: 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  m = 0;.      int
7290: 20 6e 45 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20   nElem = 0;.    
72a0: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 69    int i;.      i
72b0: 6e 74 20 6d 61 73 6b 20 3d 20 30 3b 0a 20 20 20  nt mask = 0;.   
72c0: 20 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29     if( objc!=3 )
72d0: 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72  {.        Tcl_Wr
72e0: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
72f0: 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 4c 49 53  p, 2, objv, "LIS
7300: 54 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  T");.        ret
7310: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7320: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
7330: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45   Tcl_ListObjGetE
7340: 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20  lements(interp, 
7350: 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45 6c 65 6d 2c  objv[2], &nElem,
7360: 20 26 61 70 45 6c 65 6d 29 20 29 7b 0a 20 20 20   &apElem) ){.   
7370: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
7380: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
7390: 20 20 20 20 20 54 63 6c 5f 52 65 73 65 74 52 65       Tcl_ResetRe
73a0: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20 20  sult(interp);.  
73b0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
73c0: 45 6c 65 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Elem; i++){.    
73d0: 20 20 20 20 69 6e 74 20 69 4d 65 74 68 6f 64 3b      int iMethod;
73e0: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a  .        char *z
73f0: 45 6c 65 6d 20 3d 20 54 63 6c 5f 47 65 74 53 74  Elem = Tcl_GetSt
7400: 72 69 6e 67 28 61 70 45 6c 65 6d 5b 69 5d 29 3b  ring(apElem[i]);
7410: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 4d 65  .        for(iMe
7420: 74 68 6f 64 3d 30 3b 20 69 4d 65 74 68 6f 64 3c  thod=0; iMethod<
7430: 41 72 72 61 79 53 69 7a 65 28 76 66 73 6d 65 74  ArraySize(vfsmet
7440: 68 6f 64 29 3b 20 69 4d 65 74 68 6f 64 2b 2b 29  hod); iMethod++)
7450: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
7460: 73 74 72 63 6d 70 28 7a 45 6c 65 6d 2c 20 76 66  strcmp(zElem, vf
7470: 73 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d  smethod[iMethod]
7480: 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20  .zName)==0 ){.  
7490: 20 20 20 20 20 20 20 20 20 20 6d 61 73 6b 20 7c            mask |
74a0: 3d 20 76 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74  = vfsmethod[iMet
74b0: 68 6f 64 5d 2e 6d 61 73 6b 3b 0a 20 20 20 20 20  hod].mask;.     
74c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
74d0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
74e0: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20    }.        if( 
74f0: 69 4d 65 74 68 6f 64 3d 3d 41 72 72 61 79 53 69  iMethod==ArraySi
7500: 7a 65 28 76 66 73 6d 65 74 68 6f 64 29 20 29 7b  ze(vfsmethod) ){
7510: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 41  .          Tcl_A
7520: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
7530: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 20 6d 65 74  rp, "unknown met
7540: 68 6f 64 3a 20 22 2c 20 7a 45 6c 65 6d 2c 20 30  hod: ", zElem, 0
7550: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74  );.          ret
7560: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7570: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
7580: 0a 20 20 20 20 20 20 70 2d 3e 6d 61 73 6b 20 3d  .      p->mask =
7590: 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 62 72 65   mask;.      bre
75a0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
75b0: 61 73 65 20 43 4d 44 5f 53 43 52 49 50 54 3a 20  ase CMD_SCRIPT: 
75c0: 7b 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63  {.      if( objc
75d0: 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==3 ){.        i
75e0: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20  nt nByte;.      
75f0: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
7600: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54 63   ){.          Tc
7610: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
7620: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 20 20  ->pScript);.    
7630: 20 20 20 20 20 20 63 6b 66 72 65 65 28 28 63 68        ckfree((ch
7640: 61 72 20 2a 29 70 2d 3e 61 70 53 63 72 69 70 74  ar *)p->apScript
7650: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e  );.          p->
7660: 61 70 53 63 72 69 70 74 20 3d 20 30 3b 0a 20 20  apScript = 0;.  
7670: 20 20 20 20 20 20 20 20 70 2d 3e 6e 53 63 72 69          p->nScri
7680: 70 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  pt = 0;.        
7690: 20 20 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 30    p->pScript = 0
76a0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
76b0: 20 20 20 20 54 63 6c 5f 47 65 74 53 74 72 69 6e      Tcl_GetStrin
76c0: 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32 5d  gFromObj(objv[2]
76d0: 2c 20 26 6e 42 79 74 65 29 3b 0a 20 20 20 20 20  , &nByte);.     
76e0: 20 20 20 69 66 28 20 6e 42 79 74 65 3e 30 20 29     if( nByte>0 )
76f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 70  {.          p->p
7700: 53 63 72 69 70 74 20 3d 20 54 63 6c 5f 44 75 70  Script = Tcl_Dup
7710: 6c 69 63 61 74 65 4f 62 6a 28 6f 62 6a 76 5b 32  licateObj(objv[2
7720: 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20 54 63  ]);.          Tc
7730: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70  l_IncrRefCount(p
7740: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 20 20  ->pScript);.    
7750: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73      }.      }els
7760: 65 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b  e if( objc!=2 ){
7770: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f  .        Tcl_Wro
7780: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
7790: 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 53 43 52  , 2, objv, "?SCR
77a0: 49 50 54 3f 22 29 3b 0a 20 20 20 20 20 20 20 20  IPT?");.        
77b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
77c0: 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
77d0: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
77e0: 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20 20  (interp);.      
77f0: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29  if( p->pScript )
7800: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
7810: 74 28 69 6e 74 65 72 70 2c 20 70 2d 3e 70 53 63  t(interp, p->pSc
7820: 72 69 70 74 29 3b 0a 0a 20 20 20 20 20 20 62 72  ript);..      br
7830: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
7840: 2f 2a 0a 20 20 20 20 2a 2a 20 54 45 53 54 56 46  /*.    ** TESTVF
7850: 53 20 69 6f 65 72 72 20 3f 49 46 41 49 4c 20 50  S ioerr ?IFAIL P
7860: 45 52 53 49 53 54 3f 0a 20 20 20 20 2a 2a 0a 20  ERSIST?.    **. 
7870: 20 20 20 2a 2a 20 20 20 57 68 65 72 65 20 49 46     **   Where IF
7880: 41 49 4c 20 69 73 20 61 6e 20 69 6e 74 65 67 65  AIL is an intege
7890: 72 20 61 6e 64 20 50 45 52 53 49 53 54 20 69 73  r and PERSIST is
78a0: 20 62 6f 6f 6c 65 61 6e 2e 0a 20 20 20 20 2a 2f   boolean..    */
78b0: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 43 41  .    case CMD_CA
78c0: 4e 54 4f 50 45 4e 45 52 52 3a 0a 20 20 20 20 63  NTOPENERR:.    c
78d0: 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a 0a 20  ase CMD_IOERR:. 
78e0: 20 20 20 63 61 73 65 20 43 4d 44 5f 46 55 4c 4c     case CMD_FULL
78f0: 45 52 52 3a 20 7b 0a 20 20 20 20 20 20 54 65 73  ERR: {.      Tes
7900: 74 46 61 75 6c 74 49 6e 6a 65 63 74 20 2a 70 54  tFaultInject *pT
7910: 65 73 74 3b 0a 20 20 20 20 20 20 69 6e 74 20 69  est;.      int i
7920: 52 65 74 3b 0a 0a 20 20 20 20 20 20 73 77 69 74  Ret;..      swit
7930: 63 68 28 20 61 53 75 62 63 6d 64 5b 69 5d 2e 65  ch( aSubcmd[i].e
7940: 43 6d 64 20 29 7b 0a 20 20 20 20 20 20 20 20 63  Cmd ){.        c
7950: 61 73 65 20 43 4d 44 5f 49 4f 45 52 52 3a 20 70  ase CMD_IOERR: p
7960: 54 65 73 74 20 3d 20 26 70 2d 3e 69 6f 65 72 72  Test = &p->ioerr
7970: 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a 20 20 20  _err; break;.   
7980: 20 20 20 20 20 63 61 73 65 20 43 4d 44 5f 46 55       case CMD_FU
7990: 4c 4c 45 52 52 3a 20 70 54 65 73 74 20 3d 20 26  LLERR: pTest = &
79a0: 70 2d 3e 66 75 6c 6c 5f 65 72 72 3b 20 62 72 65  p->full_err; bre
79b0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
79c0: 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52   CMD_CANTOPENERR
79d0: 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 63 61  : pTest = &p->ca
79e0: 6e 74 6f 70 65 6e 5f 65 72 72 3b 20 62 72 65 61  ntopen_err; brea
79f0: 6b 3b 0a 20 20 20 20 20 20 20 20 64 65 66 61 75  k;.        defau
7a00: 6c 74 3a 20 61 73 73 65 72 74 28 30 29 3b 0a 20  lt: assert(0);. 
7a10: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 52 65       }.      iRe
7a20: 74 20 3d 20 70 54 65 73 74 2d 3e 6e 46 61 69 6c  t = pTest->nFail
7a30: 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d 3e 6e  ;.      pTest->n
7a40: 46 61 69 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20  Fail = 0;.      
7a50: 70 54 65 73 74 2d 3e 65 46 61 75 6c 74 20 3d 20  pTest->eFault = 
7a60: 30 3b 0a 20 20 20 20 20 20 70 54 65 73 74 2d 3e  0;.      pTest->
7a70: 69 43 6e 74 20 3d 20 30 3b 0a 0a 20 20 20 20 20  iCnt = 0;..     
7a80: 20 69 66 28 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a   if( objc==4 ){.
7a90: 20 20 20 20 20 20 20 20 69 6e 74 20 69 43 6e 74          int iCnt
7aa0: 2c 20 69 50 65 72 73 69 73 74 3b 0a 20 20 20 20  , iPersist;.    
7ab0: 20 20 20 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d      if( TCL_OK!=
7ac0: 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62  Tcl_GetIntFromOb
7ad0: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32  j(interp, objv[2
7ae0: 5d 2c 20 26 69 43 6e 74 29 0a 20 20 20 20 20 20  ], &iCnt).      
7af0: 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b 21 3d 54 63     || TCL_OK!=Tc
7b00: 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d  l_GetBooleanFrom
7b10: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
7b20: 5b 33 5d 2c 20 26 69 50 65 72 73 69 73 74 29 0a  [3], &iPersist).
7b30: 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20          ){.     
7b40: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
7b50: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d  ERROR;.        }
7b60: 0a 20 20 20 20 20 20 20 20 70 54 65 73 74 2d 3e  .        pTest->
7b70: 65 46 61 75 6c 74 20 3d 20 69 50 65 72 73 69 73  eFault = iPersis
7b80: 74 3f 46 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 50  t?FAULT_INJECT_P
7b90: 45 52 53 49 53 54 45 4e 54 3a 46 41 55 4c 54 5f  ERSISTENT:FAULT_
7ba0: 49 4e 4a 45 43 54 5f 54 52 41 4e 53 49 45 4e 54  INJECT_TRANSIENT
7bb0: 3b 0a 20 20 20 20 20 20 20 20 70 54 65 73 74 2d  ;.        pTest-
7bc0: 3e 69 43 6e 74 20 3d 20 69 43 6e 74 3b 0a 20 20  >iCnt = iCnt;.  
7bd0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 6f 62      }else if( ob
7be0: 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 20 20 20  jc!=2 ){.       
7bf0: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
7c00: 73 28 69 6e 74 65 72 70 2c 20 32 2c 20 6f 62 6a  s(interp, 2, obj
7c10: 76 2c 20 22 3f 43 4e 54 20 50 45 52 53 49 53 54  v, "?CNT PERSIST
7c20: 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  ?");.        ret
7c30: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7c40: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c       }.      Tcl
7c50: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
7c60: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  terp, Tcl_NewInt
7c70: 4f 62 6a 28 69 52 65 74 29 29 3b 0a 20 20 20 20  Obj(iRet));.    
7c80: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
7c90: 20 20 20 20 63 61 73 65 20 43 4d 44 5f 44 45 4c      case CMD_DEL
7ca0: 45 54 45 3a 20 7b 0a 20 20 20 20 20 20 54 63 6c  ETE: {.      Tcl
7cb0: 5f 44 65 6c 65 74 65 43 6f 6d 6d 61 6e 64 28 69  _DeleteCommand(i
7cc0: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74  nterp, Tcl_GetSt
7cd0: 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 29 3b 0a  ring(objv[0]));.
7ce0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
7cf0: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44   }..    case CMD
7d00: 5f 44 45 56 43 48 41 52 3a 20 7b 0a 20 20 20 20  _DEVCHAR: {.    
7d10: 20 20 73 74 72 75 63 74 20 44 65 76 69 63 65 46    struct DeviceF
7d20: 6c 61 67 20 7b 0a 20 20 20 20 20 20 20 20 63 68  lag {.        ch
7d30: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
7d40: 20 20 20 69 6e 74 20 69 56 61 6c 75 65 3b 0a 20     int iValue;. 
7d50: 20 20 20 20 20 7d 20 61 46 6c 61 67 5b 5d 20 3d       } aFlag[] =
7d60: 20 7b 0a 20 20 20 20 20 20 20 20 7b 20 22 64 65   {.        { "de
7d70: 66 61 75 6c 74 22 2c 20 20 20 20 20 20 20 20 20  fault",         
7d80: 20 20 20 20 20 20 2d 31 20 7d 2c 0a 20 20 20 20        -1 },.    
7d90: 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 22 2c 20      { "atomic", 
7da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
7db0: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d  QLITE_IOCAP_ATOM
7dc0: 49 43 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20  IC      },.     
7dd0: 20 20 20 7b 20 22 61 74 6f 6d 69 63 35 31 32 22     { "atomic512"
7de0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51  ,             SQ
7df0: 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49  LITE_IOCAP_ATOMI
7e00: 43 35 31 32 20 20 20 7d 2c 0a 20 20 20 20 20 20  C512   },.      
7e10: 20 20 7b 20 22 61 74 6f 6d 69 63 31 6b 22 2c 20    { "atomic1k", 
7e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
7e30: 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43  ITE_IOCAP_ATOMIC
7e40: 31 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20  1K    },.       
7e50: 20 7b 20 22 61 74 6f 6d 69 63 32 6b 22 2c 20 20   { "atomic2k",  
7e60: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7e70: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 32  TE_IOCAP_ATOMIC2
7e80: 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20  K    },.        
7e90: 7b 20 22 61 74 6f 6d 69 63 34 6b 22 2c 20 20 20  { "atomic4k",   
7ea0: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
7eb0: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 34 4b  E_IOCAP_ATOMIC4K
7ec0: 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b      },.        {
7ed0: 20 22 61 74 6f 6d 69 63 38 6b 22 2c 20 20 20 20   "atomic8k",    
7ee0: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7ef0: 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 38 4b 20  _IOCAP_ATOMIC8K 
7f00: 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20     },.        { 
7f10: 22 61 74 6f 6d 69 63 31 36 6b 22 2c 20 20 20 20  "atomic16k",    
7f20: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7f30: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 31 36 4b 20  IOCAP_ATOMIC16K 
7f40: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22    },.        { "
7f50: 61 74 6f 6d 69 63 33 32 6b 22 2c 20 20 20 20 20  atomic32k",     
7f60: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49          SQLITE_I
7f70: 4f 43 41 50 5f 41 54 4f 4d 49 43 33 32 4b 20 20  OCAP_ATOMIC32K  
7f80: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61   },.        { "a
7f90: 74 6f 6d 69 63 36 34 6b 22 2c 20 20 20 20 20 20  tomic64k",      
7fa0: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f         SQLITE_IO
7fb0: 43 41 50 5f 41 54 4f 4d 49 43 36 34 4b 20 20 20  CAP_ATOMIC64K   
7fc0: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 73 65  },.        { "se
7fd0: 71 75 65 6e 74 69 61 6c 22 2c 20 20 20 20 20 20  quential",      
7fe0: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
7ff0: 41 50 5f 53 45 51 55 45 4e 54 49 41 4c 20 20 7d  AP_SEQUENTIAL  }
8000: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 73 61 66  ,.        { "saf
8010: 65 5f 61 70 70 65 6e 64 22 2c 20 20 20 20 20 20  e_append",      
8020: 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41       SQLITE_IOCA
8030: 50 5f 53 41 46 45 5f 41 50 50 45 4e 44 20 7d 2c  P_SAFE_APPEND },
8040: 0a 20 20 20 20 20 20 20 20 7b 20 22 75 6e 64 65  .        { "unde
8050: 6c 65 74 61 62 6c 65 5f 77 68 65 6e 5f 6f 70 65  letable_when_ope
8060: 6e 22 2c 20 53 51 4c 49 54 45 5f 49 4f 43 41 50  n", SQLITE_IOCAP
8070: 5f 55 4e 44 45 4c 45 54 41 42 4c 45 5f 57 48 45  _UNDELETABLE_WHE
8080: 4e 5f 4f 50 45 4e 20 7d 2c 0a 20 20 20 20 20 20  N_OPEN },.      
8090: 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 20 20 20    { 0, 0 }.     
80a0: 20 7d 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62   };.      Tcl_Ob
80b0: 6a 20 2a 70 52 65 74 3b 0a 20 20 20 20 20 20 69  j *pRet;.      i
80c0: 6e 74 20 69 46 6c 61 67 3b 0a 0a 20 20 20 20 20  nt iFlag;..     
80d0: 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20   if( objc>3 ){. 
80e0: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
80f0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
8100: 32 2c 20 6f 62 6a 76 2c 20 22 3f 41 54 54 52 2d  2, objv, "?ATTR-
8110: 4c 49 53 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  LIST?");.       
8120: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8130: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
8140: 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a   if( objc==3 ){.
8150: 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b 0a 20          int j;. 
8160: 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65 77 20         int iNew 
8170: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 54 63 6c  = 0;.        Tcl
8180: 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73 20 3d 20 30  _Obj **flags = 0
8190: 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 46  ;.        int nF
81a0: 6c 61 67 73 20 3d 20 30 3b 0a 0a 20 20 20 20 20  lags = 0;..     
81b0: 20 20 20 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f     if( Tcl_ListO
81c0: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e  bjGetElements(in
81d0: 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26  terp, objv[2], &
81e0: 6e 46 6c 61 67 73 2c 20 26 66 6c 61 67 73 29 20  nFlags, &flags) 
81f0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74  ){.          ret
8200: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
8210: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
8220: 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 46 6c    for(j=0; j<nFl
8230: 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  ags; j++){.     
8240: 20 20 20 20 20 69 6e 74 20 69 64 78 20 3d 20 30       int idx = 0
8250: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
8260: 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d  Tcl_GetIndexFrom
8270: 4f 62 6a 53 74 72 75 63 74 28 69 6e 74 65 72 70  ObjStruct(interp
8280: 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20 61 46 6c 61  , flags[j], aFla
8290: 67 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  g, .            
82a0: 20 20 20 20 73 69 7a 65 6f 66 28 61 46 6c 61 67      sizeof(aFlag
82b0: 5b 30 5d 29 2c 20 22 66 6c 61 67 22 2c 20 30 2c  [0]), "flag", 0,
82c0: 20 26 69 64 78 29 20 0a 20 20 20 20 20 20 20 20   &idx) .        
82d0: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20    ){.           
82e0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
82f0: 52 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  R;.          }. 
8300: 20 20 20 20 20 20 20 20 20 69 66 28 20 61 46 6c           if( aFl
8310: 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3c 30  ag[idx].iValue<0
8320: 20 26 26 20 6e 46 6c 61 67 73 3e 31 20 29 7b 0a   && nFlags>1 ){.
8330: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
8340: 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74  AppendResult(int
8350: 65 72 70 2c 20 22 62 61 64 20 66 6c 61 67 73 3a  erp, "bad flags:
8360: 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e   ", Tcl_GetStrin
8370: 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a  g(objv[2]), 0);.
8380: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
8390: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
83a0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
83b0: 20 20 20 20 69 4e 65 77 20 7c 3d 20 61 46 6c 61      iNew |= aFla
83c0: 67 5b 69 64 78 5d 2e 69 56 61 6c 75 65 3b 0a 20  g[idx].iValue;. 
83d0: 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
83e0: 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20 3d 20    p->iDevchar = 
83f0: 69 4e 65 77 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  iNew;.      }.. 
8400: 20 20 20 20 20 70 52 65 74 20 3d 20 54 63 6c 5f       pRet = Tcl_
8410: 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20  NewObj();.      
8420: 66 6f 72 28 69 46 6c 61 67 3d 30 3b 20 69 46 6c  for(iFlag=0; iFl
8430: 61 67 3c 73 69 7a 65 6f 66 28 61 46 6c 61 67 29  ag<sizeof(aFlag)
8440: 2f 73 69 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d  /sizeof(aFlag[0]
8450: 29 3b 20 69 46 6c 61 67 2b 2b 29 7b 0a 20 20 20  ); iFlag++){.   
8460: 20 20 20 20 20 69 66 28 20 70 2d 3e 69 44 65 76       if( p->iDev
8470: 63 68 61 72 20 26 20 61 46 6c 61 67 5b 69 46 6c  char & aFlag[iFl
8480: 61 67 5d 2e 69 56 61 6c 75 65 20 29 7b 0a 20 20  ag].iValue ){.  
8490: 20 20 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74          Tcl_List
84a0: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
84b0: 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (.              
84c0: 69 6e 74 65 72 70 2c 20 70 52 65 74 2c 20 54 63  interp, pRet, Tc
84d0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61  l_NewStringObj(a
84e0: 46 6c 61 67 5b 69 46 6c 61 67 5d 2e 7a 4e 61 6d  Flag[iFlag].zNam
84f0: 65 2c 20 2d 31 29 0a 20 20 20 20 20 20 20 20 20  e, -1).         
8500: 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   );.        }.  
8510: 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f      }.      Tcl_
8520: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
8530: 65 72 70 2c 20 70 52 65 74 29 3b 0a 0a 20 20 20  erp, pRet);..   
8540: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
8550: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 53 45  .    case CMD_SE
8560: 43 54 4f 52 53 49 5a 45 3a 20 7b 0a 20 20 20 20  CTORSIZE: {.    
8570: 20 20 69 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a    if( objc>3 ){.
8580: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
8590: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
85a0: 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 56 41 4c 55   2, objv, "?VALU
85b0: 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  E?");.        re
85c0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
85d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
85e0: 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20  ( objc==3 ){.   
85f0: 20 20 20 20 20 69 6e 74 20 69 4e 65 77 20 3d 20       int iNew = 
8600: 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 54  0;.        if( T
8610: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
8620: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d  (interp, objv[2]
8630: 2c 20 26 69 4e 65 77 29 20 29 7b 0a 20 20 20 20  , &iNew) ){.    
8640: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
8650: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20  _ERROR;.        
8660: 7d 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 53 65  }.        p->iSe
8670: 63 74 6f 72 73 69 7a 65 20 3d 20 69 4e 65 77 3b  ctorsize = iNew;
8680: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 54  .      }.      T
8690: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
86a0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49  interp, Tcl_NewI
86b0: 6e 74 4f 62 6a 28 70 2d 3e 69 53 65 63 74 6f 72  ntObj(p->iSector
86c0: 73 69 7a 65 29 29 3b 0a 20 20 20 20 20 20 62 72  size));.      br
86d0: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  eak;.    }.  }..
86e0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
86f0: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
8700: 74 65 73 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 28  testvfs_obj_del(
8710: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 29 7b 0a  ClientData cd){.
8720: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
8730: 54 65 73 74 76 66 73 20 2a 29 63 64 3b 0a 20 20  Testvfs *)cd;.  
8740: 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29  if( p->pScript )
8750: 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e   Tcl_DecrRefCoun
8760: 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20  t(p->pScript);. 
8770: 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72   sqlite3_vfs_unr
8780: 65 67 69 73 74 65 72 28 70 2d 3e 70 56 66 73 29  egister(p->pVfs)
8790: 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61 72  ;.  ckfree((char
87a0: 20 2a 29 70 2d 3e 61 70 53 63 72 69 70 74 29 3b   *)p->apScript);
87b0: 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20  .  ckfree((char 
87c0: 2a 29 70 2d 3e 70 56 66 73 29 3b 0a 20 20 63 6b  *)p->pVfs);.  ck
87d0: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 29 3b  free((char *)p);
87e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a  .}../*.** Usage:
87f0: 20 20 74 65 73 74 76 66 73 20 56 46 53 4e 41 4d    testvfs VFSNAM
8800: 45 20 3f 53 57 49 54 43 48 45 53 3f 0a 2a 2a 0a  E ?SWITCHES?.**.
8810: 2a 2a 20 53 77 69 74 63 68 65 73 20 61 72 65 3a  ** Switches are:
8820: 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d 20  .**.**   -noshm 
8830: 20 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20    BOOLEAN       
8840: 20 20 20 20 20 20 28 54 72 75 65 20 74 6f 20 6f        (True to o
8850: 6d 69 74 20 73 68 6d 20 6d 65 74 68 6f 64 73 2e  mit shm methods.
8860: 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a   Default false).
8870: 2a 2a 20 20 20 2d 64 65 66 61 75 6c 74 20 42 4f  **   -default BO
8880: 4f 4c 45 41 4e 20 20 20 20 20 20 20 20 20 20 20  OLEAN           
8890: 20 20 28 54 72 75 65 20 74 6f 20 6d 61 6b 65 20    (True to make 
88a0: 74 68 65 20 76 66 73 20 64 65 66 61 75 6c 74 2e  the vfs default.
88b0: 20 44 65 66 61 75 6c 74 20 66 61 6c 73 65 29 0a   Default false).
88c0: 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 6f 6d 6d 61  **.** This comma
88d0: 6e 64 20 63 72 65 61 74 65 73 20 74 77 6f 20 74  nd creates two t
88e0: 68 69 6e 67 73 20 77 68 65 6e 20 69 74 20 69 73  hings when it is
88f0: 20 69 6e 76 6f 6b 65 64 3a 20 61 6e 20 53 51 4c   invoked: an SQL
8900: 69 74 65 20 56 46 53 2c 20 61 6e 64 0a 2a 2a 20  ite VFS, and.** 
8910: 61 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20 42  a Tcl command. B
8920: 6f 74 68 20 61 72 65 20 6e 61 6d 65 64 20 56 46  oth are named VF
8930: 53 4e 41 4d 45 2e 20 54 68 65 20 56 46 53 20 69  SNAME. The VFS i
8940: 73 20 69 6e 73 74 61 6c 6c 65 64 2e 20 49 74 20  s installed. It 
8950: 69 73 20 6e 6f 74 0a 2a 2a 20 69 6e 73 74 61 6c  is not.** instal
8960: 6c 65 64 20 61 73 20 74 68 65 20 64 65 66 61 75  led as the defau
8970: 6c 74 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 54 68  lt VFS..**.** Th
8980: 65 20 56 46 53 20 70 61 73 73 65 73 20 61 6c 6c  e VFS passes all
8990: 20 66 69 6c 65 20 49 2f 4f 20 63 61 6c 6c 73 20   file I/O calls 
89a0: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 75  through to the u
89b0: 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 2e 0a 2a  nderlying VFS..*
89c0: 2a 0a 2a 2a 20 57 68 65 6e 65 76 65 72 20 74 68  *.** Whenever th
89d0: 65 20 78 53 68 6d 4d 61 70 20 6d 65 74 68 6f 64  e xShmMap method
89e0: 20 6f 66 20 74 68 65 20 56 46 53 0a 2a 2a 20 69   of the VFS.** i
89f0: 73 20 69 6e 76 6f 6b 65 64 2c 20 74 68 65 20 53  s invoked, the S
8a00: 43 52 49 50 54 20 69 73 20 65 78 65 63 75 74 65  CRIPT is execute
8a10: 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a  d as follows:.**
8a20: 0a 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53 68  .**   SCRIPT xSh
8a30: 6d 4d 61 70 20 20 20 20 46 49 4c 45 4e 41 4d 45  mMap    FILENAME
8a40: 20 49 44 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61   ID.**.** The va
8a50: 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  lue returned by 
8a60: 74 68 65 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f  the invocation o
8a70: 66 20 53 43 52 49 50 54 20 61 62 6f 76 65 20 69  f SCRIPT above i
8a80: 73 20 69 6e 74 65 72 70 72 65 74 65 64 20 61 73  s interpreted as
8a90: 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72  .** an SQLite er
8aa0: 72 6f 72 20 63 6f 64 65 20 61 6e 64 20 72 65 74  ror code and ret
8ab0: 75 72 6e 65 64 20 74 6f 20 53 51 4c 69 74 65 2e  urned to SQLite.
8ac0: 20 45 69 74 68 65 72 20 61 20 73 79 6d 62 6f 6c   Either a symbol
8ad0: 69 63 20 0a 2a 2a 20 22 53 51 4c 49 54 45 5f 4f  ic .** "SQLITE_O
8ae0: 4b 22 20 6f 72 20 6e 75 6d 65 72 69 63 20 22 30  K" or numeric "0
8af0: 22 20 76 61 6c 75 65 20 6d 61 79 20 62 65 20 72  " value may be r
8b00: 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  eturned..**.** T
8b10: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
8b20: 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79  he shared-memory
8b30: 20 62 75 66 66 65 72 20 61 73 73 6f 63 69 61 74   buffer associat
8b40: 65 64 20 77 69 74 68 20 61 20 67 69 76 65 6e 20  ed with a given 
8b50: 66 69 6c 65 0a 2a 2a 20 6d 61 79 20 62 65 20 72  file.** may be r
8b60: 65 61 64 20 61 6e 64 20 73 65 74 20 75 73 69 6e  ead and set usin
8b70: 67 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  g the following 
8b80: 63 6f 6d 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20  command:.**.**  
8b90: 20 56 46 53 4e 41 4d 45 20 73 68 6d 20 46 49 4c   VFSNAME shm FIL
8ba0: 45 4e 41 4d 45 20 3f 4e 45 57 56 41 4c 55 45 3f  ENAME ?NEWVALUE?
8bb0: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20  .**.** When the 
8bc0: 78 53 68 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64 20  xShmLock method 
8bd0: 69 73 20 69 6e 76 6f 6b 65 64 20 62 79 20 53 51  is invoked by SQ
8be0: 4c 69 74 65 2c 20 74 68 65 20 66 6f 6c 6c 6f 77  Lite, the follow
8bf0: 69 6e 67 20 73 63 72 69 70 74 20 69 73 0a 2a 2a  ing script is.**
8c00: 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43   run:.**.**   SC
8c10: 52 49 50 54 20 78 53 68 6d 4c 6f 63 6b 20 20 20  RIPT xShmLock   
8c20: 20 46 49 4c 45 4e 41 4d 45 20 49 44 20 4c 4f 43   FILENAME ID LOC
8c30: 4b 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 4c 4f  K.**.** where LO
8c40: 43 4b 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72  CK is of the for
8c50: 6d 20 22 4f 46 46 53 45 54 20 4e 42 59 54 45 20  m "OFFSET NBYTE 
8c60: 6c 6f 63 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61 72  lock/unlock shar
8c70: 65 64 2f 65 78 63 6c 75 73 69 76 65 22 0a 2a 2f  ed/exclusive".*/
8c80: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
8c90: 76 66 73 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e  vfs_cmd(.  Clien
8ca0: 74 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f  tData cd,.  Tcl_
8cb0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
8cc0: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
8cd0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
8ce0: 76 5b 5d 0a 29 7b 0a 20 20 73 74 61 74 69 63 20  v[].){.  static 
8cf0: 73 71 6c 69 74 65 33 5f 76 66 73 20 74 76 66 73  sqlite3_vfs tvfs
8d00: 5f 76 66 73 20 3d 20 7b 0a 20 20 20 20 32 2c 20  _vfs = {.    2, 
8d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
8d30: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c  ersion */.    0,
8d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
8d60: 7a 4f 73 46 69 6c 65 20 2a 2f 0a 20 20 20 20 30  zOsFile */.    0
8d70: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8d90: 6d 78 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20  mxPathname */.  
8da0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
8db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8dc0: 2f 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20  /* pNext */.    
8dd0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
8de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8df0: 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c   zName */.    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 20 20 20 20 20 2f 2a 20 70              /* p
8e20: 41 70 70 44 61 74 61 20 2a 2f 0a 20 20 20 20 74  AppData */.    t
8e30: 76 66 73 4f 70 65 6e 2c 20 20 20 20 20 20 20 20  vfsOpen,        
8e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8e50: 78 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66  xOpen */.    tvf
8e60: 73 44 65 6c 65 74 65 2c 20 20 20 20 20 20 20 20  sDelete,        
8e70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
8e80: 65 6c 65 74 65 20 2a 2f 0a 20 20 20 20 74 76 66  elete */.    tvf
8e90: 73 41 63 63 65 73 73 2c 20 20 20 20 20 20 20 20  sAccess,        
8ea0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41             /* xA
8eb0: 63 63 65 73 73 20 2a 2f 0a 20 20 20 20 74 76 66  ccess */.    tvf
8ec0: 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20  sFullPathname,  
8ed0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
8ee0: 75 6c 6c 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 23  ullPathname */.#
8ef0: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
8f00: 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f  IT_LOAD_EXTENSIO
8f10: 4e 0a 20 20 20 20 74 76 66 73 44 6c 4f 70 65 6e  N.    tvfsDlOpen
8f20: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8f30: 20 20 20 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a      /* xDlOpen *
8f40: 2f 0a 20 20 20 20 74 76 66 73 44 6c 45 72 72 6f  /.    tvfsDlErro
8f50: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
8f60: 20 20 20 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20      /* xDlError 
8f70: 2a 2f 0a 20 20 20 20 74 76 66 73 44 6c 53 79 6d  */.    tvfsDlSym
8f80: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8f90: 20 20 20 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a       /* xDlSym *
8fa0: 2f 0a 20 20 20 20 74 76 66 73 44 6c 43 6c 6f 73  /.    tvfsDlClos
8fb0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
8fc0: 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20      /* xDlClose 
8fd0: 2a 2f 0a 23 65 6c 73 65 0a 20 20 20 20 30 2c 20  */.#else.    0, 
8fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ff0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
9000: 6c 4f 70 65 6e 20 2a 2f 0a 20 20 20 20 30 2c 20  lOpen */.    0, 
9010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9020: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
9030: 6c 45 72 72 6f 72 20 2a 2f 0a 20 20 20 20 30 2c  lError */.    0,
9040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9050: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9060: 44 6c 53 79 6d 20 2a 2f 0a 20 20 20 20 30 2c 20  DlSym */.    0, 
9070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9080: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44             /* xD
9090: 6c 43 6c 6f 73 65 20 2a 2f 0a 23 65 6e 64 69 66  lClose */.#endif
90a0: 20 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f   /* SQLITE_OMIT_
90b0: 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a  LOAD_EXTENSION *
90c0: 2f 0a 20 20 20 20 74 76 66 73 52 61 6e 64 6f 6d  /.    tvfsRandom
90d0: 6e 65 73 73 2c 20 20 20 20 20 20 20 20 20 20 20  ness,           
90e0: 20 20 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e 65      /* xRandomne
90f0: 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 53 6c  ss */.    tvfsSl
9100: 65 65 70 2c 20 20 20 20 20 20 20 20 20 20 20 20  eep,            
9110: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 6c 65 65          /* xSlee
9120: 70 20 2a 2f 0a 20 20 20 20 74 76 66 73 43 75 72  p */.    tvfsCur
9130: 72 65 6e 74 54 69 6d 65 2c 20 20 20 20 20 20 20  rentTime,       
9140: 20 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65         /* xCurre
9150: 6e 74 54 69 6d 65 20 2a 2f 0a 20 20 20 20 30 2c  ntTime */.    0,
9160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9170: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
9180: 47 65 74 4c 61 73 74 45 72 72 6f 72 20 2a 2f 0a  GetLastError */.
9190: 20 20 20 20 30 2c 0a 20 20 20 20 30 2c 0a 20 20      0,.    0,.  
91a0: 7d 3b 0a 0a 20 20 54 65 73 74 76 66 73 20 2a 70  };..  Testvfs *p
91b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
91c0: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6f 62 6a        /* New obj
91d0: 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ect */.  sqlite3
91e0: 5f 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20  _vfs *pVfs;     
91f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20           /* New 
9200: 56 46 53 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  VFS */.  char *z
9210: 56 66 73 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65  Vfs;.  int nByte
9220: 3b 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 42 79 74 65 73 20         /* Bytes 
9240: 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f  of space to allo
9250: 63 61 74 65 20 61 74 20 70 20 2a 2f 0a 0a 20 20  cate at p */..  
9260: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 73 4e  int i;.  int isN
9270: 6f 73 68 6d 20 3d 20 30 3b 20 20 20 20 20 20 20  oshm = 0;       
9280: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
9290: 20 69 66 20 2d 6e 6f 73 68 6d 20 69 73 20 70 61   if -noshm is pa
92a0: 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69 73  ssed */.  int is
92b0: 44 65 66 61 75 6c 74 20 3d 20 30 3b 20 20 20 20  Default = 0;    
92c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
92d0: 65 20 69 66 20 2d 64 65 66 61 75 6c 74 20 69 73  e if -default is
92e0: 20 70 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74   passed */.  int
92f0: 20 73 7a 4f 73 46 69 6c 65 20 3d 20 30 3b 20 20   szOsFile = 0;  
9300: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9310: 56 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f 20  Value passed to 
9320: 2d 73 7a 6f 73 66 69 6c 65 20 2a 2f 0a 20 20 69  -szosfile */.  i
9330: 6e 74 20 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20  nt mxPathname = 
9340: 2d 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  -1;            /
9350: 2a 20 56 61 6c 75 65 20 70 61 73 73 65 64 20 74  * Value passed t
9360: 6f 20 2d 6d 78 70 61 74 68 6e 61 6d 65 20 2a 2f  o -mxpathname */
9370: 0a 20 20 69 6e 74 20 69 56 65 72 73 69 6f 6e 20  .  int iVersion 
9380: 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 2;            
9390: 20 20 20 2f 2a 20 56 61 6c 75 65 20 70 61 73 73     /* Value pass
93a0: 65 64 20 74 6f 20 2d 69 76 65 72 73 69 6f 6e 20  ed to -iversion 
93b0: 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32  */..  if( objc<2
93c0: 20 7c 7c 20 30 21 3d 28 6f 62 6a 63 25 32 29 20   || 0!=(objc%2) 
93d0: 29 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b  ) goto bad_args;
93e0: 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6f 62  .  for(i=2; i<ob
93f0: 6a 63 3b 20 69 20 2b 3d 20 32 29 7b 0a 20 20 20  jc; i += 2){.   
9400: 20 69 6e 74 20 6e 53 77 69 74 63 68 3b 0a 20 20   int nSwitch;.  
9410: 20 20 63 68 61 72 20 2a 7a 53 77 69 74 63 68 3b    char *zSwitch;
9420: 0a 20 20 20 20 7a 53 77 69 74 63 68 20 3d 20 54  .    zSwitch = T
9430: 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d  cl_GetStringFrom
9440: 4f 62 6a 28 6f 62 6a 76 5b 69 5d 2c 20 26 6e 53  Obj(objv[i], &nS
9450: 77 69 74 63 68 29 3b 20 0a 0a 20 20 20 20 69 66  witch); ..    if
9460: 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20 30  ( nSwitch>2 && 0
9470: 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 6e 6f 73 68  ==strncmp("-nosh
9480: 6d 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77  m", zSwitch, nSw
9490: 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69  itch) ){.      i
94a0: 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61  f( Tcl_GetBoolea
94b0: 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  nFromObj(interp,
94c0: 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 4e   objv[i+1], &isN
94d0: 6f 73 68 6d 29 20 29 7b 0a 20 20 20 20 20 20 20  oshm) ){.       
94e0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
94f0: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  R;.      }.    }
9500: 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53  .    else if( nS
9510: 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74  witch>2 && 0==st
9520: 72 6e 63 6d 70 28 22 2d 64 65 66 61 75 6c 74 22  rncmp("-default"
9530: 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74  , zSwitch, nSwit
9540: 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ch) ){.      if(
9550: 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46   Tcl_GetBooleanF
9560: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
9570: 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 44 65 66  bjv[i+1], &isDef
9580: 61 75 6c 74 29 20 29 7b 0a 20 20 20 20 20 20 20  ault) ){.       
9590: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
95a0: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  R;.      }.    }
95b0: 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e 53  .    else if( nS
95c0: 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73 74  witch>2 && 0==st
95d0: 72 6e 63 6d 70 28 22 2d 73 7a 6f 73 66 69 6c 65  rncmp("-szosfile
95e0: 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69  ", zSwitch, nSwi
95f0: 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66  tch) ){.      if
9600: 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d  ( Tcl_GetIntFrom
9610: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
9620: 5b 69 2b 31 5d 2c 20 26 73 7a 4f 73 46 69 6c 65  [i+1], &szOsFile
9630: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  ) ){.        ret
9640: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
9650: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
9660: 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63   else if( nSwitc
9670: 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d  h>2 && 0==strncm
9680: 70 28 22 2d 6d 78 70 61 74 68 6e 61 6d 65 22 2c  p("-mxpathname",
9690: 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63   zSwitch, nSwitc
96a0: 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  h) ){.      if( 
96b0: 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62  Tcl_GetIntFromOb
96c0: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69  j(interp, objv[i
96d0: 2b 31 5d 2c 20 26 6d 78 50 61 74 68 6e 61 6d 65  +1], &mxPathname
96e0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  ) ){.        ret
96f0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
9700: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
9710: 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74 63   else if( nSwitc
9720: 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d  h>2 && 0==strncm
9730: 70 28 22 2d 69 76 65 72 73 69 6f 6e 22 2c 20 7a  p("-iversion", z
9740: 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29  Switch, nSwitch)
9750: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63   ){.      if( Tc
9760: 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28  l_GetIntFromObj(
9770: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31  interp, objv[i+1
9780: 5d 2c 20 26 69 56 65 72 73 69 6f 6e 29 20 29 7b  ], &iVersion) ){
9790: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
97a0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
97b0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73   }.    }.    els
97c0: 65 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 62 61  e{.      goto ba
97d0: 64 5f 61 72 67 73 3b 0a 20 20 20 20 7d 0a 20 20  d_args;.    }.  
97e0: 7d 0a 0a 20 20 69 66 28 20 73 7a 4f 73 46 69 6c  }..  if( szOsFil
97f0: 65 3c 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  e<sizeof(Testvfs
9800: 46 69 6c 65 29 20 29 7b 0a 20 20 20 20 73 7a 4f  File) ){.    szO
9810: 73 46 69 6c 65 20 3d 20 73 69 7a 65 6f 66 28 54  sFile = sizeof(T
9820: 65 73 74 76 66 73 46 69 6c 65 29 3b 0a 20 20 7d  estvfsFile);.  }
9830: 0a 0a 20 20 7a 56 66 73 20 3d 20 54 63 6c 5f 47  ..  zVfs = Tcl_G
9840: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
9850: 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a  );.  nByte = siz
9860: 65 6f 66 28 54 65 73 74 76 66 73 29 20 2b 20 73  eof(Testvfs) + s
9870: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 3b 0a 20  trlen(zVfs)+1;. 
9880: 20 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29   p = (Testvfs *)
9890: 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  ckalloc(nByte);.
98a0: 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e    memset(p, 0, n
98b0: 42 79 74 65 29 3b 0a 20 20 70 2d 3e 69 44 65 76  Byte);.  p->iDev
98c0: 63 68 61 72 20 3d 20 2d 31 3b 0a 20 20 70 2d 3e  char = -1;.  p->
98d0: 69 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 2d 31  iSectorsize = -1
98e0: 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20 74  ;..  /* Create t
98f0: 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 63 6f  he new object co
9900: 6d 6d 61 6e 64 20 62 65 66 6f 72 65 20 71 75 65  mmand before que
9910: 72 79 69 6e 67 20 53 51 4c 69 74 65 20 66 6f 72  rying SQLite for
9920: 20 61 20 64 65 66 61 75 6c 74 20 56 46 53 0a 20   a default VFS. 
9930: 20 2a 2a 20 74 6f 20 75 73 65 20 66 6f 72 20 27   ** to use for '
9940: 72 65 61 6c 27 20 49 4f 20 6f 70 65 72 61 74 69  real' IO operati
9950: 6f 6e 73 2e 20 54 68 69 73 20 69 73 20 62 65 63  ons. This is bec
9960: 61 75 73 65 20 63 72 65 61 74 69 6e 67 20 74 68  ause creating th
9970: 65 20 6e 65 77 20 56 46 53 0a 20 20 2a 2a 20 6d  e new VFS.  ** m
9980: 61 79 20 64 65 6c 65 74 65 20 61 6e 20 65 78 69  ay delete an exi
9990: 73 74 69 6e 67 20 5b 74 65 73 74 76 66 73 5d 20  sting [testvfs] 
99a0: 56 46 53 20 6f 66 20 74 68 65 20 73 61 6d 65 20  VFS of the same 
99b0: 6e 61 6d 65 2e 20 49 66 20 73 75 63 68 20 61 20  name. If such a 
99c0: 56 46 53 0a 20 20 2a 2a 20 69 73 20 63 75 72 72  VFS.  ** is curr
99d0: 65 6e 74 6c 79 20 74 68 65 20 64 65 66 61 75 6c  ently the defaul
99e0: 74 2c 20 74 68 65 20 6e 65 77 20 5b 74 65 73 74  t, the new [test
99f0: 76 66 73 5d 20 6d 61 79 20 65 6e 64 20 75 70 20  vfs] may end up 
9a00: 63 61 6c 6c 69 6e 67 20 74 68 65 20 0a 20 20 2a  calling the .  *
9a10: 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 61 20 64  * methods of a d
9a20: 65 6c 65 74 65 64 20 6f 62 6a 65 63 74 2e 0a 20  eleted object.. 
9a30: 20 2a 2f 0a 20 20 54 63 6c 5f 43 72 65 61 74 65   */.  Tcl_Create
9a40: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
9a50: 70 2c 20 7a 56 66 73 2c 20 74 65 73 74 76 66 73  p, zVfs, testvfs
9a60: 5f 6f 62 6a 5f 63 6d 64 2c 20 70 2c 20 74 65 73  _obj_cmd, p, tes
9a70: 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 29 3b 0a 20  tvfs_obj_del);. 
9a80: 20 70 2d 3e 70 50 61 72 65 6e 74 20 3d 20 73 71   p->pParent = sq
9a90: 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28 30  lite3_vfs_find(0
9aa0: 29 3b 0a 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d  );.  p->interp =
9ab0: 20 69 6e 74 65 72 70 3b 0a 0a 20 20 70 2d 3e 7a   interp;..  p->z
9ac0: 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29 26  Name = (char *)&
9ad0: 70 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70  p[1];.  memcpy(p
9ae0: 2d 3e 7a 4e 61 6d 65 2c 20 7a 56 66 73 2c 20 73  ->zName, zVfs, s
9af0: 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 29 3b 0a  trlen(zVfs)+1);.
9b00: 0a 20 20 70 56 66 73 20 3d 20 28 73 71 6c 69 74  .  pVfs = (sqlit
9b10: 65 33 5f 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63  e3_vfs *)ckalloc
9b20: 28 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f  (sizeof(sqlite3_
9b30: 76 66 73 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28  vfs));.  memcpy(
9b40: 70 56 66 73 2c 20 26 74 76 66 73 5f 76 66 73 2c  pVfs, &tvfs_vfs,
9b50: 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f   sizeof(sqlite3_
9b60: 76 66 73 29 29 3b 0a 20 20 70 56 66 73 2d 3e 70  vfs));.  pVfs->p
9b70: 41 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64 20  AppData = (void 
9b80: 2a 29 70 3b 0a 20 20 70 56 66 73 2d 3e 69 56 65  *)p;.  pVfs->iVe
9b90: 72 73 69 6f 6e 20 3d 20 69 56 65 72 73 69 6f 6e  rsion = iVersion
9ba0: 3b 0a 20 20 70 56 66 73 2d 3e 7a 4e 61 6d 65 20  ;.  pVfs->zName 
9bb0: 3d 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 70 56  = p->zName;.  pV
9bc0: 66 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d  fs->mxPathname =
9bd0: 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50   p->pParent->mxP
9be0: 61 74 68 6e 61 6d 65 3b 0a 20 20 69 66 28 20 6d  athname;.  if( m
9bf0: 78 50 61 74 68 6e 61 6d 65 3e 3d 30 20 26 26 20  xPathname>=0 && 
9c00: 6d 78 50 61 74 68 6e 61 6d 65 3c 70 56 66 73 2d  mxPathname<pVfs-
9c10: 3e 6d 78 50 61 74 68 6e 61 6d 65 20 29 7b 0a 20  >mxPathname ){. 
9c20: 20 20 20 70 56 66 73 2d 3e 6d 78 50 61 74 68 6e     pVfs->mxPathn
9c30: 61 6d 65 20 3d 20 6d 78 50 61 74 68 6e 61 6d 65  ame = mxPathname
9c40: 3b 0a 20 20 7d 0a 20 20 70 56 66 73 2d 3e 73 7a  ;.  }.  pVfs->sz
9c50: 4f 73 46 69 6c 65 20 3d 20 73 7a 4f 73 46 69 6c  OsFile = szOsFil
9c60: 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20 3d 20 70  e;.  p->pVfs = p
9c70: 56 66 73 3b 0a 20 20 70 2d 3e 69 73 4e 6f 73 68  Vfs;.  p->isNosh
9c80: 6d 20 3d 20 69 73 4e 6f 73 68 6d 3b 0a 20 20 70  m = isNoshm;.  p
9c90: 2d 3e 6d 61 73 6b 20 3d 20 54 45 53 54 56 46 53  ->mask = TESTVFS
9ca0: 5f 41 4c 4c 5f 4d 41 53 4b 3b 0a 0a 20 20 73 71  _ALL_MASK;..  sq
9cb0: 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74  lite3_vfs_regist
9cc0: 65 72 28 70 56 66 73 2c 20 69 73 44 65 66 61 75  er(pVfs, isDefau
9cd0: 6c 74 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 54  lt);..  return T
9ce0: 43 4c 5f 4f 4b 3b 0a 0a 20 62 61 64 5f 61 72 67  CL_OK;.. bad_arg
9cf0: 73 3a 0a 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  s:.  Tcl_WrongNu
9d00: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
9d10: 20 6f 62 6a 76 2c 20 22 56 46 53 4e 41 4d 45 20   objv, "VFSNAME 
9d20: 3f 2d 6e 6f 73 68 6d 20 42 4f 4f 4c 3f 20 3f 2d  ?-noshm BOOL? ?-
9d30: 64 65 66 61 75 6c 74 20 42 4f 4f 4c 3f 20 3f 2d  default BOOL? ?-
9d40: 6d 78 70 61 74 68 6e 61 6d 65 20 49 4e 54 3f 20  mxpathname INT? 
9d50: 3f 2d 73 7a 6f 73 66 69 6c 65 20 49 4e 54 3f 20  ?-szosfile INT? 
9d60: 3f 2d 69 76 65 72 73 69 6f 6e 20 49 4e 54 3f 22  ?-iversion INT?"
9d70: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
9d80: 45 52 52 4f 52 3b 0a 7d 0a 0a 69 6e 74 20 53 71  ERROR;.}..int Sq
9d90: 6c 69 74 65 74 65 73 74 76 66 73 5f 49 6e 69 74  litetestvfs_Init
9da0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
9db0: 65 72 70 29 7b 0a 20 20 54 63 6c 5f 43 72 65 61  erp){.  Tcl_Crea
9dc0: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
9dd0: 65 72 70 2c 20 22 74 65 73 74 76 66 73 22 2c 20  erp, "testvfs", 
9de0: 74 65 73 74 76 66 73 5f 63 6d 64 2c 20 30 2c 20  testvfs_cmd, 0, 
9df0: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  0);.  return TCL
9e00: 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a     _OK;.}..#endif.