/ Hex Artifact Content
Login

Artifact 702e52636113f6b9721da90ef1bf26e07fff414d:


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 55 6e 6d 61 70 28 73 71 6c 69  vfsShmUnmap(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 4d 61 70 2c 20 20 20    tvfsShmMap,   
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 4d 61 70 20 2a 2f 0a    /* xShmMap */.
1d70: 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c 20 20    tvfsShmLock,  
1d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d90: 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20 2a 2f    /* xShmLock */
1da0: 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72 69 65  .  tvfsShmBarrie
1db0: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
1dc0: 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72 69 65     /* xShmBarrie
1dd0: 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d 55 6e  r */.  tvfsShmUn
1de0: 6d 61 70 20 20 20 20 20 20 20 20 20 20 20 20 20  map             
1df0: 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d 55 6e         /* xShmUn
1e00: 6d 61 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69  map */.};..stati
1e10: 63 20 69 6e 74 20 74 76 66 73 52 65 73 75 6c 74  c int tvfsResult
1e20: 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a 70 2c  Code(Testvfs *p,
1e30: 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 73 74   int *pRc){.  st
1e40: 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b 0a 20  ruct errcode {. 
1e50: 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a 20 20     int eCode;.  
1e60: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43    const char *zC
1e70: 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65 5b 5d  ode;.  } aCode[]
1e80: 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c 49 54   = {.    { SQLIT
1e90: 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c 49 54  E_OK,     "SQLIT
1ea0: 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20 20 20  E_OK"     },.   
1eb0: 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 2c   { SQLITE_ERROR,
1ec0: 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f 52 22    "SQLITE_ERROR"
1ed0: 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49 54    },.    { SQLIT
1ee0: 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c 49 54  E_IOERR,  "SQLIT
1ef0: 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20 20 20  E_IOERR"  },.   
1f00: 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 45 44   { SQLITE_LOCKED
1f10: 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b 45 44  , "SQLITE_LOCKED
1f20: 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c 49 54  " },.    { SQLIT
1f30: 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c 49 54  E_BUSY,   "SQLIT
1f40: 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20 20 7d  E_BUSY"   },.  }
1f50: 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ;..  const char 
1f60: 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20  *z;.  int i;..  
1f70: 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  z = Tcl_GetStrin
1f80: 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72  gResult(p->inter
1f90: 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  p);.  for(i=0; i
1fa0: 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f 64 65  <ArraySize(aCode
1fb0: 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  ); i++){.    if(
1fc0: 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 61 43   0==strcmp(z, aC
1fd0: 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20 29 7b  ode[i].zCode) ){
1fe0: 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 61 43  .      *pRc = aC
1ff0: 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a 20 20  ode[i].eCode;.  
2000: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
2010: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
2020: 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  n 0;.}..static i
2030: 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75  nt tvfsInjectFau
2040: 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e 6a 65  lt(TestFaultInje
2050: 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72 65  ct *p){.  int re
2060: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70 2d 3e  t = 0;.  if( p->
2070: 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20 70 2d  eFault ){.    p-
2080: 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69 66 28  >iCnt--;.    if(
2090: 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c 20 28   p->iCnt==0 || (
20a0: 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70 2d 3e  p->iCnt<0 && p->
20b0: 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f 49 4e  eFault==FAULT_IN
20c0: 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e 54 20  JECT_PERSISTENT 
20d0: 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 20 3d  ) ){.      ret =
20e0: 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e 46 61   1;.      p->nFa
20f0: 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  il++;.    }.  }.
2100: 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a    return ret;.}.
2110: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ..static int tvf
2120: 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54 65 73  sInjectIoerr(Tes
2130: 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75  tvfs *p){.  retu
2140: 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75  rn tvfsInjectFau
2150: 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65 72 72  lt(&p->ioerr_err
2160: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
2170: 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c 65   tvfsInjectFulle
2180: 72 72 28 54 65 73 74 76 66 73 20 2a 70 29 7b 0a  rr(Testvfs *p){.
2190: 20 20 72 65 74 75 72 6e 20 74 76 66 73 49 6e 6a    return tvfsInj
21a0: 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66 75 6c  ectFault(&p->ful
21b0: 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74 69 63  l_err);.}.static
21c0: 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 43   int tvfsInjectC
21d0: 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73 74 76  antopenerr(Testv
21e0: 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e  fs *p){.  return
21f0: 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75 6c 74   tvfsInjectFault
2200: 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65 72  (&p->cantopen_er
2210: 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 76  r);.}...static v
2220: 6f 69 64 20 74 76 66 73 45 78 65 63 54 63 6c 28  oid tvfsExecTcl(
2230: 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c 20 0a  .  Testvfs *p, .
2240: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d    const char *zM
2250: 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f 62 6a  ethod,.  Tcl_Obj
2260: 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f 4f 62   *arg1,.  Tcl_Ob
2270: 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c 5f 4f  j *arg2,.  Tcl_O
2280: 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20 69 6e  bj *arg3.){.  in
2290: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
22a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
22b0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72 6f   Return code fro
22c0: 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28 29 20  m Tcl_EvalObj() 
22d0: 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 3b 20 20  */.  int nArg;  
22e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22f0: 20 20 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74 73       /* Elements
2300: 20 69 6e 20 65 76 61 6c 27 64 20 6c 69 73 74 20   in eval'd list 
2310: 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70 74  */.  int nScript
2320: 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 2a 20 61  ;.  Tcl_Obj ** a
2330: 70 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 2d  p;..  assert( p-
2340: 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a 20 20 69  >pScript );..  i
2350: 66 28 20 21 70 2d 3e 61 70 53 63 72 69 70 74 20  f( !p->apScript 
2360: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65  ){.    int nByte
2370: 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  ;.    int i;.   
2380: 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c   if( TCL_OK!=Tcl
2390: 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65  _ListObjGetEleme
23a0: 6e 74 73 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70  nts(p->interp, p
23b0: 2d 3e 70 53 63 72 69 70 74 2c 20 26 6e 53 63 72  ->pScript, &nScr
23c0: 69 70 74 2c 20 26 61 70 29 20 29 7b 0a 20 20 20  ipt, &ap) ){.   
23d0: 20 20 20 54 63 6c 5f 42 61 63 6b 67 72 6f 75 6e     Tcl_Backgroun
23e0: 64 45 72 72 6f 72 28 70 2d 3e 69 6e 74 65 72 70  dError(p->interp
23f0: 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 52 65 73  );.      Tcl_Res
2400: 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  etResult(p->inte
2410: 72 70 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  rp);.      retur
2420: 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e  n;.    }.    p->
2430: 6e 53 63 72 69 70 74 20 3d 20 6e 53 63 72 69 70  nScript = nScrip
2440: 74 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20 28  t;.    nByte = (
2450: 6e 53 63 72 69 70 74 2b 54 45 53 54 56 46 53 5f  nScript+TESTVFS_
2460: 4d 41 58 5f 41 52 47 53 29 2a 73 69 7a 65 6f 66  MAX_ARGS)*sizeof
2470: 28 54 63 6c 5f 4f 62 6a 20 2a 29 3b 0a 20 20 20  (Tcl_Obj *);.   
2480: 20 70 2d 3e 61 70 53 63 72 69 70 74 20 3d 20 28   p->apScript = (
2490: 54 63 6c 5f 4f 62 6a 20 2a 2a 29 63 6b 61 6c 6c  Tcl_Obj **)ckall
24a0: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 6d  oc(nByte);.    m
24b0: 65 6d 73 65 74 28 70 2d 3e 61 70 53 63 72 69 70  emset(p->apScrip
24c0: 74 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20  t, 0, nByte);.  
24d0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 63    for(i=0; i<nSc
24e0: 72 69 70 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ript; i++){.    
24f0: 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 69 5d    p->apScript[i]
2500: 20 3d 20 61 70 5b 69 5d 3b 0a 20 20 20 20 7d 0a   = ap[i];.    }.
2510: 20 20 7d 0a 0a 20 20 70 2d 3e 61 70 53 63 72 69    }..  p->apScri
2520: 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74 5d 20 3d  pt[p->nScript] =
2530: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
2540: 6a 28 7a 4d 65 74 68 6f 64 2c 20 2d 31 29 3b 0a  j(zMethod, -1);.
2550: 20 20 70 2d 3e 61 70 53 63 72 69 70 74 5b 70 2d    p->apScript[p-
2560: 3e 6e 53 63 72 69 70 74 2b 31 5d 20 3d 20 61 72  >nScript+1] = ar
2570: 67 31 3b 0a 20 20 70 2d 3e 61 70 53 63 72 69 70  g1;.  p->apScrip
2580: 74 5b 70 2d 3e 6e 53 63 72 69 70 74 2b 32 5d 20  t[p->nScript+2] 
2590: 3d 20 61 72 67 32 3b 0a 20 20 70 2d 3e 61 70 53  = arg2;.  p->apS
25a0: 63 72 69 70 74 5b 70 2d 3e 6e 53 63 72 69 70 74  cript[p->nScript
25b0: 2b 33 5d 20 3d 20 61 72 67 33 3b 0a 0a 20 20 66  +3] = arg3;..  f
25c0: 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53 63 72 69  or(nArg=p->nScri
25d0: 70 74 3b 20 70 2d 3e 61 70 53 63 72 69 70 74 5b  pt; p->apScript[
25e0: 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b 29 7b 0a  nArg]; nArg++){.
25f0: 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43      Tcl_IncrRefC
2600: 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72 69 70 74  ount(p->apScript
2610: 5b 6e 41 72 67 5d 29 3b 0a 20 20 7d 0a 0a 20 20  [nArg]);.  }..  
2620: 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a  rc = Tcl_EvalObj
2630: 76 28 70 2d 3e 69 6e 74 65 72 70 2c 20 6e 41 72  v(p->interp, nAr
2640: 67 2c 20 70 2d 3e 61 70 53 63 72 69 70 74 2c 20  g, p->apScript, 
2650: 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c 29  TCL_EVAL_GLOBAL)
2660: 3b 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c 5f  ;.  if( rc!=TCL_
2670: 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42 61  OK ){.    Tcl_Ba
2680: 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70 2d  ckgroundError(p-
2690: 3e 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54 63  >interp);.    Tc
26a0: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d  l_ResetResult(p-
26b0: 3e 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 0a 20  >interp);.  }.. 
26c0: 20 66 6f 72 28 6e 41 72 67 3d 70 2d 3e 6e 53 63   for(nArg=p->nSc
26d0: 72 69 70 74 3b 20 70 2d 3e 61 70 53 63 72 69 70  ript; p->apScrip
26e0: 74 5b 6e 41 72 67 5d 3b 20 6e 41 72 67 2b 2b 29  t[nArg]; nArg++)
26f0: 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52 65  {.    Tcl_DecrRe
2700: 66 43 6f 75 6e 74 28 70 2d 3e 61 70 53 63 72 69  fCount(p->apScri
2710: 70 74 5b 6e 41 72 67 5d 29 3b 0a 20 20 20 20 70  pt[nArg]);.    p
2720: 2d 3e 61 70 53 63 72 69 70 74 5b 6e 41 72 67 5d  ->apScript[nArg]
2730: 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 0a 2f 2a   = 0;.  }.}.../*
2740: 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 74 76 66  .** Close an tvf
2750: 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  s-file..*/.stati
2760: 63 20 69 6e 74 20 74 76 66 73 43 6c 6f 73 65 28  c int tvfsClose(
2770: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2780: 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  ile){.  int rc;.
2790: 20 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70    TestvfsFile *p
27a0: 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73 74  Testfile = (Test
27b0: 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  vfsFile *)pFile;
27c0: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
27d0: 64 20 3d 20 70 54 65 73 74 66 69 6c 65 2d 3e 70  d = pTestfile->p
27e0: 46 64 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  Fd;.  Testvfs *p
27f0: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46   = (Testvfs *)pF
2800: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
2810: 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  a;..  if( p->pSc
2820: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
2830: 54 45 53 54 56 46 53 5f 43 4c 4f 53 45 5f 4d 41  TESTVFS_CLOSE_MA
2840: 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78  SK ){.    tvfsEx
2850: 65 63 54 63 6c 28 70 2c 20 22 78 43 6c 6f 73 65  ecTcl(p, "xClose
2860: 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  ", .        Tcl_
2870: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64  NewStringObj(pFd
2880: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29  ->zFilename, -1)
2890: 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30  , pFd->pShmId, 0
28a0: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 69  .    );.  }..  i
28b0: 66 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 29  f( pFd->pShmId )
28c0: 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52 65  {.    Tcl_DecrRe
28d0: 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70 53 68 6d  fCount(pFd->pShm
28e0: 49 64 29 3b 0a 20 20 20 20 70 46 64 2d 3e 70 53  Id);.    pFd->pS
28f0: 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  hmId = 0;.  }.  
2900: 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68  if( pFile->pMeth
2910: 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b 66 72 65  ods ){.    ckfre
2920: 65 28 28 63 68 61 72 20 2a 29 70 46 69 6c 65 2d  e((char *)pFile-
2930: 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20 20 7d 0a  >pMethods);.  }.
2940: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
2950: 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52 65 61 6c  Close(pFd->pReal
2960: 29 3b 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61  );.  ckfree((cha
2970: 72 20 2a 29 70 46 64 29 3b 0a 20 20 70 54 65 73  r *)pFd);.  pTes
2980: 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 30 3b 0a  tfile->pFd = 0;.
2990: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
29a0: 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61 74 61 20  /*.** Read data 
29b0: 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d 66 69 6c  from an tvfs-fil
29c0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
29d0: 20 74 76 66 73 52 65 61 64 28 0a 20 20 73 71 6c   tvfsRead(.  sql
29e0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
29f0: 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42 75 66 2c  , .  void *zBuf,
2a00: 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 0a 20   .  int iAmt, . 
2a10: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 4f   sqlite_int64 iO
2a20: 66 73 74 0a 29 7b 0a 20 20 54 65 73 74 76 66 73  fst.){.  Testvfs
2a30: 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46  Fd *p = tvfsGetF
2a40: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
2a50: 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64  rn sqlite3OsRead
2a60: 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66 2c  (p->pReal, zBuf,
2a70: 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a 7d   iAmt, iOfst);.}
2a80: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 64 61  ../*.** Write da
2a90: 74 61 20 74 6f 20 61 6e 20 74 76 66 73 2d 66 69  ta to an tvfs-fi
2aa0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2ab0: 74 20 74 76 66 73 57 72 69 74 65 28 0a 20 20 73  t tvfsWrite(.  s
2ac0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2ad0: 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20 76 6f 69  le, .  const voi
2ae0: 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74 20  d *zBuf, .  int 
2af0: 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65 5f  iAmt, .  sqlite_
2b00: 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a 20  int64 iOfst.){. 
2b10: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2b20: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
2b30: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
2b40: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
2b50: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
2b60: 73 20 2a 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70  s *)pFd->pVfs->p
2b70: 41 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20  AppData;..  if( 
2b80: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
2b90: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 57 52  >mask&TESTVFS_WR
2ba0: 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20  ITE_MASK ){.    
2bb0: 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22  tvfsExecTcl(p, "
2bc0: 78 57 72 69 74 65 22 2c 20 0a 20 20 20 20 20 20  xWrite", .      
2bd0: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
2be0: 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  bj(pFd->zFilenam
2bf0: 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68  e, -1), pFd->pSh
2c00: 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20  mId, 0.    );.  
2c10: 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65    tvfsResultCode
2c20: 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20  (p, &rc);.  }.. 
2c30: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
2c40: 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74  OK && tvfsInject
2c50: 46 75 6c 6c 65 72 72 28 70 29 20 29 7b 0a 20 20  Fullerr(p) ){.  
2c60: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55    rc = SQLITE_FU
2c70: 4c 4c 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63  LL;.  }.  if( rc
2c80: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70  ==SQLITE_OK && p
2c90: 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 57  ->mask&TESTVFS_W
2ca0: 52 49 54 45 5f 4d 41 53 4b 20 26 26 20 74 76 66  RITE_MASK && tvf
2cb0: 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 70 29 20  sInjectIoerr(p) 
2cc0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  ){.    rc = SQLI
2cd0: 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 20 20  TE_IOERR;.  }.  
2ce0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
2cf0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
2d00: 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
2d10: 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a 42 75 66  pFd->pReal, zBuf
2d20: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
2d30: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
2d40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e 63 61  .}../*.** Trunca
2d50: 74 65 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  te an tvfs-file.
2d60: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
2d70: 76 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69  vfsTruncate(sqli
2d80: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
2d90: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 73 69   sqlite_int64 si
2da0: 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ze){.  int rc = 
2db0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73  SQLITE_OK;.  Tes
2dc0: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
2dd0: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
2de0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
2df0: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
2e00: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a  Vfs->pAppData;..
2e10: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
2e20: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
2e30: 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53  VFS_TRUNCATE_MAS
2e40: 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65  K ){.    tvfsExe
2e50: 63 54 63 6c 28 70 2c 20 22 78 54 72 75 6e 63 61  cTcl(p, "xTrunca
2e60: 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  te", .        Tc
2e70: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
2e80: 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d  Fd->zFilename, -
2e90: 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c  1), pFd->pShmId,
2ea0: 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76   0.    );.    tv
2eb0: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
2ec0: 26 72 63 29 3b 0a 20 20 7d 0a 20 20 0a 20 20 69  &rc);.  }.  .  i
2ed0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2ee0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2ef0: 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28 70  ite3OsTruncate(p
2f00: 46 64 2d 3e 70 52 65 61 6c 2c 20 73 69 7a 65 29  Fd->pReal, size)
2f10: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
2f20: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63  c;.}../*.** Sync
2f30: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
2f40: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
2f50: 73 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 66 69  sSync(sqlite3_fi
2f60: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 66  le *pFile, int f
2f70: 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20 72 63 20  lags){.  int rc 
2f80: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54  = SQLITE_OK;.  T
2f90: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
2fa0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
2fb0: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
2fc0: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
2fd0: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
2fe0: 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ..  if( p->pScri
2ff0: 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  pt && p->mask&TE
3000: 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b 20  STVFS_SYNC_MASK 
3010: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46 6c  ){.    char *zFl
3020: 61 67 73 3b 0a 0a 20 20 20 20 73 77 69 74 63 68  ags;..    switch
3030: 28 20 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20  ( flags ){.     
3040: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e   case SQLITE_SYN
3050: 43 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20 20 20 20  C_NORMAL:.      
3060: 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e 6f 72 6d    zFlags = "norm
3070: 61 6c 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65  al";.        bre
3080: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53  ak;.      case S
3090: 51 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 3a  QLITE_SYNC_FULL:
30a0: 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73 20  .        zFlags 
30b0: 3d 20 22 66 75 6c 6c 22 3b 0a 20 20 20 20 20 20  = "full";.      
30c0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63    break;.      c
30d0: 61 73 65 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f  ase SQLITE_SYNC_
30e0: 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53 59  NORMAL|SQLITE_SY
30f0: 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a 20 20 20  NC_DATAONLY:.   
3100: 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e       zFlags = "n
3110: 6f 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c 79 22 3b  ormal|dataonly";
3120: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
3130: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
3140: 45 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53 51 4c 49  E_SYNC_FULL|SQLI
3150: 54 45 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c 59  TE_SYNC_DATAONLY
3160: 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73  :.        zFlags
3170: 20 3d 20 22 66 75 6c 6c 7c 64 61 74 61 6f 6e 6c   = "full|dataonl
3180: 79 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  y";.        brea
3190: 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74  k;.      default
31a0: 3a 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  :.        assert
31b0: 28 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  (0);.    }..    
31c0: 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22  tvfsExecTcl(p, "
31d0: 78 53 79 6e 63 22 2c 20 0a 20 20 20 20 20 20 20  xSync", .       
31e0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
31f0: 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65  j(pFd->zFilename
3200: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
3210: 49 64 2c 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  Id,.        Tcl_
3220: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 46 6c  NewStringObj(zFl
3230: 61 67 73 2c 20 2d 31 29 0a 20 20 20 20 29 3b 0a  ags, -1).    );.
3240: 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f      tvfsResultCo
3250: 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a  de(p, &rc);.  }.
3260: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
3270: 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a 65  E_OK && tvfsInje
3280: 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 20 72  ctFullerr(p) ) r
3290: 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3b  c = SQLITE_FULL;
32a0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
32b0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
32c0: 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
32d0: 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c 61 67  pFd->pReal, flag
32e0: 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  s);.  }..  retur
32f0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  n rc;.}../*.** R
3300: 65 74 75 72 6e 20 74 68 65 20 63 75 72 72 65 6e  eturn the curren
3310: 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f 66 20 61  t file-size of a
3320: 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a  n tvfs-file..*/.
3330: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 46  static int tvfsF
3340: 69 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f  ileSize(sqlite3_
3350: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 73 71 6c  file *pFile, sql
3360: 69 74 65 5f 69 6e 74 36 34 20 2a 70 53 69 7a 65  ite_int64 *pSize
3370: 29 7b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  ){.  TestvfsFd *
3380: 70 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  p = tvfsGetFd(pF
3390: 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  ile);.  return s
33a0: 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65  qlite3OsFileSize
33b0: 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53 69 7a 65  (p->pReal, pSize
33c0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63 6b  );.}../*.** Lock
33d0: 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a   an tvfs-file..*
33e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
33f0: 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  sLock(sqlite3_fi
3400: 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 65  le *pFile, int e
3410: 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74 76 66 73  Lock){.  Testvfs
3420: 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46  Fd *p = tvfsGetF
3430: 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75  d(pFile);.  retu
3440: 72 6e 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63 6b  rn sqlite3OsLock
3450: 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c 6f 63 6b  (p->pReal, eLock
3460: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 6e 6c 6f  );.}../*.** Unlo
3470: 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  ck an tvfs-file.
3480: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
3490: 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69 74 65  vfsUnlock(sqlite
34a0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69  3_file *pFile, i
34b0: 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73  nt eLock){.  Tes
34c0: 74 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66 73  tvfsFd *p = tvfs
34d0: 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20  GetFd(pFile);.  
34e0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
34f0: 55 6e 6c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c  Unlock(p->pReal,
3500: 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a   eLock);.}../*.*
3510: 2a 20 43 68 65 63 6b 20 69 66 20 61 6e 6f 74 68  * Check if anoth
3520: 65 72 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 68  er file-handle h
3530: 6f 6c 64 73 20 61 20 52 45 53 45 52 56 45 44 20  olds a RESERVED 
3540: 6c 6f 63 6b 20 6f 6e 20 61 6e 20 74 76 66 73 2d  lock on an tvfs-
3550: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
3560: 69 6e 74 20 74 76 66 73 43 68 65 63 6b 52 65 73  int tvfsCheckRes
3570: 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65  ervedLock(sqlite
3580: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69  3_file *pFile, i
3590: 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20 20  nt *pResOut){.  
35a0: 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74  TestvfsFd *p = t
35b0: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
35c0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
35d0: 33 4f 73 43 68 65 63 6b 52 65 73 65 72 76 65 64  3OsCheckReserved
35e0: 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 70  Lock(p->pReal, p
35f0: 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  ResOut);.}../*.*
3600: 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f 6c 20 6d  * File control m
3610: 65 74 68 6f 64 2e 20 46 6f 72 20 63 75 73 74 6f  ethod. For custo
3620: 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20  m operations on 
3630: 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f  an tvfs-file..*/
3640: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3650: 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c 69  FileControl(sqli
3660: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
3670: 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70   int op, void *p
3680: 41 72 67 29 7b 0a 20 20 54 65 73 74 76 66 73 46  Arg){.  TestvfsF
3690: 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64  d *p = tvfsGetFd
36a0: 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72  (pFile);.  retur
36b0: 6e 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43  n sqlite3OsFileC
36c0: 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65 61 6c 2c  ontrol(p->pReal,
36d0: 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d 0a 0a 2f   op, pArg);.}../
36e0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
36f0: 73 65 63 74 6f 72 2d 73 69 7a 65 20 69 6e 20 62  sector-size in b
3700: 79 74 65 73 20 66 6f 72 20 61 6e 20 74 76 66 73  ytes for an tvfs
3710: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
3720: 20 69 6e 74 20 74 76 66 73 53 65 63 74 6f 72 53   int tvfsSectorS
3730: 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ize(sqlite3_file
3740: 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73 74   *pFile){.  Test
3750: 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66  vfsFd *pFd = tvf
3760: 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20  sGetFd(pFile);. 
3770: 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54   Testvfs *p = (T
3780: 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56  estvfs *)pFd->pV
3790: 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20 20  fs->pAppData;.  
37a0: 69 66 28 20 70 2d 3e 69 53 65 63 74 6f 72 73 69  if( p->iSectorsi
37b0: 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  ze>=0 ){.    ret
37c0: 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f 72 73 69  urn p->iSectorsi
37d0: 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ze;.  }.  return
37e0: 20 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f 72   sqlite3OsSector
37f0: 53 69 7a 65 28 70 46 64 2d 3e 70 52 65 61 6c 29  Size(pFd->pReal)
3800: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
3810: 6e 20 74 68 65 20 64 65 76 69 63 65 20 63 68 61  n the device cha
3820: 72 61 63 74 65 72 69 73 74 69 63 20 66 6c 61 67  racteristic flag
3830: 73 20 73 75 70 70 6f 72 74 65 64 20 62 79 20 61  s supported by a
3840: 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a  n tvfs-file..*/.
3850: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44  static int tvfsD
3860: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
3870: 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69 6c  tics(sqlite3_fil
3880: 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73  e *pFile){.  Tes
3890: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
38a0: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
38b0: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
38c0: 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d 3e 70  Testvfs *)pFd->p
38d0: 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a 20  Vfs->pAppData;. 
38e0: 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61 72   if( p->iDevchar
38f0: 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  >=0 ){.    retur
3900: 6e 20 70 2d 3e 69 44 65 76 63 68 61 72 3b 0a 20  n p->iDevchar;. 
3910: 20 7d 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69   }.  return sqli
3920: 74 65 33 4f 73 44 65 76 69 63 65 43 68 61 72 61  te3OsDeviceChara
3930: 63 74 65 72 69 73 74 69 63 73 28 70 46 64 2d 3e  cteristics(pFd->
3940: 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  pReal);.}../*.**
3950: 20 4f 70 65 6e 20 61 6e 20 74 76 66 73 20 66 69   Open an tvfs fi
3960: 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  le handle..*/.st
3970: 61 74 69 63 20 69 6e 74 20 74 76 66 73 4f 70 65  atic int tvfsOpe
3980: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  n(.  sqlite3_vfs
3990: 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74 20   *pVfs,.  const 
39a0: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73  char *zName,.  s
39b0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
39c0: 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c  le,.  int flags,
39d0: 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67  .  int *pOutFlag
39e0: 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  s.){.  int rc;. 
39f0: 20 54 65 73 74 76 66 73 46 69 6c 65 20 2a 70 54   TestvfsFile *pT
3a00: 65 73 74 66 69 6c 65 20 3d 20 28 54 65 73 74 76  estfile = (Testv
3a10: 66 73 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a  fsFile *)pFile;.
3a20: 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64    TestvfsFd *pFd
3a30: 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 49 64  ;.  Tcl_Obj *pId
3a40: 20 3d 20 30 3b 0a 20 20 54 65 73 74 76 66 73 20   = 0;.  Testvfs 
3a50: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
3a60: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b 0a  pVfs->pAppData;.
3a70: 0a 20 20 70 46 64 20 3d 20 28 54 65 73 74 76 66  .  pFd = (Testvf
3a80: 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63 28 73 69  sFd *)ckalloc(si
3a90: 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64 29 20  zeof(TestvfsFd) 
3aa0: 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  + PARENTVFS(pVfs
3ab0: 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20 20  )->szOsFile);.  
3ac0: 6d 65 6d 73 65 74 28 70 46 64 2c 20 30 2c 20 73  memset(pFd, 0, s
3ad0: 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46 64 29  izeof(TestvfsFd)
3ae0: 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70 56 66   + PARENTVFS(pVf
3af0: 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20  s)->szOsFile);. 
3b00: 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20 30 3b 0a   pFd->pShm = 0;.
3b10: 20 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d 20    pFd->pShmId = 
3b20: 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69 6c 65 6e  0;.  pFd->zFilen
3b30: 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20 70  ame = zName;.  p
3b40: 46 64 2d 3e 70 56 66 73 20 3d 20 70 56 66 73 3b  Fd->pVfs = pVfs;
3b50: 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c 20 3d 20  .  pFd->pReal = 
3b60: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29  (sqlite3_file *)
3b70: 26 70 46 64 5b 31 5d 3b 0a 20 20 70 54 65 73 74  &pFd[1];.  pTest
3b80: 66 69 6c 65 2d 3e 70 46 64 20 3d 20 70 46 64 3b  file->pFd = pFd;
3b90: 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61 74 65 20  ..  /* Evaluate 
3ba0: 74 68 65 20 54 63 6c 20 73 63 72 69 70 74 3a 20  the Tcl script: 
3bb0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 53 43 52  .  **.  **   SCR
3bc0: 49 50 54 20 78 4f 70 65 6e 20 46 49 4c 45 4e 41  IPT xOpen FILENA
3bd0: 4d 45 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20  ME.  **.  ** If 
3be0: 74 68 65 20 73 63 72 69 70 74 20 72 65 74 75 72  the script retur
3bf0: 6e 73 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  ns an SQLite err
3c00: 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 20 74 68  or code other th
3c10: 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 61 6e  an SQLITE_OK, an
3c20: 0a 20 20 2a 2a 20 65 72 72 6f 72 20 69 73 20 72  .  ** error is r
3c30: 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63  eturned to the c
3c40: 61 6c 6c 65 72 2e 20 49 66 20 69 74 20 72 65 74  aller. If it ret
3c50: 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2c 20  urns SQLITE_OK, 
3c60: 74 68 65 20 6e 65 77 0a 20 20 2a 2a 20 63 6f 6e  the new.  ** con
3c70: 6e 65 63 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64  nection is named
3c80: 20 22 61 6e 6f 6e 22 2e 20 4f 74 68 65 72 77 69   "anon". Otherwi
3c90: 73 65 2c 20 74 68 65 20 76 61 6c 75 65 20 72 65  se, the value re
3ca0: 74 75 72 6e 65 64 20 62 79 20 74 68 65 0a 20 20  turned by the.  
3cb0: 2a 2a 20 73 63 72 69 70 74 20 69 73 20 75 73 65  ** script is use
3cc0: 64 20 61 73 20 74 68 65 20 63 6f 6e 6e 65 63 74  d as the connect
3cd0: 69 6f 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20  ion name..  */. 
3ce0: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
3cf0: 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 20 20 69  (p->interp);.  i
3d00: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
3d10: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
3d20: 5f 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20  _OPEN_MASK ){.  
3d30: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
3d40: 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c 5f 4e 65   "xOpen", Tcl_Ne
3d50: 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e  wStringObj(pFd->
3d60: 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20  zFilename, -1), 
3d70: 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 74  0, 0);.    if( t
3d80: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
3d90: 20 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20 69   &rc) ){.      i
3da0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
3db0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
3dc0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70    }else{.      p
3dd0: 49 64 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52  Id = Tcl_GetObjR
3de0: 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29  esult(p->interp)
3df0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
3e00: 66 28 20 28 70 2d 3e 6d 61 73 6b 26 54 45 53 54  f( (p->mask&TEST
3e10: 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 29 20 26  VFS_OPEN_MASK) &
3e20: 26 20 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65  &  tvfsInjectIoe
3e30: 72 72 28 70 29 20 29 20 72 65 74 75 72 6e 20 53  rr(p) ) return S
3e40: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 69  QLITE_IOERR;.  i
3e50: 66 28 20 74 76 66 73 49 6e 6a 65 63 74 43 61 6e  f( tvfsInjectCan
3e60: 74 6f 70 65 6e 65 72 72 28 70 29 20 29 20 72 65  topenerr(p) ) re
3e70: 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 41 4e 54  turn SQLITE_CANT
3e80: 4f 50 45 4e 3b 0a 20 20 69 66 28 20 74 76 66 73  OPEN;.  if( tvfs
3e90: 49 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28 70 29  InjectFullerr(p)
3ea0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
3eb0: 5f 46 55 4c 4c 3b 0a 0a 20 20 69 66 28 20 21 70  _FULL;..  if( !p
3ec0: 49 64 20 29 7b 0a 20 20 20 20 70 49 64 20 3d 20  Id ){.    pId = 
3ed0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
3ee0: 28 22 61 6e 6f 6e 22 2c 20 2d 31 29 3b 0a 20 20  ("anon", -1);.  
3ef0: 7d 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43  }.  Tcl_IncrRefC
3f00: 6f 75 6e 74 28 70 49 64 29 3b 0a 20 20 70 46 64  ount(pId);.  pFd
3f10: 2d 3e 70 53 68 6d 49 64 20 3d 20 70 49 64 3b 0a  ->pShmId = pId;.
3f20: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
3f30: 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 0a 20  t(p->interp);.. 
3f40: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f   rc = sqlite3OsO
3f50: 70 65 6e 28 50 41 52 45 4e 54 56 46 53 28 70 56  pen(PARENTVFS(pV
3f60: 66 73 29 2c 20 7a 4e 61 6d 65 2c 20 70 46 64 2d  fs), zName, pFd-
3f70: 3e 70 52 65 61 6c 2c 20 66 6c 61 67 73 2c 20 70  >pReal, flags, p
3f80: 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 69 66 28  OutFlags);.  if(
3f90: 20 70 46 64 2d 3e 70 52 65 61 6c 2d 3e 70 4d 65   pFd->pReal->pMe
3fa0: 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 73 71 6c  thods ){.    sql
3fb0: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20  ite3_io_methods 
3fc0: 2a 70 4d 65 74 68 6f 64 73 3b 0a 20 20 20 20 69  *pMethods;.    i
3fd0: 6e 74 20 6e 42 79 74 65 3b 0a 0a 20 20 20 20 69  nt nByte;..    i
3fe0: 66 28 20 70 56 66 73 2d 3e 69 56 65 72 73 69 6f  f( pVfs->iVersio
3ff0: 6e 3e 31 20 29 7b 0a 20 20 20 20 20 20 6e 42 79  n>1 ){.      nBy
4000: 74 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69  te = sizeof(sqli
4010: 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 29 3b  te3_io_methods);
4020: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4030: 20 20 6e 42 79 74 65 20 3d 20 6f 66 66 73 65 74    nByte = offset
4040: 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65  of(sqlite3_io_me
4050: 74 68 6f 64 73 2c 20 78 53 68 6d 4d 61 70 29 3b  thods, xShmMap);
4060: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4d 65 74  .    }..    pMet
4070: 68 6f 64 73 20 3d 20 28 73 71 6c 69 74 65 33 5f  hods = (sqlite3_
4080: 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 29 63 6b 61  io_methods *)cka
4090: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20  lloc(nByte);.   
40a0: 20 6d 65 6d 63 70 79 28 70 4d 65 74 68 6f 64 73   memcpy(pMethods
40b0: 2c 20 26 74 76 66 73 5f 69 6f 5f 6d 65 74 68 6f  , &tvfs_io_metho
40c0: 64 73 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  ds, nByte);.    
40d0: 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69  pMethods->iVersi
40e0: 6f 6e 20 3d 20 70 56 66 73 2d 3e 69 56 65 72 73  on = pVfs->iVers
40f0: 69 6f 6e 3b 0a 20 20 20 20 69 66 28 20 70 56 66  ion;.    if( pVf
4100: 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 31 20 26 26  s->iVersion>1 &&
4110: 20 28 28 54 65 73 74 76 66 73 20 2a 29 70 56 66   ((Testvfs *)pVf
4120: 73 2d 3e 70 41 70 70 44 61 74 61 29 2d 3e 69 73  s->pAppData)->is
4130: 4e 6f 73 68 6d 20 29 7b 0a 20 20 20 20 20 20 70  Noshm ){.      p
4140: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e 6d  Methods->xShmUnm
4150: 61 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d  ap = 0;.      pM
4160: 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63 6b  ethods->xShmLock
4170: 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65 74   = 0;.      pMet
4180: 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72 69 65  hods->xShmBarrie
4190: 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 4d 65  r = 0;.      pMe
41a0: 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 20 3d  thods->xShmMap =
41b0: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 46   0;.    }.    pF
41c0: 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 20 3d 20  ile->pMethods = 
41d0: 70 4d 65 74 68 6f 64 73 3b 0a 20 20 7d 0a 0a 20  pMethods;.  }.. 
41e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
41f0: 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 74 68 65 20  *.** Delete the 
4200: 66 69 6c 65 20 6c 6f 63 61 74 65 64 20 61 74 20  file located at 
4210: 7a 50 61 74 68 2e 20 49 66 20 74 68 65 20 64 69  zPath. If the di
4220: 72 53 79 6e 63 20 61 72 67 75 6d 65 6e 74 20 69  rSync argument i
4230: 73 20 74 72 75 65 2c 0a 2a 2a 20 65 6e 73 75 72  s true,.** ensur
4240: 65 20 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65  e the file-syste
4250: 6d 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 73 20  m modifications 
4260: 61 72 65 20 73 79 6e 63 65 64 20 74 6f 20 64 69  are synced to di
4270: 73 6b 20 62 65 66 6f 72 65 0a 2a 2a 20 72 65 74  sk before.** ret
4280: 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  urning..*/.stati
4290: 63 20 69 6e 74 20 74 76 66 73 44 65 6c 65 74 65  c int tvfsDelete
42a0: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
42b0: 66 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  fs, const char *
42c0: 7a 50 61 74 68 2c 20 69 6e 74 20 64 69 72 53 79  zPath, int dirSy
42d0: 6e 63 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  nc){.  int rc = 
42e0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73  SQLITE_OK;.  Tes
42f0: 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76  tvfs *p = (Testv
4300: 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44  fs *)pVfs->pAppD
4310: 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70  ata;..  if( p->p
4320: 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73  Script && p->mas
4330: 6b 26 54 45 53 54 56 46 53 5f 44 45 4c 45 54 45  k&TESTVFS_DELETE
4340: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66  _MASK ){.    tvf
4350: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 44 65  sExecTcl(p, "xDe
4360: 6c 65 74 65 22 2c 20 0a 20 20 20 20 20 20 20 20  lete", .        
4370: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
4380: 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c  (zPath, -1), Tcl
4390: 5f 4e 65 77 49 6e 74 4f 62 6a 28 64 69 72 53 79  _NewIntObj(dirSy
43a0: 6e 63 29 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20  nc), 0.    );.  
43b0: 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65    tvfsResultCode
43c0: 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20  (p, &rc);.  }.  
43d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
43e0: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
43f0: 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28 50 41  lite3OsDelete(PA
4400: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a  RENTVFS(pVfs), z
4410: 50 61 74 68 2c 20 64 69 72 53 79 6e 63 29 3b 0a  Path, dirSync);.
4420: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
4430: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 66  .}../*.** Test f
4440: 6f 72 20 61 63 63 65 73 73 20 70 65 72 6d 69 73  or access permis
4450: 73 69 6f 6e 73 2e 20 52 65 74 75 72 6e 20 74 72  sions. Return tr
4460: 75 65 20 69 66 20 74 68 65 20 72 65 71 75 65 73  ue if the reques
4470: 74 65 64 20 70 65 72 6d 69 73 73 69 6f 6e 0a 2a  ted permission.*
4480: 2a 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2c 20  * is available, 
4490: 6f 72 20 66 61 6c 73 65 20 6f 74 68 65 72 77 69  or false otherwi
44a0: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
44b0: 74 20 74 76 66 73 41 63 63 65 73 73 28 0a 20 20  t tvfsAccess(.  
44c0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
44d0: 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  s, .  const char
44e0: 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74 20   *zPath, .  int 
44f0: 66 6c 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70  flags, .  int *p
4500: 52 65 73 4f 75 74 0a 29 7b 0a 20 20 54 65 73 74  ResOut.){.  Test
4510: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
4520: 73 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61  s *)pVfs->pAppDa
4530: 74 61 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  ta;.  if( p->pSc
4540: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
4550: 54 45 53 54 56 46 53 5f 41 43 43 45 53 53 5f 4d  TESTVFS_ACCESS_M
4560: 41 53 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  ASK ){.    int r
4570: 63 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 72  c;.    char *zAr
4580: 67 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 66  g = 0;.    if( f
4590: 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43  lags==SQLITE_ACC
45a0: 45 53 53 5f 45 58 49 53 54 53 20 29 20 7a 41 72  ESS_EXISTS ) zAr
45b0: 67 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45  g = "SQLITE_ACCE
45c0: 53 53 5f 45 58 49 53 54 53 22 3b 0a 20 20 20 20  SS_EXISTS";.    
45d0: 69 66 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54  if( flags==SQLIT
45e0: 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57 52 49  E_ACCESS_READWRI
45f0: 54 45 20 29 20 7a 41 72 67 20 3d 20 22 53 51 4c  TE ) zArg = "SQL
4600: 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44 57  ITE_ACCESS_READW
4610: 52 49 54 45 22 3b 0a 20 20 20 20 69 66 28 20 66  RITE";.    if( f
4620: 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f 41 43 43  lags==SQLITE_ACC
4630: 45 53 53 5f 52 45 41 44 20 29 20 7a 41 72 67 20  ESS_READ ) zArg 
4640: 3d 20 22 53 51 4c 49 54 45 5f 41 43 43 45 53 53  = "SQLITE_ACCESS
4650: 5f 52 45 41 44 22 3b 0a 20 20 20 20 74 76 66 73  _READ";.    tvfs
4660: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 41 63 63  ExecTcl(p, "xAcc
4670: 65 73 73 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ess", .        T
4680: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
4690: 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54 63 6c 5f  zPath, -1), Tcl_
46a0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 41 72  NewStringObj(zAr
46b0: 67 2c 20 2d 31 29 2c 20 30 0a 20 20 20 20 29 3b  g, -1), 0.    );
46c0: 0a 20 20 20 20 69 66 28 20 74 76 66 73 52 65 73  .    if( tvfsRes
46d0: 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63 29 20  ultCode(p, &rc) 
46e0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  ){.      if( rc!
46f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74  =SQLITE_OK ) ret
4700: 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 65 6c 73  urn rc;.    }els
4710: 65 7b 0a 20 20 20 20 20 20 54 63 6c 5f 49 6e 74  e{.      Tcl_Int
4720: 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 2d  erp *interp = p-
4730: 3e 69 6e 74 65 72 70 3b 0a 20 20 20 20 20 20 69  >interp;.      i
4740: 66 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63 6c 5f 47  f( TCL_OK==Tcl_G
4750: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
4760: 28 30 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65  (0, Tcl_GetObjRe
4770: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 70 52  sult(interp), pR
4780: 65 73 4f 75 74 29 20 29 7b 0a 20 20 20 20 20 20  esOut) ){.      
4790: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
47a0: 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OK;.      }.    
47b0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  }.  }.  return s
47c0: 71 6c 69 74 65 33 4f 73 41 63 63 65 73 73 28 50  qlite3OsAccess(P
47d0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
47e0: 7a 50 61 74 68 2c 20 66 6c 61 67 73 2c 20 70 52  zPath, flags, pR
47f0: 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  esOut);.}../*.**
4800: 20 50 6f 70 75 6c 61 74 65 20 62 75 66 66 65 72   Populate buffer
4810: 20 7a 4f 75 74 20 77 69 74 68 20 74 68 65 20 66   zOut with the f
4820: 75 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c 20 70 61  ull canonical pa
4830: 74 68 6e 61 6d 65 20 63 6f 72 72 65 73 70 6f 6e  thname correspon
4840: 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 70  ding.** to the p
4850: 61 74 68 6e 61 6d 65 20 69 6e 20 7a 50 61 74 68  athname in zPath
4860: 2e 20 7a 4f 75 74 20 69 73 20 67 75 61 72 61 6e  . zOut is guaran
4870: 74 65 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f  teed to point to
4880: 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 6f 66 20   a buffer.** of 
4890: 61 74 20 6c 65 61 73 74 20 28 44 45 56 53 59 4d  at least (DEVSYM
48a0: 5f 4d 41 58 5f 50 41 54 48 4e 41 4d 45 2b 31 29  _MAX_PATHNAME+1)
48b0: 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   bytes..*/.stati
48c0: 63 20 69 6e 74 20 74 76 66 73 46 75 6c 6c 50 61  c int tvfsFullPa
48d0: 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c 69 74 65  thname(.  sqlite
48e0: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 0a 20 20  3_vfs *pVfs, .  
48f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74  const char *zPat
4900: 68 2c 20 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20  h, .  int nOut, 
4910: 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 0a 29 7b  .  char *zOut.){
4920: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
4930: 33 4f 73 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  3OsFullPathname(
4940: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
4950: 20 7a 50 61 74 68 2c 20 6e 4f 75 74 2c 20 7a 4f   zPath, nOut, zO
4960: 75 74 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66 20  ut);.}..#ifndef 
4970: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44  SQLITE_OMIT_LOAD
4980: 5f 45 58 54 45 4e 53 49 4f 4e 0a 2f 2a 0a 2a 2a  _EXTENSION./*.**
4990: 20 4f 70 65 6e 20 74 68 65 20 64 79 6e 61 6d 69   Open the dynami
49a0: 63 20 6c 69 62 72 61 72 79 20 6c 6f 63 61 74 65  c library locate
49b0: 64 20 61 74 20 7a 50 61 74 68 20 61 6e 64 20 72  d at zPath and r
49c0: 65 74 75 72 6e 20 61 20 68 61 6e 64 6c 65 2e 0a  eturn a handle..
49d0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  */.static void *
49e0: 74 76 66 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74  tvfsDlOpen(sqlit
49f0: 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 63 6f  e3_vfs *pVfs, co
4a00: 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 29  nst char *zPath)
4a10: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
4a20: 65 33 4f 73 44 6c 4f 70 65 6e 28 50 41 52 45 4e  e3OsDlOpen(PAREN
4a30: 54 56 46 53 28 70 56 66 73 29 2c 20 7a 50 61 74  TVFS(pVfs), zPat
4a40: 68 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70  h);.}../*.** Pop
4a50: 75 6c 61 74 65 20 74 68 65 20 62 75 66 66 65 72  ulate the buffer
4a60: 20 7a 45 72 72 4d 73 67 20 28 73 69 7a 65 20 6e   zErrMsg (size n
4a70: 42 79 74 65 20 62 79 74 65 73 29 20 77 69 74 68  Byte bytes) with
4a80: 20 61 20 68 75 6d 61 6e 20 72 65 61 64 61 62 6c   a human readabl
4a90: 65 0a 2a 2a 20 75 74 66 2d 38 20 73 74 72 69 6e  e.** utf-8 strin
4aa0: 67 20 64 65 73 63 72 69 62 69 6e 67 20 74 68 65  g describing the
4ab0: 20 6d 6f 73 74 20 72 65 63 65 6e 74 20 65 72 72   most recent err
4ac0: 6f 72 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 61  or encountered a
4ad0: 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a 20 77 69  ssociated .** wi
4ae0: 74 68 20 64 79 6e 61 6d 69 63 20 6c 69 62 72 61  th dynamic libra
4af0: 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ries..*/.static 
4b00: 76 6f 69 64 20 74 76 66 73 44 6c 45 72 72 6f 72  void tvfsDlError
4b10: 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56  (sqlite3_vfs *pV
4b20: 66 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63  fs, int nByte, c
4b30: 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20  har *zErrMsg){. 
4b40: 20 73 71 6c 69 74 65 33 4f 73 44 6c 45 72 72 6f   sqlite3OsDlErro
4b50: 72 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  r(PARENTVFS(pVfs
4b60: 29 2c 20 6e 42 79 74 65 2c 20 7a 45 72 72 4d 73  ), nByte, zErrMs
4b70: 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  g);.}../*.** Ret
4b80: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
4b90: 20 74 68 65 20 73 79 6d 62 6f 6c 20 7a 53 79 6d   the symbol zSym
4ba0: 62 6f 6c 20 69 6e 20 74 68 65 20 64 79 6e 61 6d  bol in the dynam
4bb0: 69 63 20 6c 69 62 72 61 72 79 20 70 48 61 6e 64  ic library pHand
4bc0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
4bd0: 69 64 20 28 2a 74 76 66 73 44 6c 53 79 6d 28 73  id (*tvfsDlSym(s
4be0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
4bf0: 2c 20 76 6f 69 64 20 2a 70 2c 20 63 6f 6e 73 74  , void *p, const
4c00: 20 63 68 61 72 20 2a 7a 53 79 6d 29 29 28 76 6f   char *zSym))(vo
4c10: 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  id){.  return sq
4c20: 6c 69 74 65 33 4f 73 44 6c 53 79 6d 28 50 41 52  lite3OsDlSym(PAR
4c30: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 2c  ENTVFS(pVfs), p,
4c40: 20 7a 53 79 6d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   zSym);.}../*.**
4c50: 20 43 6c 6f 73 65 20 74 68 65 20 64 79 6e 61 6d   Close the dynam
4c60: 69 63 20 6c 69 62 72 61 72 79 20 68 61 6e 64 6c  ic library handl
4c70: 65 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  e pHandle..*/.st
4c80: 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c  atic void tvfsDl
4c90: 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 66  Close(sqlite3_vf
4ca0: 73 20 2a 70 56 66 73 2c 20 76 6f 69 64 20 2a 70  s *pVfs, void *p
4cb0: 48 61 6e 64 6c 65 29 7b 0a 20 20 73 71 6c 69 74  Handle){.  sqlit
4cc0: 65 33 4f 73 44 6c 43 6c 6f 73 65 28 50 41 52 45  e3OsDlClose(PARE
4cd0: 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 48 61  NTVFS(pVfs), pHa
4ce0: 6e 64 6c 65 29 3b 0a 7d 0a 23 65 6e 64 69 66 20  ndle);.}.#endif 
4cf0: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  /* SQLITE_OMIT_L
4d00: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f  OAD_EXTENSION */
4d10: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c 61 74 65  ../*.** Populate
4d20: 20 74 68 65 20 62 75 66 66 65 72 20 70 6f 69 6e   the buffer poin
4d30: 74 65 64 20 74 6f 20 62 79 20 7a 42 75 66 4f 75  ted to by zBufOu
4d40: 74 20 77 69 74 68 20 6e 42 79 74 65 20 62 79 74  t with nByte byt
4d50: 65 73 20 6f 66 20 0a 2a 2a 20 72 61 6e 64 6f 6d  es of .** random
4d60: 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61 74 69 63   data..*/.static
4d70: 20 69 6e 74 20 74 76 66 73 52 61 6e 64 6f 6d 6e   int tvfsRandomn
4d80: 65 73 73 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ess(sqlite3_vfs 
4d90: 2a 70 56 66 73 2c 20 69 6e 74 20 6e 42 79 74 65  *pVfs, int nByte
4da0: 2c 20 63 68 61 72 20 2a 7a 42 75 66 4f 75 74 29  , char *zBufOut)
4db0: 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  {.  return sqlit
4dc0: 65 33 4f 73 52 61 6e 64 6f 6d 6e 65 73 73 28 50  e3OsRandomness(P
4dd0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4de0: 6e 42 79 74 65 2c 20 7a 42 75 66 4f 75 74 29 3b  nByte, zBufOut);
4df0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6c 65 65 70 20  .}../*.** Sleep 
4e00: 66 6f 72 20 6e 4d 69 63 72 6f 20 6d 69 63 72 6f  for nMicro micro
4e10: 73 65 63 6f 6e 64 73 2e 20 52 65 74 75 72 6e 20  seconds. Return 
4e20: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6d 69  the number of mi
4e30: 63 72 6f 73 65 63 6f 6e 64 73 20 0a 2a 2a 20 61  croseconds .** a
4e40: 63 74 75 61 6c 6c 79 20 73 6c 65 70 74 2e 0a 2a  ctually slept..*
4e50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
4e60: 73 53 6c 65 65 70 28 73 71 6c 69 74 65 33 5f 76  sSleep(sqlite3_v
4e70: 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 4d  fs *pVfs, int nM
4e80: 69 63 72 6f 29 7b 0a 20 20 72 65 74 75 72 6e 20  icro){.  return 
4e90: 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 50  sqlite3OsSleep(P
4ea0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4eb0: 6e 4d 69 63 72 6f 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  nMicro);.}../*.*
4ec0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72  * Return the cur
4ed0: 72 65 6e 74 20 74 69 6d 65 20 61 73 20 61 20 4a  rent time as a J
4ee0: 75 6c 69 61 6e 20 44 61 79 20 6e 75 6d 62 65 72  ulian Day number
4ef0: 20 69 6e 20 2a 70 54 69 6d 65 4f 75 74 2e 0a 2a   in *pTimeOut..*
4f00: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  /.static int tvf
4f10: 73 43 75 72 72 65 6e 74 54 69 6d 65 28 73 71 6c  sCurrentTime(sql
4f20: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4f30: 64 6f 75 62 6c 65 20 2a 70 54 69 6d 65 4f 75 74  double *pTimeOut
4f40: 29 7b 0a 20 20 72 65 74 75 72 6e 20 50 41 52 45  ){.  return PARE
4f50: 4e 54 56 46 53 28 70 56 66 73 29 2d 3e 78 43 75  NTVFS(pVfs)->xCu
4f60: 72 72 65 6e 74 54 69 6d 65 28 50 41 52 45 4e 54  rrentTime(PARENT
4f70: 56 46 53 28 70 56 66 73 29 2c 20 70 54 69 6d 65  VFS(pVfs), pTime
4f80: 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  Out);.}..static 
4f90: 69 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28  int tvfsShmOpen(
4fa0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
4fb0: 69 6c 65 29 7b 0a 20 20 54 65 73 74 76 66 73 20  ile){.  Testvfs 
4fc0: 2a 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  *p;.  int rc = S
4fd0: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
4fe0: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
4ff0: 63 6f 64 65 20 2a 2f 0a 20 20 54 65 73 74 76 66  code */.  Testvf
5000: 73 42 75 66 66 65 72 20 2a 70 42 75 66 66 65 72  sBuffer *pBuffer
5010: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66  ;         /* Buf
5020: 66 65 72 20 74 6f 20 6f 70 65 6e 20 63 6f 6e 6e  fer to open conn
5030: 65 63 74 69 6f 6e 20 74 6f 20 2a 2f 0a 20 20 54  ection to */.  T
5040: 65 73 74 76 66 73 46 64 20 2a 70 46 64 3b 20 20  estvfsFd *pFd;  
5050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5060: 2a 20 54 68 65 20 74 65 73 74 76 66 73 20 66 69  * The testvfs fi
5070: 6c 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a  le structure */.
5080: 0a 20 20 70 46 64 20 3d 20 74 76 66 73 47 65 74  .  pFd = tvfsGet
5090: 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 70 20 3d  Fd(pFile);.  p =
50a0: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
50b0: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
50c0: 0a 20 20 61 73 73 65 72 74 28 20 70 46 64 2d 3e  .  assert( pFd->
50d0: 70 53 68 6d 49 64 20 26 26 20 70 46 64 2d 3e 70  pShmId && pFd->p
50e0: 53 68 6d 3d 3d 30 20 26 26 20 70 46 64 2d 3e 70  Shm==0 && pFd->p
50f0: 4e 65 78 74 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a  Next==0 );..  /*
5100: 20 45 76 61 6c 75 61 74 65 20 74 68 65 20 54 63   Evaluate the Tc
5110: 6c 20 73 63 72 69 70 74 3a 20 0a 20 20 2a 2a 0a  l script: .  **.
5120: 20 20 2a 2a 20 20 20 53 43 52 49 50 54 20 78 53    **   SCRIPT xS
5130: 68 6d 4f 70 65 6e 20 46 49 4c 45 4e 41 4d 45 0a  hmOpen FILENAME.
5140: 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74    */.  Tcl_Reset
5150: 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70  Result(p->interp
5160: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  );.  if( p->pScr
5170: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
5180: 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d  ESTVFS_SHMOPEN_M
5190: 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45  ASK ){.    tvfsE
51a0: 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 4f  xecTcl(p, "xShmO
51b0: 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77 53 74 72  pen", Tcl_NewStr
51c0: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c  ingObj(pFd->zFil
51d0: 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30 2c 20 30  ename, -1), 0, 0
51e0: 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73 52  );.    if( tvfsR
51f0: 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72 63  esultCode(p, &rc
5200: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 72  ) ){.      if( r
5210: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c!=SQLITE_OK ) r
5220: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
5230: 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 72    }..  assert( r
5240: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
5250: 20 20 69 66 28 20 70 2d 3e 6d 61 73 6b 26 54 45    if( p->mask&TE
5260: 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41  STVFS_SHMOPEN_MA
5270: 53 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74  SK && tvfsInject
5280: 49 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20  Ioerr(p) ){.    
5290: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
52a0: 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  ERR;.  }..  /* S
52b0: 65 61 72 63 68 20 66 6f 72 20 61 20 54 65 73 74  earch for a Test
52c0: 76 66 73 42 75 66 66 65 72 2e 20 43 72 65 61 74  vfsBuffer. Creat
52d0: 65 20 61 20 6e 65 77 20 6f 6e 65 20 69 66 20 72  e a new one if r
52e0: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 66 6f  equired. */.  fo
52f0: 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70 42 75  r(pBuffer=p->pBu
5300: 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b 20 70  ffer; pBuffer; p
5310: 42 75 66 66 65 72 3d 70 42 75 66 66 65 72 2d 3e  Buffer=pBuffer->
5320: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
5330: 30 3d 3d 73 74 72 63 6d 70 28 70 46 64 2d 3e 7a  0==strcmp(pFd->z
5340: 46 69 6c 65 6e 61 6d 65 2c 20 70 42 75 66 66 65  Filename, pBuffe
5350: 72 2d 3e 7a 46 69 6c 65 29 20 29 20 62 72 65 61  r->zFile) ) brea
5360: 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 21 70 42  k;.  }.  if( !pB
5370: 75 66 66 65 72 20 29 7b 0a 20 20 20 20 69 6e 74  uffer ){.    int
5380: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
5390: 54 65 73 74 76 66 73 42 75 66 66 65 72 29 20 2b  TestvfsBuffer) +
53a0: 20 73 74 72 6c 65 6e 28 70 46 64 2d 3e 7a 46 69   strlen(pFd->zFi
53b0: 6c 65 6e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 20  lename) + 1;.   
53c0: 20 70 42 75 66 66 65 72 20 3d 20 28 54 65 73 74   pBuffer = (Test
53d0: 76 66 73 42 75 66 66 65 72 20 2a 29 63 6b 61 6c  vfsBuffer *)ckal
53e0: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20  loc(nByte);.    
53f0: 6d 65 6d 73 65 74 28 70 42 75 66 66 65 72 2c 20  memset(pBuffer, 
5400: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 70  0, nByte);.    p
5410: 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 20 3d 20  Buffer->zFile = 
5420: 28 63 68 61 72 20 2a 29 26 70 42 75 66 66 65 72  (char *)&pBuffer
5430: 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28  [1];.    strcpy(
5440: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
5450: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b  pFd->zFilename);
5460: 0a 20 20 20 20 70 42 75 66 66 65 72 2d 3e 70 4e  .    pBuffer->pN
5470: 65 78 74 20 3d 20 70 2d 3e 70 42 75 66 66 65 72  ext = p->pBuffer
5480: 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66 66 65 72  ;.    p->pBuffer
5490: 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 7d 0a   = pBuffer;.  }.
54a0: 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74 20 74 68  .  /* Connect th
54b0: 65 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20  e TestvfsBuffer 
54c0: 74 6f 20 74 68 65 20 6e 65 77 20 54 65 73 74 76  to the new Testv
54d0: 66 73 53 68 6d 20 68 61 6e 64 6c 65 20 61 6e 64  fsShm handle and
54e0: 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 70 46   return. */.  pF
54f0: 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42 75 66 66  d->pNext = pBuff
5500: 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20 70 42 75  er->pFile;.  pBu
5510: 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d 20 70 46  ffer->pFile = pF
5520: 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d  d;.  pFd->pShm =
5530: 20 70 42 75 66 66 65 72 3b 0a 20 20 72 65 74 75   pBuffer;.  retu
5540: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
5550: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66  .static void tvf
5560: 73 41 6c 6c 6f 63 50 61 67 65 28 54 65 73 74 76  sAllocPage(Testv
5570: 66 73 42 75 66 66 65 72 20 2a 70 2c 20 69 6e 74  fsBuffer *p, int
5580: 20 69 50 61 67 65 2c 20 69 6e 74 20 70 67 73 7a   iPage, int pgsz
5590: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61  ){.  assert( iPa
55a0: 67 65 3c 54 45 53 54 56 46 53 5f 4d 41 58 5f 50  ge<TESTVFS_MAX_P
55b0: 41 47 45 53 20 29 3b 0a 20 20 69 66 28 20 70 2d  AGES );.  if( p-
55c0: 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 3d 3d 30  >aPage[iPage]==0
55d0: 20 29 7b 0a 20 20 20 20 70 2d 3e 61 50 61 67 65   ){.    p->aPage
55e0: 5b 69 50 61 67 65 5d 20 3d 20 28 75 38 20 2a 29  [iPage] = (u8 *)
55f0: 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29 3b 0a 20  ckalloc(pgsz);. 
5600: 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e 61 50 61     memset(p->aPa
5610: 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c 20 70 67  ge[iPage], 0, pg
5620: 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70 67 73 7a  sz);.    p->pgsz
5630: 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a 7d 0a 0a   = pgsz;.  }.}..
5640: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
5650: 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33  hmMap(.  sqlite3
5660: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 20 20  _file *pFile,   
5670: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64           /* Hand
5680: 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62  le open on datab
5690: 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  ase file */.  in
56a0: 74 20 69 50 61 67 65 2c 20 20 20 20 20 20 20 20  t iPage,        
56b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
56c0: 20 50 61 67 65 20 74 6f 20 72 65 74 72 69 65 76   Page to retriev
56d0: 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67 73 7a 2c  e */.  int pgsz,
56e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56f0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
5700: 66 20 70 61 67 65 73 20 2a 2f 0a 20 20 69 6e 74  f pages */.  int
5710: 20 69 73 57 72 69 74 65 2c 20 20 20 20 20 20 20   isWrite,       
5720: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5730: 54 72 75 65 20 74 6f 20 65 78 74 65 6e 64 20 66  True to extend f
5740: 69 6c 65 20 69 66 20 6e 65 63 65 73 73 61 72 79  ile if necessary
5750: 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f 6c 61 74   */.  void volat
5760: 69 6c 65 20 2a 2a 70 70 20 20 20 20 20 20 20 20  ile **pp        
5770: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4d 61        /* OUT: Ma
5780: 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 29  pped memory */.)
5790: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
57a0: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
57b0: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
57c0: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
57d0: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
57e0: 74 76 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66  tvfs *)(pFd->pVf
57f0: 73 2d 3e 70 41 70 70 44 61 74 61 29 3b 0a 0a 20  s->pAppData);.. 
5800: 20 69 66 28 20 30 3d 3d 70 46 64 2d 3e 70 53 68   if( 0==pFd->pSh
5810: 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 74 76  m ){.    rc = tv
5820: 66 73 53 68 6d 4f 70 65 6e 28 70 46 69 6c 65 29  fsShmOpen(pFile)
5830: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
5840: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
5850: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
5860: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e  }.  }..  if( p->
5870: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
5880: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4d 41  sk&TESTVFS_SHMMA
5890: 50 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 54 63  P_MASK ){.    Tc
58a0: 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d 20 54 63  l_Obj *pArg = Tc
58b0: 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20  l_NewObj();.    
58c0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
58d0: 28 70 41 72 67 29 3b 0a 20 20 20 20 54 63 6c 5f  (pArg);.    Tcl_
58e0: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
58f0: 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72 70 2c 20  ment(p->interp, 
5900: 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77 49 6e 74  pArg, Tcl_NewInt
5910: 4f 62 6a 28 69 50 61 67 65 29 29 3b 0a 20 20 20  Obj(iPage));.   
5920: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
5930: 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74  ndElement(p->int
5940: 65 72 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e  erp, pArg, Tcl_N
5950: 65 77 49 6e 74 4f 62 6a 28 70 67 73 7a 29 29 3b  ewIntObj(pgsz));
5960: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
5970: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
5980: 3e 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54  >interp, pArg, T
5990: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 69 73 57  cl_NewIntObj(isW
59a0: 72 69 74 65 29 29 3b 0a 20 20 20 20 74 76 66 73  rite));.    tvfs
59b0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d  ExecTcl(p, "xShm
59c0: 4d 61 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54  Map", .        T
59d0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
59e0: 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65  pFd->pShm->zFile
59f0: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
5a00: 49 64 2c 20 70 41 72 67 0a 20 20 20 20 29 3b 0a  Id, pArg.    );.
5a10: 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f      tvfsResultCo
5a20: 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 20 20  de(p, &rc);.    
5a30: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
5a40: 28 70 41 72 67 29 3b 0a 20 20 7d 0a 20 20 69 66  (pArg);.  }.  if
5a50: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5a60: 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56  && p->mask&TESTV
5a70: 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20 26  FS_SHMMAP_MASK &
5a80: 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72  & tvfsInjectIoer
5a90: 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d  r(p) ){.    rc =
5aa0: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20   SQLITE_IOERR;. 
5ab0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
5ac0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73 57 72 69  LITE_OK && isWri
5ad0: 74 65 20 26 26 20 21 70 46 64 2d 3e 70 53 68 6d  te && !pFd->pShm
5ae0: 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d 20 29  ->aPage[iPage] )
5af0: 7b 0a 20 20 20 20 74 76 66 73 41 6c 6c 6f 63 50  {.    tvfsAllocP
5b00: 61 67 65 28 70 46 64 2d 3e 70 53 68 6d 2c 20 69  age(pFd->pShm, i
5b10: 50 61 67 65 2c 20 70 67 73 7a 29 3b 0a 20 20 7d  Page, pgsz);.  }
5b20: 0a 20 20 2a 70 70 20 3d 20 28 76 6f 69 64 20 76  .  *pp = (void v
5b30: 6f 6c 61 74 69 6c 65 20 2a 29 70 46 64 2d 3e 70  olatile *)pFd->p
5b40: 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50 61 67 65  Shm->aPage[iPage
5b50: 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ];..  return rc;
5b60: 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  .}...static int 
5b70: 74 76 66 73 53 68 6d 4c 6f 63 6b 28 0a 20 20 73  tvfsShmLock(.  s
5b80: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
5b90: 6c 65 2c 0a 20 20 69 6e 74 20 6f 66 73 74 2c 0a  le,.  int ofst,.
5ba0: 20 20 69 6e 74 20 6e 2c 0a 20 20 69 6e 74 20 66    int n,.  int f
5bb0: 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63  lags.){.  int rc
5bc0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
5bd0: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
5be0: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
5bf0: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
5c00: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46  = (Testvfs *)(pF
5c10: 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74  d->pVfs->pAppDat
5c20: 61 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b  a);.  int nLock;
5c30: 0a 20 20 63 68 61 72 20 7a 4c 6f 63 6b 5b 38 30  .  char zLock[80
5c40: 5d 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  ];..  if( p->pSc
5c50: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
5c60: 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f 43 4b 5f  TESTVFS_SHMLOCK_
5c70: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  MASK ){.    sqli
5c80: 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
5c90: 65 6f 66 28 7a 4c 6f 63 6b 29 2c 20 7a 4c 6f 63  eof(zLock), zLoc
5ca0: 6b 2c 20 22 25 64 20 25 64 22 2c 20 6f 66 73 74  k, "%d %d", ofst
5cb0: 2c 20 6e 29 3b 0a 20 20 20 20 6e 4c 6f 63 6b 20  , n);.    nLock 
5cc0: 3d 20 73 74 72 6c 65 6e 28 7a 4c 6f 63 6b 29 3b  = strlen(zLock);
5cd0: 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 26  .    if( flags &
5ce0: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b   SQLITE_SHM_LOCK
5cf0: 20 29 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79   ){.      strcpy
5d00: 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20  (&zLock[nLock], 
5d10: 22 20 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 7d 65  " lock");.    }e
5d20: 6c 73 65 7b 0a 20 20 20 20 20 20 73 74 72 63 70  lse{.      strcp
5d30: 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c  y(&zLock[nLock],
5d40: 20 22 20 75 6e 6c 6f 63 6b 22 29 3b 0a 20 20 20   " unlock");.   
5d50: 20 7d 0a 20 20 20 20 6e 4c 6f 63 6b 20 2b 3d 20   }.    nLock += 
5d60: 73 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b 5b 6e 4c  strlen(&zLock[nL
5d70: 6f 63 6b 5d 29 3b 0a 20 20 20 20 69 66 28 20 66  ock]);.    if( f
5d80: 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48  lags & SQLITE_SH
5d90: 4d 5f 53 48 41 52 45 44 20 29 7b 0a 20 20 20 20  M_SHARED ){.    
5da0: 20 20 73 74 72 63 70 79 28 26 7a 4c 6f 63 6b 5b    strcpy(&zLock[
5db0: 6e 4c 6f 63 6b 5d 2c 20 22 20 73 68 61 72 65 64  nLock], " shared
5dc0: 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ");.    }else{. 
5dd0: 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f       strcpy(&zLo
5de0: 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 65 78 63  ck[nLock], " exc
5df0: 6c 75 73 69 76 65 22 29 3b 0a 20 20 20 20 7d 0a  lusive");.    }.
5e00: 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28      tvfsExecTcl(
5e10: 70 2c 20 22 78 53 68 6d 4c 6f 63 6b 22 2c 20 0a  p, "xShmLock", .
5e20: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
5e30: 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53  tringObj(pFd->pS
5e40: 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20  hm->zFile, -1), 
5e50: 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a 20 20 20  pFd->pShmId,.   
5e60: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
5e70: 6e 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20 2d 31 29  ngObj(zLock, -1)
5e80: 0a 20 20 20 20 29 3b 0a 20 20 20 20 74 76 66 73  .    );.    tvfs
5e90: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
5ea0: 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  c);.  }..  if( r
5eb0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
5ec0: 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f  p->mask&TESTVFS_
5ed0: 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 26 26 20  SHMLOCK_MASK && 
5ee0: 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28  tvfsInjectIoerr(
5ef0: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  p) ){.    rc = S
5f00: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d  QLITE_IOERR;.  }
5f10: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
5f20: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
5f30: 20 69 73 4c 6f 63 6b 20 3d 20 28 66 6c 61 67 73   isLock = (flags
5f40: 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f   & SQLITE_SHM_LO
5f50: 43 4b 29 3b 0a 20 20 20 20 69 6e 74 20 69 73 45  CK);.    int isE
5f60: 78 63 6c 20 3d 20 28 66 6c 61 67 73 20 26 20 53  xcl = (flags & S
5f70: 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53  QLITE_SHM_EXCLUS
5f80: 49 56 45 29 3b 0a 20 20 20 20 75 33 32 20 6d 61  IVE);.    u32 ma
5f90: 73 6b 20 3d 20 28 28 28 31 3c 3c 6e 29 2d 31 29  sk = (((1<<n)-1)
5fa0: 20 3c 3c 20 6f 66 73 74 29 3b 0a 20 20 20 20 69   << ofst);.    i
5fb0: 66 28 20 69 73 4c 6f 63 6b 20 29 7b 0a 20 20 20  f( isLock ){.   
5fc0: 20 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 32     TestvfsFd *p2
5fd0: 3b 0a 20 20 20 20 20 20 66 6f 72 28 70 32 3d 70  ;.      for(p2=p
5fe0: 46 64 2d 3e 70 53 68 6d 2d 3e 70 46 69 6c 65 3b  Fd->pShm->pFile;
5ff0: 20 70 32 3b 20 70 32 3d 70 32 2d 3e 70 4e 65 78   p2; p2=p2->pNex
6000: 74 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t){.        if( 
6010: 70 32 3d 3d 70 46 64 20 29 20 63 6f 6e 74 69 6e  p2==pFd ) contin
6020: 75 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ue;.        if( 
6030: 28 70 32 2d 3e 65 78 63 6c 6c 6f 63 6b 26 6d 61  (p2->excllock&ma
6040: 73 6b 29 20 7c 7c 20 28 69 73 45 78 63 6c 20 26  sk) || (isExcl &
6050: 26 20 70 32 2d 3e 73 68 61 72 65 64 6c 6f 63 6b  & p2->sharedlock
6060: 26 6d 61 73 6b 29 20 29 7b 0a 20 20 20 20 20 20  &mask) ){.      
6070: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
6080: 42 55 53 59 3b 0a 20 20 20 20 20 20 20 20 20 20  BUSY;.          
6090: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
60a0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
60b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
60c0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
60d0: 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65  isExcl )  pFd->e
60e0: 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b  xcllock |= mask;
60f0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 69 73  .        if( !is
6100: 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72  Excl ) pFd->shar
6110: 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61 73 6b 3b 0a  edlock |= mask;.
6120: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
6130: 65 7b 0a 20 20 20 20 20 20 69 66 28 20 69 73 45  e{.      if( isE
6140: 78 63 6c 20 29 20 20 70 46 64 2d 3e 65 78 63 6c  xcl )  pFd->excl
6150: 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b  lock &= (~mask);
6160: 0a 20 20 20 20 20 20 69 66 28 20 21 69 73 45 78  .      if( !isEx
6170: 63 6c 20 29 20 70 46 64 2d 3e 73 68 61 72 65 64  cl ) pFd->shared
6180: 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73 6b 29 3b  lock &= (~mask);
6190: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
61a0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
61b0: 69 63 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42  ic void tvfsShmB
61c0: 61 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66  arrier(sqlite3_f
61d0: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
61e0: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
61f0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
6200: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
6210: 20 28 54 65 73 74 76 66 73 20 2a 29 28 70 46 64   (Testvfs *)(pFd
6220: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
6230: 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63  );..  if( p->pSc
6240: 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26  ript && p->mask&
6250: 54 45 53 54 56 46 53 5f 53 48 4d 42 41 52 52 49  TESTVFS_SHMBARRI
6260: 45 52 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74  ER_MASK ){.    t
6270: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
6280: 53 68 6d 42 61 72 72 69 65 72 22 2c 20 0a 20 20  ShmBarrier", .  
6290: 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72        Tcl_NewStr
62a0: 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70 53 68 6d  ingObj(pFd->pShm
62b0: 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c 20 70 46  ->zFile, -1), pF
62c0: 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a 20 20 20  d->pShmId, 0.   
62d0: 20 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69   );.  }.}..stati
62e0: 63 20 69 6e 74 20 74 76 66 73 53 68 6d 55 6e 6d  c int tvfsShmUnm
62f0: 61 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  ap(.  sqlite3_fi
6300: 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 69 6e 74  le *pFile,.  int
6310: 20 64 65 6c 65 74 65 46 6c 61 67 0a 29 7b 0a 20   deleteFlag.){. 
6320: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
6330: 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66 73 46 64  _OK;.  TestvfsFd
6340: 20 2a 70 46 64 20 3d 20 74 76 66 73 47 65 74 46   *pFd = tvfsGetF
6350: 64 28 70 46 69 6c 65 29 3b 0a 20 20 54 65 73 74  d(pFile);.  Test
6360: 76 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66  vfs *p = (Testvf
6370: 73 20 2a 29 28 70 46 64 2d 3e 70 56 66 73 2d 3e  s *)(pFd->pVfs->
6380: 70 41 70 70 44 61 74 61 29 3b 0a 20 20 54 65 73  pAppData);.  Tes
6390: 74 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66  tvfsBuffer *pBuf
63a0: 66 65 72 20 3d 20 70 46 64 2d 3e 70 53 68 6d 3b  fer = pFd->pShm;
63b0: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 2a 70  .  TestvfsFd **p
63c0: 70 46 64 3b 0a 0a 20 20 69 66 28 20 21 70 42 75  pFd;..  if( !pBu
63d0: 66 66 65 72 20 29 20 72 65 74 75 72 6e 20 53 51  ffer ) return SQ
63e0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61 73 73 65 72  LITE_OK;.  asser
63f0: 74 28 20 70 46 64 2d 3e 70 53 68 6d 49 64 20 26  t( pFd->pShmId &
6400: 26 20 70 46 64 2d 3e 70 53 68 6d 20 29 3b 0a 0a  & pFd->pShm );..
6410: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
6420: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
6430: 56 46 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53  VFS_SHMCLOSE_MAS
6440: 4b 20 29 7b 0a 20 20 20 20 74 76 66 73 45 78 65  K ){.    tvfsExe
6450: 63 54 63 6c 28 70 2c 20 22 78 53 68 6d 55 6e 6d  cTcl(p, "xShmUnm
6460: 61 70 22 2c 20 0a 20 20 20 20 20 20 20 20 54 63  ap", .        Tc
6470: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
6480: 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c  Fd->pShm->zFile,
6490: 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49   -1), pFd->pShmI
64a0: 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20 20  d, 0.    );.    
64b0: 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70  tvfsResultCode(p
64c0: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 66  , &rc);.  }..  f
64d0: 6f 72 28 70 70 46 64 3d 26 70 42 75 66 66 65 72  or(ppFd=&pBuffer
64e0: 2d 3e 70 46 69 6c 65 3b 20 2a 70 70 46 64 21 3d  ->pFile; *ppFd!=
64f0: 70 46 64 3b 20 70 70 46 64 3d 26 28 28 2a 70 70  pFd; ppFd=&((*pp
6500: 46 64 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20  Fd)->pNext));.  
6510: 61 73 73 65 72 74 28 20 28 2a 70 70 46 64 29 3d  assert( (*ppFd)=
6520: 3d 70 46 64 20 29 3b 0a 20 20 2a 70 70 46 64 20  =pFd );.  *ppFd 
6530: 3d 20 70 46 64 2d 3e 70 4e 65 78 74 3b 0a 20 20  = pFd->pNext;.  
6540: 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a  pFd->pNext = 0;.
6550: 0a 20 20 69 66 28 20 70 42 75 66 66 65 72 2d 3e  .  if( pBuffer->
6560: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
6570: 69 6e 74 20 69 3b 0a 20 20 20 20 54 65 73 74 76  int i;.    Testv
6580: 66 73 42 75 66 66 65 72 20 2a 2a 70 70 3b 0a 20  fsBuffer **pp;. 
6590: 20 20 20 66 6f 72 28 70 70 3d 26 70 2d 3e 70 42     for(pp=&p->pB
65a0: 75 66 66 65 72 3b 20 2a 70 70 21 3d 70 42 75 66  uffer; *pp!=pBuf
65b0: 66 65 72 3b 20 70 70 3d 26 28 28 2a 70 70 29 2d  fer; pp=&((*pp)-
65c0: 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20 20 2a 70  >pNext));.    *p
65d0: 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e 65 78 74  p = (*pp)->pNext
65e0: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 70  ;.    for(i=0; p
65f0: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
6600: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6b  ; i++){.      ck
6610: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 42 75  free((char *)pBu
6620: 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d 29 3b  ffer->aPage[i]);
6630: 0a 20 20 20 20 7d 0a 20 20 20 20 63 6b 66 72 65  .    }.    ckfre
6640: 65 28 28 63 68 61 72 20 2a 29 70 42 75 66 66 65  e((char *)pBuffe
6650: 72 29 3b 0a 20 20 7d 0a 20 20 70 46 64 2d 3e 70  r);.  }.  pFd->p
6660: 53 68 6d 20 3d 20 30 3b 0a 0a 20 20 72 65 74 75  Shm = 0;..  retu
6670: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
6680: 20 69 6e 74 20 74 65 73 74 76 66 73 5f 6f 62 6a   int testvfs_obj
6690: 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61  _cmd(.  ClientDa
66a0: 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74  ta cd,.  Tcl_Int
66b0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
66c0: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
66d0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
66e0: 0a 29 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  .){.  Testvfs *p
66f0: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63 64   = (Testvfs *)cd
6700: 3b 0a 0a 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75  ;..  enum DB_enu
6710: 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f 53 48 4d  m { .    CMD_SHM
6720: 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c 20 43 4d  , CMD_DELETE, CM
6730: 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44 5f 49 4f  D_FILTER, CMD_IO
6740: 45 52 52 2c 20 43 4d 44 5f 53 43 52 49 50 54 2c  ERR, CMD_SCRIPT,
6750: 20 0a 20 20 20 20 43 4d 44 5f 44 45 56 43 48 41   .    CMD_DEVCHA
6760: 52 2c 20 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a  R, CMD_SECTORSIZ
6770: 45 2c 20 43 4d 44 5f 46 55 4c 4c 45 52 52 2c 20  E, CMD_FULLERR, 
6780: 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 0a  CMD_CANTOPENERR.
6790: 20 20 7d 3b 0a 20 20 73 74 72 75 63 74 20 54 65    };.  struct Te
67a0: 73 74 76 66 73 53 75 62 63 6d 64 20 7b 0a 20 20  stvfsSubcmd {.  
67b0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
67c0: 20 20 20 65 6e 75 6d 20 44 42 5f 65 6e 75 6d 20     enum DB_enum 
67d0: 65 43 6d 64 3b 0a 20 20 7d 20 61 53 75 62 63 6d  eCmd;.  } aSubcm
67e0: 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73  d[] = {.    { "s
67f0: 68 6d 22 2c 20 20 20 20 20 20 20 20 20 43 4d 44  hm",         CMD
6800: 5f 53 48 4d 20 20 20 20 20 20 20 20 20 7d 2c 0a  _SHM         },.
6810: 20 20 20 20 7b 20 22 64 65 6c 65 74 65 22 2c 20      { "delete", 
6820: 20 20 20 20 20 43 4d 44 5f 44 45 4c 45 54 45 20       CMD_DELETE 
6830: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66       },.    { "f
6840: 69 6c 74 65 72 22 2c 20 20 20 20 20 20 43 4d 44  ilter",      CMD
6850: 5f 46 49 4c 54 45 52 20 20 20 20 20 20 7d 2c 0a  _FILTER      },.
6860: 20 20 20 20 7b 20 22 69 6f 65 72 72 22 2c 20 20      { "ioerr",  
6870: 20 20 20 20 20 43 4d 44 5f 49 4f 45 52 52 20 20       CMD_IOERR  
6880: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 66       },.    { "f
6890: 75 6c 6c 65 72 72 22 2c 20 20 20 20 20 43 4d 44  ullerr",     CMD
68a0: 5f 46 55 4c 4c 45 52 52 20 20 20 20 20 7d 2c 0a  _FULLERR     },.
68b0: 20 20 20 20 7b 20 22 63 61 6e 74 6f 70 65 6e 65      { "cantopene
68c0: 72 72 22 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45  rr", CMD_CANTOPE
68d0: 4e 45 52 52 20 7d 2c 0a 20 20 20 20 7b 20 22 73  NERR },.    { "s
68e0: 63 72 69 70 74 22 2c 20 20 20 20 20 20 43 4d 44  cript",      CMD
68f0: 5f 53 43 52 49 50 54 20 20 20 20 20 20 7d 2c 0a  _SCRIPT      },.
6900: 20 20 20 20 7b 20 22 64 65 76 63 68 61 72 22 2c      { "devchar",
6910: 20 20 20 20 20 43 4d 44 5f 44 45 56 43 48 41 52       CMD_DEVCHAR
6920: 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b 20 22 73       },.    { "s
6930: 65 63 74 6f 72 73 69 7a 65 22 2c 20 20 43 4d 44  ectorsize",  CMD
6940: 5f 53 45 43 54 4f 52 53 49 5a 45 20 20 7d 2c 0a  _SECTORSIZE  },.
6950: 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20 20 7d      { 0, 0 }.  }
6960: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 0a 20 20  ;.  int i;.  .  
6970: 69 66 28 20 6f 62 6a 63 3c 32 20 29 7b 0a 20 20  if( objc<2 ){.  
6980: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
6990: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
69a0: 6a 76 2c 20 22 53 55 42 43 4f 4d 4d 41 4e 44 20  jv, "SUBCOMMAND 
69b0: 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 65 74 75 72  ...");.    retur
69c0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
69d0: 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e  .  if( Tcl_GetIn
69e0: 64 65 78 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74  dexFromObjStruct
69f0: 28 0a 20 20 20 20 20 20 20 20 69 6e 74 65 72 70  (.        interp
6a00: 2c 20 6f 62 6a 76 5b 31 5d 2c 20 61 53 75 62 63  , objv[1], aSubc
6a10: 6d 64 2c 20 73 69 7a 65 6f 66 28 61 53 75 62 63  md, sizeof(aSubc
6a20: 6d 64 5b 30 5d 29 2c 20 22 73 75 62 63 6f 6d 6d  md[0]), "subcomm
6a30: 61 6e 64 22 2c 20 30 2c 20 26 69 29 20 0a 20 20  and", 0, &i) .  
6a40: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  ){.    return TC
6a50: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54  L_ERROR;.  }.  T
6a60: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
6a70: 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77 69 74 63  nterp);..  switc
6a80: 68 28 20 61 53 75 62 63 6d 64 5b 69 5d 2e 65 43  h( aSubcmd[i].eC
6a90: 6d 64 20 29 7b 0a 20 20 20 20 63 61 73 65 20 43  md ){.    case C
6aa0: 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20 20 20 20  MD_SHM: {.      
6ab0: 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a 3b 0a 20  Tcl_Obj *pObj;. 
6ac0: 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
6ad0: 20 20 54 65 73 74 76 66 73 42 75 66 66 65 72 20    TestvfsBuffer 
6ae0: 2a 70 42 75 66 66 65 72 3b 0a 20 20 20 20 20 20  *pBuffer;.      
6af0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
6b00: 20 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 26     if( objc!=3 &
6b10: 26 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20  & objc!=4 ){.   
6b20: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
6b30: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
6b40: 20 6f 62 6a 76 2c 20 22 46 49 4c 45 20 3f 56 41   objv, "FILE ?VA
6b50: 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20 20 20 20  LUE?");.        
6b60: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
6b70: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6b80: 7a 4e 61 6d 65 20 3d 20 63 6b 61 6c 6c 6f 63 28  zName = ckalloc(
6b90: 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78 50 61  p->pParent->mxPa
6ba0: 74 68 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70  thname);.      p
6bb0: 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46 75 6c 6c  ->pParent->xFull
6bc0: 50 61 74 68 6e 61 6d 65 28 0a 20 20 20 20 20 20  Pathname(.      
6bd0: 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74 2c 20      p->pParent, 
6be0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
6bf0: 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20 20 20 20  jv[2]), .       
6c00: 20 20 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d     p->pParent->m
6c10: 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e 61 6d 65  xPathname, zName
6c20: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
6c30: 66 6f 72 28 70 42 75 66 66 65 72 3d 70 2d 3e 70  for(pBuffer=p->p
6c40: 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72 3b  Buffer; pBuffer;
6c50: 20 70 42 75 66 66 65 72 3d 70 42 75 66 66 65 72   pBuffer=pBuffer
6c60: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
6c70: 20 20 69 66 28 20 30 3d 3d 73 74 72 63 6d 70 28    if( 0==strcmp(
6c80: 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65 2c 20  pBuffer->zFile, 
6c90: 7a 4e 61 6d 65 29 20 29 20 62 72 65 61 6b 3b 0a  zName) ) break;.
6ca0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 6b        }.      ck
6cb0: 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 20  free(zName);.   
6cc0: 20 20 20 69 66 28 20 21 70 42 75 66 66 65 72 20     if( !pBuffer 
6cd0: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41  ){.        Tcl_A
6ce0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
6cf0: 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 66 69 6c  rp, "no such fil
6d00: 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  e: ", Tcl_GetStr
6d10: 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20 30 29  ing(objv[2]), 0)
6d20: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
6d30: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
6d40: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f 62    }.      if( ob
6d50: 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20 20 20 20  jc==4 ){.       
6d60: 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20 20 20 20   int n;.        
6d70: 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47 65 74 42  u8 *a = Tcl_GetB
6d80: 79 74 65 41 72 72 61 79 46 72 6f 6d 4f 62 6a 28  yteArrayFromObj(
6d90: 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b 0a 20 20  objv[3], &n);.  
6da0: 20 20 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d        int pgsz =
6db0: 20 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b 0a   pBuffer->pgsz;.
6dc0: 20 20 20 20 20 20 20 20 69 66 28 20 70 67 73 7a          if( pgsz
6dd0: 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20 36 35 35  ==0 ) pgsz = 655
6de0: 33 36 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  36;.        for(
6df0: 69 3d 30 3b 20 69 2a 70 67 73 7a 3c 6e 3b 20 69  i=0; i*pgsz<n; i
6e00: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  ++){.          i
6e10: 6e 74 20 6e 42 79 74 65 20 3d 20 70 67 73 7a 3b  nt nByte = pgsz;
6e20: 0a 20 20 20 20 20 20 20 20 20 20 74 76 66 73 41  .          tvfsA
6e30: 6c 6c 6f 63 50 61 67 65 28 70 42 75 66 66 65 72  llocPage(pBuffer
6e40: 2c 20 69 2c 20 70 67 73 7a 29 3b 0a 20 20 20 20  , i, pgsz);.    
6e50: 20 20 20 20 20 20 69 66 28 20 6e 2d 69 2a 70 67        if( n-i*pg
6e60: 73 7a 3c 70 67 73 7a 20 29 7b 0a 20 20 20 20 20  sz<pgsz ){.     
6e70: 20 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 6e         nByte = n
6e80: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
6e90: 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70          memcpy(p
6ea0: 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69 5d  Buffer->aPage[i]
6eb0: 2c 20 26 61 5b 69 2a 70 67 73 7a 5d 2c 20 6e 42  , &a[i*pgsz], nB
6ec0: 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  yte);.        }.
6ed0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70        }..      p
6ee0: 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  Obj = Tcl_NewObj
6ef0: 28 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  ();.      for(i=
6f00: 30 3b 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67  0; pBuffer->aPag
6f10: 65 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  e[i]; i++){.    
6f20: 20 20 20 20 69 6e 74 20 70 67 73 7a 20 3d 20 70      int pgsz = p
6f30: 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b 0a 20 20  Buffer->pgsz;.  
6f40: 20 20 20 20 20 20 69 66 28 20 70 67 73 7a 3d 3d        if( pgsz==
6f50: 30 20 29 20 70 67 73 7a 20 3d 20 36 35 35 33 36  0 ) pgsz = 65536
6f60: 3b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70  ;.        Tcl_Ap
6f70: 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28 70 4f 62  pendObjToObj(pOb
6f80: 6a 2c 20 54 63 6c 5f 4e 65 77 42 79 74 65 41 72  j, Tcl_NewByteAr
6f90: 72 61 79 4f 62 6a 28 70 42 75 66 66 65 72 2d 3e  rayObj(pBuffer->
6fa0: 61 50 61 67 65 5b 69 5d 2c 20 70 67 73 7a 29 29  aPage[i], pgsz))
6fb0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6fc0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
6fd0: 28 69 6e 74 65 72 70 2c 20 70 4f 62 6a 29 3b 0a  (interp, pObj);.
6fe0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
6ff0: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44   }..    case CMD
7000: 5f 46 49 4c 54 45 52 3a 20 7b 0a 20 20 20 20 20  _FILTER: {.     
7010: 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20 56   static struct V
7020: 66 73 4d 65 74 68 6f 64 20 7b 0a 20 20 20 20 20  fsMethod {.     
7030: 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a     char *zName;.
7040: 20 20 20 20 20 20 20 20 69 6e 74 20 6d 61 73 6b          int mask
7050: 3b 0a 20 20 20 20 20 20 7d 20 76 66 73 6d 65 74  ;.      } vfsmet
7060: 68 6f 64 20 5b 5d 20 3d 20 7b 0a 20 20 20 20 20  hod [] = {.     
7070: 20 20 20 7b 20 22 78 53 68 6d 4f 70 65 6e 22 2c     { "xShmOpen",
7080: 20 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d 4f      TESTVFS_SHMO
7090: 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20 20  PEN_MASK },.    
70a0: 20 20 20 20 7b 20 22 78 53 68 6d 4c 6f 63 6b 22      { "xShmLock"
70b0: 2c 20 20 20 20 54 45 53 54 56 46 53 5f 53 48 4d  ,    TESTVFS_SHM
70c0: 4c 4f 43 4b 5f 4d 41 53 4b 20 7d 2c 0a 20 20 20  LOCK_MASK },.   
70d0: 20 20 20 20 20 7b 20 22 78 53 68 6d 42 61 72 72       { "xShmBarr
70e0: 69 65 72 22 2c 20 54 45 53 54 56 46 53 5f 53 48  ier", TESTVFS_SH
70f0: 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b 20 7d 2c  MBARRIER_MASK },
7100: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d  .        { "xShm
7110: 55 6e 6d 61 70 22 2c 20 20 20 54 45 53 54 56 46  Unmap",   TESTVF
7120: 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20  S_SHMCLOSE_MASK 
7130: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53  },.        { "xS
7140: 68 6d 4d 61 70 22 2c 20 20 20 20 20 54 45 53 54  hmMap",     TEST
7150: 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53 4b 20  VFS_SHMMAP_MASK 
7160: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 53  },.        { "xS
7170: 79 6e 63 22 2c 20 20 20 20 20 20 20 54 45 53 54  ync",       TEST
7180: 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 7d 2c  VFS_SYNC_MASK },
7190: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 44 65 6c  .        { "xDel
71a0: 65 74 65 22 2c 20 20 20 20 20 54 45 53 54 56 46  ete",     TESTVF
71b0: 53 5f 44 45 4c 45 54 45 5f 4d 41 53 4b 20 7d 2c  S_DELETE_MASK },
71c0: 0a 20 20 20 20 20 20 20 20 7b 20 22 78 57 72 69  .        { "xWri
71d0: 74 65 22 2c 20 20 20 20 20 20 54 45 53 54 56 46  te",      TESTVF
71e0: 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 7d 2c 0a  S_WRITE_MASK },.
71f0: 20 20 20 20 20 20 20 20 7b 20 22 78 54 72 75 6e          { "xTrun
7200: 63 61 74 65 22 2c 20 20 20 54 45 53 54 56 46 53  cate",   TESTVFS
7210: 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 7d  _TRUNCATE_MASK }
7220: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 4f 70  ,.        { "xOp
7230: 65 6e 22 2c 20 20 20 20 20 20 20 54 45 53 54 56  en",       TESTV
7240: 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a  FS_OPEN_MASK },.
7250: 20 20 20 20 20 20 20 20 7b 20 22 78 43 6c 6f 73          { "xClos
7260: 65 22 2c 20 20 20 20 20 20 54 45 53 54 56 46 53  e",      TESTVFS
7270: 5f 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d 2c 0a 20  _CLOSE_MASK },. 
7280: 20 20 20 20 20 20 20 7b 20 22 78 41 63 63 65 73         { "xAcces
7290: 73 22 2c 20 20 20 20 20 54 45 53 54 56 46 53 5f  s",     TESTVFS_
72a0: 41 43 43 45 53 53 5f 4d 41 53 4b 20 7d 2c 0a 20  ACCESS_MASK },. 
72b0: 20 20 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63       };.      Tc
72c0: 6c 5f 4f 62 6a 20 2a 2a 61 70 45 6c 65 6d 20 3d  l_Obj **apElem =
72d0: 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 6e 45   0;.      int nE
72e0: 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  lem = 0;.      i
72f0: 6e 74 20 69 3b 0a 20 20 20 20 20 20 69 6e 74 20  nt i;.      int 
7300: 6d 61 73 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  mask = 0;.      
7310: 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20  if( objc!=3 ){. 
7320: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
7330: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
7340: 32 2c 20 6f 62 6a 76 2c 20 22 4c 49 53 54 22 29  2, objv, "LIST")
7350: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7360: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
7370: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 54 63    }.      if( Tc
7380: 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d  l_ListObjGetElem
7390: 65 6e 74 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a  ents(interp, obj
73a0: 76 5b 32 5d 2c 20 26 6e 45 6c 65 6d 2c 20 26 61  v[2], &nElem, &a
73b0: 70 45 6c 65 6d 29 20 29 7b 0a 20 20 20 20 20 20  pElem) ){.      
73c0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
73d0: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
73e0: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
73f0: 74 28 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 20  t(interp);.     
7400: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 45 6c 65   for(i=0; i<nEle
7410: 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  m; i++){.       
7420: 20 69 6e 74 20 69 4d 65 74 68 6f 64 3b 0a 20 20   int iMethod;.  
7430: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 45 6c 65        char *zEle
7440: 6d 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  m = Tcl_GetStrin
7450: 67 28 61 70 45 6c 65 6d 5b 69 5d 29 3b 0a 20 20  g(apElem[i]);.  
7460: 20 20 20 20 20 20 66 6f 72 28 69 4d 65 74 68 6f        for(iMetho
7470: 64 3d 30 3b 20 69 4d 65 74 68 6f 64 3c 41 72 72  d=0; iMethod<Arr
7480: 61 79 53 69 7a 65 28 76 66 73 6d 65 74 68 6f 64  aySize(vfsmethod
7490: 29 3b 20 69 4d 65 74 68 6f 64 2b 2b 29 7b 0a 20  ); iMethod++){. 
74a0: 20 20 20 20 20 20 20 20 20 69 66 28 20 73 74 72           if( str
74b0: 63 6d 70 28 7a 45 6c 65 6d 2c 20 76 66 73 6d 65  cmp(zElem, vfsme
74c0: 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d 2e 7a 4e  thod[iMethod].zN
74d0: 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ame)==0 ){.     
74e0: 20 20 20 20 20 20 20 6d 61 73 6b 20 7c 3d 20 76         mask |= v
74f0: 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64  fsmethod[iMethod
7500: 5d 2e 6d 61 73 6b 3b 0a 20 20 20 20 20 20 20 20  ].mask;.        
7510: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
7520: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
7530: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 4d 65  .        if( iMe
7540: 74 68 6f 64 3d 3d 41 72 72 61 79 53 69 7a 65 28  thod==ArraySize(
7550: 76 66 73 6d 65 74 68 6f 64 29 20 29 7b 0a 20 20  vfsmethod) ){.  
7560: 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70 65          Tcl_Appe
7570: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
7580: 20 22 75 6e 6b 6e 6f 77 6e 20 6d 65 74 68 6f 64   "unknown method
7590: 3a 20 22 2c 20 7a 45 6c 65 6d 2c 20 30 29 3b 0a  : ", zElem, 0);.
75a0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
75b0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
75c0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
75d0: 20 20 20 20 70 2d 3e 6d 61 73 6b 20 3d 20 6d 61      p->mask = ma
75e0: 73 6b 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  sk;.      break;
75f0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
7600: 20 43 4d 44 5f 53 43 52 49 50 54 3a 20 7b 0a 20   CMD_SCRIPT: {. 
7610: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33       if( objc==3
7620: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
7630: 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 20 20 69  nByte;.        i
7640: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 29 7b  f( p->pScript ){
7650: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 44  .          Tcl_D
7660: 65 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70  ecrRefCount(p->p
7670: 53 63 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20  Script);.       
7680: 20 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20     ckfree((char 
7690: 2a 29 70 2d 3e 61 70 53 63 72 69 70 74 29 3b 0a  *)p->apScript);.
76a0: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 61 70 53            p->apS
76b0: 63 72 69 70 74 20 3d 20 30 3b 0a 20 20 20 20 20  cript = 0;.     
76c0: 20 20 20 20 20 70 2d 3e 6e 53 63 72 69 70 74 20       p->nScript 
76d0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 70  = 0;.          p
76e0: 2d 3e 70 53 63 72 69 70 74 20 3d 20 30 3b 0a 20  ->pScript = 0;. 
76f0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
7700: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72   Tcl_GetStringFr
7710: 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 32 5d 2c 20 26  omObj(objv[2], &
7720: 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20  nByte);.        
7730: 69 66 28 20 6e 42 79 74 65 3e 30 20 29 7b 0a 20  if( nByte>0 ){. 
7740: 20 20 20 20 20 20 20 20 20 70 2d 3e 70 53 63 72           p->pScr
7750: 69 70 74 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63  ipt = Tcl_Duplic
7760: 61 74 65 4f 62 6a 28 6f 62 6a 76 5b 32 5d 29 3b  ateObj(objv[2]);
7770: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 49  .          Tcl_I
7780: 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70  ncrRefCount(p->p
7790: 53 63 72 69 70 74 29 3b 0a 20 20 20 20 20 20 20  Script);.       
77a0: 20 7d 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69   }.      }else i
77b0: 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20  f( objc!=2 ){.  
77c0: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e        Tcl_WrongN
77d0: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32  umArgs(interp, 2
77e0: 2c 20 6f 62 6a 76 2c 20 22 3f 53 43 52 49 50 54  , objv, "?SCRIPT
77f0: 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  ?");.        ret
7800: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7810: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 54 63       }..      Tc
7820: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e  l_ResetResult(in
7830: 74 65 72 70 29 3b 0a 20 20 20 20 20 20 69 66 28  terp);.      if(
7840: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 20 54 63   p->pScript ) Tc
7850: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_SetObjResult(i
7860: 6e 74 65 72 70 2c 20 70 2d 3e 70 53 63 72 69 70  nterp, p->pScrip
7870: 74 29 3b 0a 0a 20 20 20 20 20 20 62 72 65 61 6b  t);..      break
7880: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 0a  ;.    }..    /*.
7890: 20 20 20 20 2a 2a 20 54 45 53 54 56 46 53 20 69      ** TESTVFS i
78a0: 6f 65 72 72 20 3f 49 46 41 49 4c 20 50 45 52 53  oerr ?IFAIL PERS
78b0: 49 53 54 3f 0a 20 20 20 20 2a 2a 0a 20 20 20 20  IST?.    **.    
78c0: 2a 2a 20 20 20 57 68 65 72 65 20 49 46 41 49 4c  **   Where IFAIL
78d0: 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61   is an integer a
78e0: 6e 64 20 50 45 52 53 49 53 54 20 69 73 20 62 6f  nd PERSIST is bo
78f0: 6f 6c 65 61 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20  olean..    */.  
7900: 20 20 63 61 73 65 20 43 4d 44 5f 43 41 4e 54 4f    case CMD_CANTO
7910: 50 45 4e 45 52 52 3a 0a 20 20 20 20 63 61 73 65  PENERR:.    case
7920: 20 43 4d 44 5f 49 4f 45 52 52 3a 0a 20 20 20 20   CMD_IOERR:.    
7930: 63 61 73 65 20 43 4d 44 5f 46 55 4c 4c 45 52 52  case CMD_FULLERR
7940: 3a 20 7b 0a 20 20 20 20 20 20 54 65 73 74 46 61  : {.      TestFa
7950: 75 6c 74 49 6e 6a 65 63 74 20 2a 70 54 65 73 74  ultInject *pTest
7960: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 52 65 74  ;.      int iRet
7970: 3b 0a 0a 20 20 20 20 20 20 73 77 69 74 63 68 28  ;..      switch(
7980: 20 61 53 75 62 63 6d 64 5b 69 5d 2e 65 43 6d 64   aSubcmd[i].eCmd
7990: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61 73 65   ){.        case
79a0: 20 43 4d 44 5f 49 4f 45 52 52 3a 20 70 54 65 73   CMD_IOERR: pTes
79b0: 74 20 3d 20 26 70 2d 3e 69 6f 65 72 72 5f 65 72  t = &p->ioerr_er
79c0: 72 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  r; break;.      
79d0: 20 20 63 61 73 65 20 43 4d 44 5f 46 55 4c 4c 45    case CMD_FULLE
79e0: 52 52 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e  RR: pTest = &p->
79f0: 66 75 6c 6c 5f 65 72 72 3b 20 62 72 65 61 6b 3b  full_err; break;
7a00: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 43 4d  .        case CM
7a10: 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 3a 20 70  D_CANTOPENERR: p
7a20: 54 65 73 74 20 3d 20 26 70 2d 3e 63 61 6e 74 6f  Test = &p->canto
7a30: 70 65 6e 5f 65 72 72 3b 20 62 72 65 61 6b 3b 0a  pen_err; break;.
7a40: 20 20 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a          default:
7a50: 20 61 73 73 65 72 74 28 30 29 3b 0a 20 20 20 20   assert(0);.    
7a60: 20 20 7d 0a 20 20 20 20 20 20 69 52 65 74 20 3d    }.      iRet =
7a70: 20 70 54 65 73 74 2d 3e 6e 46 61 69 6c 3b 0a 20   pTest->nFail;. 
7a80: 20 20 20 20 20 70 54 65 73 74 2d 3e 6e 46 61 69       pTest->nFai
7a90: 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 65  l = 0;.      pTe
7aa0: 73 74 2d 3e 65 46 61 75 6c 74 20 3d 20 30 3b 0a  st->eFault = 0;.
7ab0: 20 20 20 20 20 20 70 54 65 73 74 2d 3e 69 43 6e        pTest->iCn
7ac0: 74 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20 69 66  t = 0;..      if
7ad0: 28 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20  ( objc==4 ){.   
7ae0: 20 20 20 20 20 69 6e 74 20 69 43 6e 74 2c 20 69       int iCnt, i
7af0: 50 65 72 73 69 73 74 3b 0a 20 20 20 20 20 20 20  Persist;.       
7b00: 20 69 66 28 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c   if( TCL_OK!=Tcl
7b10: 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  _GetIntFromObj(i
7b20: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20  nterp, objv[2], 
7b30: 26 69 43 6e 74 29 0a 20 20 20 20 20 20 20 20 20  &iCnt).         
7b40: 7c 7c 20 54 43 4c 5f 4f 4b 21 3d 54 63 6c 5f 47  || TCL_OK!=Tcl_G
7b50: 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a  etBooleanFromObj
7b60: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 33 5d  (interp, objv[3]
7b70: 2c 20 26 69 50 65 72 73 69 73 74 29 0a 20 20 20  , &iPersist).   
7b80: 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20       ){.        
7b90: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
7ba0: 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  OR;.        }.  
7bb0: 20 20 20 20 20 20 70 54 65 73 74 2d 3e 65 46 61        pTest->eFa
7bc0: 75 6c 74 20 3d 20 69 50 65 72 73 69 73 74 3f 46  ult = iPersist?F
7bd0: 41 55 4c 54 5f 49 4e 4a 45 43 54 5f 50 45 52 53  AULT_INJECT_PERS
7be0: 49 53 54 45 4e 54 3a 46 41 55 4c 54 5f 49 4e 4a  ISTENT:FAULT_INJ
7bf0: 45 43 54 5f 54 52 41 4e 53 49 45 4e 54 3b 0a 20  ECT_TRANSIENT;. 
7c00: 20 20 20 20 20 20 20 70 54 65 73 74 2d 3e 69 43         pTest->iC
7c10: 6e 74 20 3d 20 69 43 6e 74 3b 0a 20 20 20 20 20  nt = iCnt;.     
7c20: 20 7d 65 6c 73 65 20 69 66 28 20 6f 62 6a 63 21   }else if( objc!
7c30: 3d 32 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63  =2 ){.        Tc
7c40: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
7c50: 6e 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20  nterp, 2, objv, 
7c60: 22 3f 43 4e 54 20 50 45 52 53 49 53 54 3f 22 29  "?CNT PERSIST?")
7c70: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
7c80: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
7c90: 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65    }.      Tcl_Se
7ca0: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
7cb0: 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a  p, Tcl_NewIntObj
7cc0: 28 69 52 65 74 29 29 3b 0a 20 20 20 20 20 20 62  (iRet));.      b
7cd0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
7ce0: 20 63 61 73 65 20 43 4d 44 5f 44 45 4c 45 54 45   case CMD_DELETE
7cf0: 3a 20 7b 0a 20 20 20 20 20 20 54 63 6c 5f 44 65  : {.      Tcl_De
7d00: 6c 65 74 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  leteCommand(inte
7d10: 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  rp, Tcl_GetStrin
7d20: 67 28 6f 62 6a 76 5b 30 5d 29 29 3b 0a 20 20 20  g(objv[0]));.   
7d30: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
7d40: 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f 44 45  .    case CMD_DE
7d50: 56 43 48 41 52 3a 20 7b 0a 20 20 20 20 20 20 73  VCHAR: {.      s
7d60: 74 72 75 63 74 20 44 65 76 69 63 65 46 6c 61 67  truct DeviceFlag
7d70: 20 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20   {.        char 
7d80: 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 20 20 20  *zName;.        
7d90: 69 6e 74 20 69 56 61 6c 75 65 3b 0a 20 20 20 20  int iValue;.    
7da0: 20 20 7d 20 61 46 6c 61 67 5b 5d 20 3d 20 7b 0a    } aFlag[] = {.
7db0: 20 20 20 20 20 20 20 20 7b 20 22 64 65 66 61 75          { "defau
7dc0: 6c 74 22 2c 20 20 20 20 20 20 20 20 20 20 20 20  lt",            
7dd0: 20 20 20 2d 31 20 7d 2c 0a 20 20 20 20 20 20 20     -1 },.       
7de0: 20 7b 20 22 61 74 6f 6d 69 63 22 2c 20 20 20 20   { "atomic",    
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7e00: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 20  TE_IOCAP_ATOMIC 
7e10: 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20       },.        
7e20: 7b 20 22 61 74 6f 6d 69 63 35 31 32 22 2c 20 20  { "atomic512",  
7e30: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
7e40: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 35 31  E_IOCAP_ATOMIC51
7e50: 32 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  2   },.        {
7e60: 20 22 61 74 6f 6d 69 63 31 6b 22 2c 20 20 20 20   "atomic1k",    
7e70: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7e80: 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 31 4b 20  _IOCAP_ATOMIC1K 
7e90: 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20     },.        { 
7ea0: 22 61 74 6f 6d 69 63 32 6b 22 2c 20 20 20 20 20  "atomic2k",     
7eb0: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7ec0: 49 4f 43 41 50 5f 41 54 4f 4d 49 43 32 4b 20 20  IOCAP_ATOMIC2K  
7ed0: 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22    },.        { "
7ee0: 61 74 6f 6d 69 63 34 6b 22 2c 20 20 20 20 20 20  atomic4k",      
7ef0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49          SQLITE_I
7f00: 4f 43 41 50 5f 41 54 4f 4d 49 43 34 4b 20 20 20  OCAP_ATOMIC4K   
7f10: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61   },.        { "a
7f20: 74 6f 6d 69 63 38 6b 22 2c 20 20 20 20 20 20 20  tomic8k",       
7f30: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f         SQLITE_IO
7f40: 43 41 50 5f 41 54 4f 4d 49 43 38 4b 20 20 20 20  CAP_ATOMIC8K    
7f50: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74  },.        { "at
7f60: 6f 6d 69 63 31 36 6b 22 2c 20 20 20 20 20 20 20  omic16k",       
7f70: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43        SQLITE_IOC
7f80: 41 50 5f 41 54 4f 4d 49 43 31 36 4b 20 20 20 7d  AP_ATOMIC16K   }
7f90: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f  ,.        { "ato
7fa0: 6d 69 63 33 32 6b 22 2c 20 20 20 20 20 20 20 20  mic32k",        
7fb0: 20 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41       SQLITE_IOCA
7fc0: 50 5f 41 54 4f 4d 49 43 33 32 4b 20 20 20 7d 2c  P_ATOMIC32K   },
7fd0: 0a 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d  .        { "atom
7fe0: 69 63 36 34 6b 22 2c 20 20 20 20 20 20 20 20 20  ic64k",         
7ff0: 20 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50      SQLITE_IOCAP
8000: 5f 41 54 4f 4d 49 43 36 34 4b 20 20 20 7d 2c 0a  _ATOMIC64K   },.
8010: 20 20 20 20 20 20 20 20 7b 20 22 73 65 71 75 65          { "seque
8020: 6e 74 69 61 6c 22 2c 20 20 20 20 20 20 20 20 20  ntial",         
8030: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
8040: 53 45 51 55 45 4e 54 49 41 4c 20 20 7d 2c 0a 20  SEQUENTIAL  },. 
8050: 20 20 20 20 20 20 20 7b 20 22 73 61 66 65 5f 61         { "safe_a
8060: 70 70 65 6e 64 22 2c 20 20 20 20 20 20 20 20 20  ppend",         
8070: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53    SQLITE_IOCAP_S
8080: 41 46 45 5f 41 50 50 45 4e 44 20 7d 2c 0a 20 20  AFE_APPEND },.  
8090: 20 20 20 20 20 20 7b 20 22 75 6e 64 65 6c 65 74        { "undelet
80a0: 61 62 6c 65 5f 77 68 65 6e 5f 6f 70 65 6e 22 2c  able_when_open",
80b0: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 55 4e   SQLITE_IOCAP_UN
80c0: 44 45 4c 45 54 41 42 4c 45 5f 57 48 45 4e 5f 4f  DELETABLE_WHEN_O
80d0: 50 45 4e 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  PEN },.        {
80e0: 20 30 2c 20 30 20 7d 0a 20 20 20 20 20 20 7d 3b   0, 0 }.      };
80f0: 0a 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a  .      Tcl_Obj *
8100: 70 52 65 74 3b 0a 20 20 20 20 20 20 69 6e 74 20  pRet;.      int 
8110: 69 46 6c 61 67 3b 0a 0a 20 20 20 20 20 20 69 66  iFlag;..      if
8120: 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20 20 20 20  ( objc>3 ){.    
8130: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
8140: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c 20  Args(interp, 2, 
8150: 6f 62 6a 76 2c 20 22 3f 41 54 54 52 2d 4c 49 53  objv, "?ATTR-LIS
8160: 54 3f 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65  T?");.        re
8170: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
8180: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
8190: 28 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20  ( objc==3 ){.   
81a0: 20 20 20 20 20 69 6e 74 20 6a 3b 0a 20 20 20 20       int j;.    
81b0: 20 20 20 20 69 6e 74 20 69 4e 65 77 20 3d 20 30      int iNew = 0
81c0: 3b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4f 62  ;.        Tcl_Ob
81d0: 6a 20 2a 2a 66 6c 61 67 73 20 3d 20 30 3b 0a 20  j **flags = 0;. 
81e0: 20 20 20 20 20 20 20 69 6e 74 20 6e 46 6c 61 67         int nFlag
81f0: 73 20 3d 20 30 3b 0a 0a 20 20 20 20 20 20 20 20  s = 0;..        
8200: 69 66 28 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47  if( Tcl_ListObjG
8210: 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72  etElements(inter
8220: 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6e 46 6c  p, objv[2], &nFl
8230: 61 67 73 2c 20 26 66 6c 61 67 73 29 20 29 7b 0a  ags, &flags) ){.
8240: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
8250: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
8260: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 66      }..        f
8270: 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 46 6c 61 67 73  or(j=0; j<nFlags
8280: 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; j++){.        
8290: 20 20 69 6e 74 20 69 64 78 20 3d 20 30 3b 0a 20    int idx = 0;. 
82a0: 20 20 20 20 20 20 20 20 20 69 66 28 20 54 63 6c           if( Tcl
82b0: 5f 47 65 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a  _GetIndexFromObj
82c0: 53 74 72 75 63 74 28 69 6e 74 65 72 70 2c 20 66  Struct(interp, f
82d0: 6c 61 67 73 5b 6a 5d 2c 20 61 46 6c 61 67 2c 20  lags[j], aFlag, 
82e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
82f0: 20 73 69 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d   sizeof(aFlag[0]
8300: 29 2c 20 22 66 6c 61 67 22 2c 20 30 2c 20 26 69  ), "flag", 0, &i
8310: 64 78 29 20 0a 20 20 20 20 20 20 20 20 20 20 29  dx) .          )
8320: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65  {.            re
8330: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
8340: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
8350: 20 20 20 20 20 20 69 66 28 20 61 46 6c 61 67 5b        if( aFlag[
8360: 69 64 78 5d 2e 69 56 61 6c 75 65 3c 30 20 26 26  idx].iValue<0 &&
8370: 20 6e 46 6c 61 67 73 3e 31 20 29 7b 0a 20 20 20   nFlags>1 ){.   
8380: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70 70           Tcl_App
8390: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
83a0: 2c 20 22 62 61 64 20 66 6c 61 67 73 3a 20 22 2c  , "bad flags: ",
83b0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
83c0: 62 6a 76 5b 32 5d 29 2c 20 30 29 3b 0a 20 20 20  bjv[2]), 0);.   
83d0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
83e0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
83f0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
8400: 20 69 4e 65 77 20 7c 3d 20 61 46 6c 61 67 5b 69   iNew |= aFlag[i
8410: 64 78 5d 2e 69 56 61 6c 75 65 3b 0a 20 20 20 20  dx].iValue;.    
8420: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 70      }..        p
8430: 2d 3e 69 44 65 76 63 68 61 72 20 3d 20 69 4e 65  ->iDevchar = iNe
8440: 77 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  w;.      }..    
8450: 20 20 70 52 65 74 20 3d 20 54 63 6c 5f 4e 65 77    pRet = Tcl_New
8460: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f 72  Obj();.      for
8470: 28 69 46 6c 61 67 3d 30 3b 20 69 46 6c 61 67 3c  (iFlag=0; iFlag<
8480: 73 69 7a 65 6f 66 28 61 46 6c 61 67 29 2f 73 69  sizeof(aFlag)/si
8490: 7a 65 6f 66 28 61 46 6c 61 67 5b 30 5d 29 3b 20  zeof(aFlag[0]); 
84a0: 69 46 6c 61 67 2b 2b 29 7b 0a 20 20 20 20 20 20  iFlag++){.      
84b0: 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63 68 61    if( p->iDevcha
84c0: 72 20 26 20 61 46 6c 61 67 5b 69 46 6c 61 67 5d  r & aFlag[iFlag]
84d0: 2e 69 56 61 6c 75 65 20 29 7b 0a 20 20 20 20 20  .iValue ){.     
84e0: 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a       Tcl_ListObj
84f0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 0a 20  AppendElement(. 
8500: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74               int
8510: 65 72 70 2c 20 70 52 65 74 2c 20 54 63 6c 5f 4e  erp, pRet, Tcl_N
8520: 65 77 53 74 72 69 6e 67 4f 62 6a 28 61 46 6c 61  ewStringObj(aFla
8530: 67 5b 69 46 6c 61 67 5d 2e 7a 4e 61 6d 65 2c 20  g[iFlag].zName, 
8540: 2d 31 29 0a 20 20 20 20 20 20 20 20 20 20 29 3b  -1).          );
8550: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
8560: 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f 53 65 74   }.      Tcl_Set
8570: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
8580: 2c 20 70 52 65 74 29 3b 0a 0a 20 20 20 20 20 20  , pRet);..      
8590: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
85a0: 20 20 63 61 73 65 20 43 4d 44 5f 53 45 43 54 4f    case CMD_SECTO
85b0: 52 53 49 5a 45 3a 20 7b 0a 20 20 20 20 20 20 69  RSIZE: {.      i
85c0: 66 28 20 6f 62 6a 63 3e 33 20 29 7b 0a 20 20 20  f( objc>3 ){.   
85d0: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
85e0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
85f0: 20 6f 62 6a 76 2c 20 22 3f 56 41 4c 55 45 3f 22   objv, "?VALUE?"
8600: 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  );.        retur
8610: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20  n TCL_ERROR;.   
8620: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6f     }.      if( o
8630: 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20  bjc==3 ){.      
8640: 20 20 69 6e 74 20 69 4e 65 77 20 3d 20 30 3b 0a    int iNew = 0;.
8650: 20 20 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f          if( Tcl_
8660: 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e  GetIntFromObj(in
8670: 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26  terp, objv[2], &
8680: 69 4e 65 77 29 20 29 7b 0a 20 20 20 20 20 20 20  iNew) ){.       
8690: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
86a0: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ROR;.        }. 
86b0: 20 20 20 20 20 20 20 70 2d 3e 69 53 65 63 74 6f         p->iSecto
86c0: 72 73 69 7a 65 20 3d 20 69 4e 65 77 3b 0a 20 20  rsize = iNew;.  
86d0: 20 20 20 20 7d 0a 20 20 20 20 20 20 54 63 6c 5f      }.      Tcl_
86e0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
86f0: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f  erp, Tcl_NewIntO
8700: 62 6a 28 70 2d 3e 69 53 65 63 74 6f 72 73 69 7a  bj(p->iSectorsiz
8710: 65 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  e));.      break
8720: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
8730: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
8740: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 65 73  .static void tes
8750: 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 28 43 6c 69  tvfs_obj_del(Cli
8760: 65 6e 74 44 61 74 61 20 63 64 29 7b 0a 20 20 54  entData cd){.  T
8770: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
8780: 74 76 66 73 20 2a 29 63 64 3b 0a 20 20 69 66 28  tvfs *)cd;.  if(
8790: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 20 54 63   p->pScript ) Tc
87a0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
87b0: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 73 71  ->pScript);.  sq
87c0: 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72 65 67 69  lite3_vfs_unregi
87d0: 73 74 65 72 28 70 2d 3e 70 56 66 73 29 3b 0a 20  ster(p->pVfs);. 
87e0: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
87f0: 70 2d 3e 61 70 53 63 72 69 70 74 29 3b 0a 20 20  p->apScript);.  
8800: 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29 70  ckfree((char *)p
8810: 2d 3e 70 56 66 73 29 3b 0a 20 20 63 6b 66 72 65  ->pVfs);.  ckfre
8820: 65 28 28 63 68 61 72 20 2a 29 70 29 3b 0a 7d 0a  e((char *)p);.}.
8830: 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 20 74  ./*.** Usage:  t
8840: 65 73 74 76 66 73 20 56 46 53 4e 41 4d 45 20 3f  estvfs VFSNAME ?
8850: 53 57 49 54 43 48 45 53 3f 0a 2a 2a 0a 2a 2a 20  SWITCHES?.**.** 
8860: 53 77 69 74 63 68 65 73 20 61 72 65 3a 0a 2a 2a  Switches are:.**
8870: 0a 2a 2a 20 20 20 2d 6e 6f 73 68 6d 20 20 20 42  .**   -noshm   B
8880: 4f 4f 4c 45 41 4e 20 20 20 20 20 20 20 20 20 20  OOLEAN          
8890: 20 20 20 28 54 72 75 65 20 74 6f 20 6f 6d 69 74     (True to omit
88a0: 20 73 68 6d 20 6d 65 74 68 6f 64 73 2e 20 44 65   shm methods. De
88b0: 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 20  fault false).** 
88c0: 20 20 2d 64 65 66 61 75 6c 74 20 42 4f 4f 4c 45    -default BOOLE
88d0: 41 4e 20 20 20 20 20 20 20 20 20 20 20 20 20 28  AN             (
88e0: 54 72 75 65 20 74 6f 20 6d 61 6b 65 20 74 68 65  True to make the
88f0: 20 76 66 73 20 64 65 66 61 75 6c 74 2e 20 44 65   vfs default. De
8900: 66 61 75 6c 74 20 66 61 6c 73 65 29 0a 2a 2a 0a  fault false).**.
8910: 2a 2a 20 54 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ** This command 
8920: 63 72 65 61 74 65 73 20 74 77 6f 20 74 68 69 6e  creates two thin
8930: 67 73 20 77 68 65 6e 20 69 74 20 69 73 20 69 6e  gs when it is in
8940: 76 6f 6b 65 64 3a 20 61 6e 20 53 51 4c 69 74 65  voked: an SQLite
8950: 20 56 46 53 2c 20 61 6e 64 0a 2a 2a 20 61 20 54   VFS, and.** a T
8960: 63 6c 20 63 6f 6d 6d 61 6e 64 2e 20 42 6f 74 68  cl command. Both
8970: 20 61 72 65 20 6e 61 6d 65 64 20 56 46 53 4e 41   are named VFSNA
8980: 4d 45 2e 20 54 68 65 20 56 46 53 20 69 73 20 69  ME. The VFS is i
8990: 6e 73 74 61 6c 6c 65 64 2e 20 49 74 20 69 73 20  nstalled. It is 
89a0: 6e 6f 74 0a 2a 2a 20 69 6e 73 74 61 6c 6c 65 64  not.** installed
89b0: 20 61 73 20 74 68 65 20 64 65 66 61 75 6c 74 20   as the default 
89c0: 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 56  VFS..**.** The V
89d0: 46 53 20 70 61 73 73 65 73 20 61 6c 6c 20 66 69  FS passes all fi
89e0: 6c 65 20 49 2f 4f 20 63 61 6c 6c 73 20 74 68 72  le I/O calls thr
89f0: 6f 75 67 68 20 74 6f 20 74 68 65 20 75 6e 64 65  ough to the unde
8a00: 72 6c 79 69 6e 67 20 56 46 53 2e 0a 2a 2a 0a 2a  rlying VFS..**.*
8a10: 2a 20 57 68 65 6e 65 76 65 72 20 74 68 65 20 78  * Whenever the x
8a20: 53 68 6d 4d 61 70 20 6d 65 74 68 6f 64 20 6f 66  ShmMap method of
8a30: 20 74 68 65 20 56 46 53 0a 2a 2a 20 69 73 20 69   the VFS.** is i
8a40: 6e 76 6f 6b 65 64 2c 20 74 68 65 20 53 43 52 49  nvoked, the SCRI
8a50: 50 54 20 69 73 20 65 78 65 63 75 74 65 64 20 61  PT is executed a
8a60: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
8a70: 20 20 20 53 43 52 49 50 54 20 78 53 68 6d 4d 61     SCRIPT xShmMa
8a80: 70 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49 44  p    FILENAME ID
8a90: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65  .**.** The value
8aa0: 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68 65   returned by the
8ab0: 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20 53   invocation of S
8ac0: 43 52 49 50 54 20 61 62 6f 76 65 20 69 73 20 69  CRIPT above is i
8ad0: 6e 74 65 72 70 72 65 74 65 64 20 61 73 0a 2a 2a  nterpreted as.**
8ae0: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
8af0: 20 63 6f 64 65 20 61 6e 64 20 72 65 74 75 72 6e   code and return
8b00: 65 64 20 74 6f 20 53 51 4c 69 74 65 2e 20 45 69  ed to SQLite. Ei
8b10: 74 68 65 72 20 61 20 73 79 6d 62 6f 6c 69 63 20  ther a symbolic 
8b20: 0a 2a 2a 20 22 53 51 4c 49 54 45 5f 4f 4b 22 20  .** "SQLITE_OK" 
8b30: 6f 72 20 6e 75 6d 65 72 69 63 20 22 30 22 20 76  or numeric "0" v
8b40: 61 6c 75 65 20 6d 61 79 20 62 65 20 72 65 74 75  alue may be retu
8b50: 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  rned..**.** The 
8b60: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20  contents of the 
8b70: 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 62 75  shared-memory bu
8b80: 66 66 65 72 20 61 73 73 6f 63 69 61 74 65 64 20  ffer associated 
8b90: 77 69 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c  with a given fil
8ba0: 65 0a 2a 2a 20 6d 61 79 20 62 65 20 72 65 61 64  e.** may be read
8bb0: 20 61 6e 64 20 73 65 74 20 75 73 69 6e 67 20 74   and set using t
8bc0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6d  he following com
8bd0: 6d 61 6e 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 56 46  mand:.**.**   VF
8be0: 53 4e 41 4d 45 20 73 68 6d 20 46 49 4c 45 4e 41  SNAME shm FILENA
8bf0: 4d 45 20 3f 4e 45 57 56 41 4c 55 45 3f 0a 2a 2a  ME ?NEWVALUE?.**
8c00: 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 78 53 68  .** When the xSh
8c10: 6d 4c 6f 63 6b 20 6d 65 74 68 6f 64 20 69 73 20  mLock method is 
8c20: 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74  invoked by SQLit
8c30: 65 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  e, the following
8c40: 20 73 63 72 69 70 74 20 69 73 0a 2a 2a 20 72 75   script is.** ru
8c50: 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50  n:.**.**   SCRIP
8c60: 54 20 78 53 68 6d 4c 6f 63 6b 20 20 20 20 46 49  T xShmLock    FI
8c70: 4c 45 4e 41 4d 45 20 49 44 20 4c 4f 43 4b 0a 2a  LENAME ID LOCK.*
8c80: 2a 0a 2a 2a 20 77 68 65 72 65 20 4c 4f 43 4b 20  *.** where LOCK 
8c90: 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 22  is of the form "
8ca0: 4f 46 46 53 45 54 20 4e 42 59 54 45 20 6c 6f 63  OFFSET NBYTE loc
8cb0: 6b 2f 75 6e 6c 6f 63 6b 20 73 68 61 72 65 64 2f  k/unlock shared/
8cc0: 65 78 63 6c 75 73 69 76 65 22 0a 2a 2f 0a 73 74  exclusive".*/.st
8cd0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 76 66 73  atic int testvfs
8ce0: 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e 74 44 61  _cmd(.  ClientDa
8cf0: 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f 49 6e 74  ta cd,.  Tcl_Int
8d00: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
8d10: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
8d20: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
8d30: 0a 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  .){.  static sql
8d40: 69 74 65 33 5f 76 66 73 20 74 76 66 73 5f 76 66  ite3_vfs tvfs_vf
8d50: 73 20 3d 20 7b 0a 20 20 20 20 32 2c 20 20 20 20  s = {.    2,    
8d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d70: 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73          /* iVers
8d80: 69 6f 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ion */.    0,   
8d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8da0: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 7a 4f 73           /* szOs
8db0: 46 69 6c 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20  File */.    0,  
8dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8dd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6d 78 50            /* mxP
8de0: 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 20 20 30  athname */.    0
8df0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8e10: 70 4e 65 78 74 20 2a 2f 0a 20 20 20 20 30 2c 20  pNext */.    0, 
8e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 7a 4e             /* zN
8e40: 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ame */.    0,   
8e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e60: 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 70 70           /* pApp
8e70: 44 61 74 61 20 2a 2f 0a 20 20 20 20 74 76 66 73  Data */.    tvfs
8e80: 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20  Open,           
8e90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70            /* xOp
8ea0: 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73 44 65  en */.    tvfsDe
8eb0: 6c 65 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  lete,           
8ec0: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65 6c 65          /* xDele
8ed0: 74 65 20 2a 2f 0a 20 20 20 20 74 76 66 73 41 63  te */.    tvfsAc
8ee0: 63 65 73 73 2c 20 20 20 20 20 20 20 20 20 20 20  cess,           
8ef0: 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63 63 65          /* xAcce
8f00: 73 73 20 2a 2f 0a 20 20 20 20 74 76 66 73 46 75  ss */.    tvfsFu
8f10: 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20 20 20  llPathname,     
8f20: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 75 6c 6c          /* xFull
8f30: 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 23 69 66 6e  Pathname */.#ifn
8f40: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
8f50: 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a 20  LOAD_EXTENSION. 
8f60: 20 20 20 74 76 66 73 44 6c 4f 70 65 6e 2c 20 20     tvfsDlOpen,  
8f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8f80: 20 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a 20   /* xDlOpen */. 
8f90: 20 20 20 74 76 66 73 44 6c 45 72 72 6f 72 2c 20     tvfsDlError, 
8fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8fb0: 20 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f 0a   /* xDlError */.
8fc0: 20 20 20 20 74 76 66 73 44 6c 53 79 6d 2c 20 20      tvfsDlSym,  
8fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8fe0: 20 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20    /* xDlSym */. 
8ff0: 20 20 20 74 76 66 73 44 6c 43 6c 6f 73 65 2c 20     tvfsDlClose, 
9000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9010: 20 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a   /* xDlClose */.
9020: 23 65 6c 73 65 0a 20 20 20 20 30 2c 20 20 20 20  #else.    0,    
9030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9040: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 4f 70          /* xDlOp
9050: 65 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  en */.    0,    
9060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9070: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 45 72          /* xDlEr
9080: 72 6f 72 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ror */.    0,   
9090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 53           /* xDlS
90b0: 79 6d 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  ym */.    0,    
90c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90d0: 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c          /* xDlCl
90e0: 6f 73 65 20 2a 2f 0a 23 65 6e 64 69 66 20 2f 2a  ose */.#endif /*
90f0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41   SQLITE_OMIT_LOA
9100: 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 20  D_EXTENSION */. 
9110: 20 20 20 74 76 66 73 52 61 6e 64 6f 6d 6e 65 73     tvfsRandomnes
9120: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
9130: 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e 65 73 73 20   /* xRandomness 
9140: 2a 2f 0a 20 20 20 20 74 76 66 73 53 6c 65 65 70  */.    tvfsSleep
9150: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9160: 20 20 20 20 20 2f 2a 20 78 53 6c 65 65 70 20 2a       /* xSleep *
9170: 2f 0a 20 20 20 20 74 76 66 73 43 75 72 72 65 6e  /.    tvfsCurren
9180: 74 54 69 6d 65 2c 20 20 20 20 20 20 20 20 20 20  tTime,          
9190: 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e 74 54      /* xCurrentT
91a0: 69 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ime */.    0,   
91b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 47 65 74           /* xGet
91d0: 4c 61 73 74 45 72 72 6f 72 20 2a 2f 0a 20 20 20  LastError */.   
91e0: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
91f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9200: 2a 20 78 43 75 72 72 65 6e 74 54 69 6d 65 49 6e  * xCurrentTimeIn
9210: 74 36 34 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 54  t64 */.  };..  T
9220: 65 73 74 76 66 73 20 2a 70 3b 20 20 20 20 20 20  estvfs *p;      
9230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9240: 2a 20 4e 65 77 20 6f 62 6a 65 63 74 20 2a 2f 0a  * New object */.
9250: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70    sqlite3_vfs *p
9260: 56 66 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  Vfs;            
9270: 20 20 2f 2a 20 4e 65 77 20 56 46 53 20 2a 2f 0a    /* New VFS */.
9280: 20 20 63 68 61 72 20 2a 7a 56 66 73 3b 0a 20 20    char *zVfs;.  
9290: 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20  int nByte;      
92a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
92b0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63  /* Bytes of spac
92c0: 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 74  e to allocate at
92d0: 20 70 20 2a 2f 0a 0a 20 20 69 6e 74 20 69 3b 0a   p */..  int i;.
92e0: 20 20 69 6e 74 20 69 73 4e 6f 73 68 6d 20 3d 20    int isNoshm = 
92f0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
9300: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 2d 6e 6f    /* True if -no
9310: 73 68 6d 20 69 73 20 70 61 73 73 65 64 20 2a 2f  shm is passed */
9320: 0a 20 20 69 6e 74 20 69 73 44 65 66 61 75 6c 74  .  int isDefault
9330: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
9340: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 2d 64     /* True if -d
9350: 65 66 61 75 6c 74 20 69 73 20 70 61 73 73 65 64  efault is passed
9360: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 4f 73 46 69   */.  int szOsFi
9370: 6c 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  le = 0;         
9380: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 70        /* Value p
9390: 61 73 73 65 64 20 74 6f 20 2d 73 7a 6f 73 66 69  assed to -szosfi
93a0: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 50 61  le */.  int mxPa
93b0: 74 68 6e 61 6d 65 20 3d 20 2d 31 3b 20 20 20 20  thname = -1;    
93c0: 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
93d0: 20 70 61 73 73 65 64 20 74 6f 20 2d 6d 78 70 61   passed to -mxpa
93e0: 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20  thname */.  int 
93f0: 69 56 65 72 73 69 6f 6e 20 3d 20 32 3b 20 20 20  iVersion = 2;   
9400: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
9410: 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f 20 2d  alue passed to -
9420: 69 76 65 72 73 69 6f 6e 20 2a 2f 0a 0a 20 20 69  iversion */..  i
9430: 66 28 20 6f 62 6a 63 3c 32 20 7c 7c 20 30 21 3d  f( objc<2 || 0!=
9440: 28 6f 62 6a 63 25 32 29 20 29 20 67 6f 74 6f 20  (objc%2) ) goto 
9450: 62 61 64 5f 61 72 67 73 3b 0a 20 20 66 6f 72 28  bad_args;.  for(
9460: 69 3d 32 3b 20 69 3c 6f 62 6a 63 3b 20 69 20 2b  i=2; i<objc; i +
9470: 3d 20 32 29 7b 0a 20 20 20 20 69 6e 74 20 6e 53  = 2){.    int nS
9480: 77 69 74 63 68 3b 0a 20 20 20 20 63 68 61 72 20  witch;.    char 
9490: 2a 7a 53 77 69 74 63 68 3b 0a 20 20 20 20 7a 53  *zSwitch;.    zS
94a0: 77 69 74 63 68 20 3d 20 54 63 6c 5f 47 65 74 53  witch = Tcl_GetS
94b0: 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a  tringFromObj(obj
94c0: 76 5b 69 5d 2c 20 26 6e 53 77 69 74 63 68 29 3b  v[i], &nSwitch);
94d0: 20 0a 0a 20 20 20 20 69 66 28 20 6e 53 77 69 74   ..    if( nSwit
94e0: 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63  ch>2 && 0==strnc
94f0: 6d 70 28 22 2d 6e 6f 73 68 6d 22 2c 20 7a 53 77  mp("-noshm", zSw
9500: 69 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29  itch, nSwitch) )
9510: 7b 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f  {.      if( Tcl_
9520: 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62  GetBooleanFromOb
9530: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69  j(interp, objv[i
9540: 2b 31 5d 2c 20 26 69 73 4e 6f 73 68 6d 29 20 29  +1], &isNoshm) )
9550: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
9560: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9570: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c    }.    }.    el
9580: 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32  se if( nSwitch>2
9590: 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22   && 0==strncmp("
95a0: 2d 64 65 66 61 75 6c 74 22 2c 20 7a 53 77 69 74  -default", zSwit
95b0: 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a  ch, nSwitch) ){.
95c0: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
95d0: 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28  tBooleanFromObj(
95e0: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31  interp, objv[i+1
95f0: 5d 2c 20 26 69 73 44 65 66 61 75 6c 74 29 20 29  ], &isDefault) )
9600: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
9610: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9620: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c    }.    }.    el
9630: 73 65 20 69 66 28 20 6e 53 77 69 74 63 68 3e 32  se if( nSwitch>2
9640: 20 26 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 22   && 0==strncmp("
9650: 2d 73 7a 6f 73 66 69 6c 65 22 2c 20 7a 53 77 69  -szosfile", zSwi
9660: 74 63 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b  tch, nSwitch) ){
9670: 0a 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47  .      if( Tcl_G
9680: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
9690: 65 72 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20  erp, objv[i+1], 
96a0: 26 73 7a 4f 73 46 69 6c 65 29 20 29 7b 0a 20 20  &szOsFile) ){.  
96b0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
96c0: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a  _ERROR;.      }.
96d0: 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69      }.    else i
96e0: 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20  f( nSwitch>2 && 
96f0: 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 6d 78 70  0==strncmp("-mxp
9700: 61 74 68 6e 61 6d 65 22 2c 20 7a 53 77 69 74 63  athname", zSwitc
9710: 68 2c 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20  h, nSwitch) ){. 
9720: 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74       if( Tcl_Get
9730: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  IntFromObj(inter
9740: 70 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 6d  p, objv[i+1], &m
9750: 78 50 61 74 68 6e 61 6d 65 29 20 29 7b 0a 20 20  xPathname) ){.  
9760: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
9770: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a  _ERROR;.      }.
9780: 20 20 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69      }.    else i
9790: 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20  f( nSwitch>2 && 
97a0: 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 69 76 65  0==strncmp("-ive
97b0: 72 73 69 6f 6e 22 2c 20 7a 53 77 69 74 63 68 2c  rsion", zSwitch,
97c0: 20 6e 53 77 69 74 63 68 29 20 29 7b 0a 20 20 20   nSwitch) ){.   
97d0: 20 20 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e     if( Tcl_GetIn
97e0: 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  tFromObj(interp,
97f0: 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 56 65   objv[i+1], &iVe
9800: 72 73 69 6f 6e 29 20 29 7b 0a 20 20 20 20 20 20  rsion) ){.      
9810: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
9820: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
9830: 7d 0a 20 20 20 20 65 6c 73 65 7b 0a 20 20 20 20  }.    else{.    
9840: 20 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73 3b    goto bad_args;
9850: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
9860: 28 20 73 7a 4f 73 46 69 6c 65 3c 73 69 7a 65 6f  ( szOsFile<sizeo
9870: 66 28 54 65 73 74 76 66 73 46 69 6c 65 29 20 29  f(TestvfsFile) )
9880: 7b 0a 20 20 20 20 73 7a 4f 73 46 69 6c 65 20 3d  {.    szOsFile =
9890: 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46   sizeof(TestvfsF
98a0: 69 6c 65 29 3b 0a 20 20 7d 0a 0a 20 20 7a 56 66  ile);.  }..  zVf
98b0: 73 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s = Tcl_GetStrin
98c0: 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 6e 42  g(objv[1]);.  nB
98d0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 54 65 73  yte = sizeof(Tes
98e0: 74 76 66 73 29 20 2b 20 73 74 72 6c 65 6e 28 7a  tvfs) + strlen(z
98f0: 56 66 73 29 2b 31 3b 0a 20 20 70 20 3d 20 28 54  Vfs)+1;.  p = (T
9900: 65 73 74 76 66 73 20 2a 29 63 6b 61 6c 6c 6f 63  estvfs *)ckalloc
9910: 28 6e 42 79 74 65 29 3b 0a 20 20 6d 65 6d 73 65  (nByte);.  memse
9920: 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  t(p, 0, nByte);.
9930: 20 20 70 2d 3e 69 44 65 76 63 68 61 72 20 3d 20    p->iDevchar = 
9940: 2d 31 3b 0a 20 20 70 2d 3e 69 53 65 63 74 6f 72  -1;.  p->iSector
9950: 73 69 7a 65 20 3d 20 2d 31 3b 0a 0a 20 20 2f 2a  size = -1;..  /*
9960: 20 43 72 65 61 74 65 20 74 68 65 20 6e 65 77 20   Create the new 
9970: 6f 62 6a 65 63 74 20 63 6f 6d 6d 61 6e 64 20 62  object command b
9980: 65 66 6f 72 65 20 71 75 65 72 79 69 6e 67 20 53  efore querying S
9990: 51 4c 69 74 65 20 66 6f 72 20 61 20 64 65 66 61  QLite for a defa
99a0: 75 6c 74 20 56 46 53 0a 20 20 2a 2a 20 74 6f 20  ult VFS.  ** to 
99b0: 75 73 65 20 66 6f 72 20 27 72 65 61 6c 27 20 49  use for 'real' I
99c0: 4f 20 6f 70 65 72 61 74 69 6f 6e 73 2e 20 54 68  O operations. Th
99d0: 69 73 20 69 73 20 62 65 63 61 75 73 65 20 63 72  is is because cr
99e0: 65 61 74 69 6e 67 20 74 68 65 20 6e 65 77 20 56  eating the new V
99f0: 46 53 0a 20 20 2a 2a 20 6d 61 79 20 64 65 6c 65  FS.  ** may dele
9a00: 74 65 20 61 6e 20 65 78 69 73 74 69 6e 67 20 5b  te an existing [
9a10: 74 65 73 74 76 66 73 5d 20 56 46 53 20 6f 66 20  testvfs] VFS of 
9a20: 74 68 65 20 73 61 6d 65 20 6e 61 6d 65 2e 20 49  the same name. I
9a30: 66 20 73 75 63 68 20 61 20 56 46 53 0a 20 20 2a  f such a VFS.  *
9a40: 2a 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 74  * is currently t
9a50: 68 65 20 64 65 66 61 75 6c 74 2c 20 74 68 65 20  he default, the 
9a60: 6e 65 77 20 5b 74 65 73 74 76 66 73 5d 20 6d 61  new [testvfs] ma
9a70: 79 20 65 6e 64 20 75 70 20 63 61 6c 6c 69 6e 67  y end up calling
9a80: 20 74 68 65 20 0a 20 20 2a 2a 20 6d 65 74 68 6f   the .  ** metho
9a90: 64 73 20 6f 66 20 61 20 64 65 6c 65 74 65 64 20  ds of a deleted 
9aa0: 6f 62 6a 65 63 74 2e 0a 20 20 2a 2f 0a 20 20 54  object..  */.  T
9ab0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
9ac0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 7a 56 66 73  and(interp, zVfs
9ad0: 2c 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f 63 6d  , testvfs_obj_cm
9ae0: 64 2c 20 70 2c 20 74 65 73 74 76 66 73 5f 6f 62  d, p, testvfs_ob
9af0: 6a 5f 64 65 6c 29 3b 0a 20 20 70 2d 3e 70 50 61  j_del);.  p->pPa
9b00: 72 65 6e 74 20 3d 20 73 71 6c 69 74 65 33 5f 76  rent = sqlite3_v
9b10: 66 73 5f 66 69 6e 64 28 30 29 3b 0a 20 20 70 2d  fs_find(0);.  p-
9b20: 3e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70  >interp = interp
9b30: 3b 0a 0a 20 20 70 2d 3e 7a 4e 61 6d 65 20 3d 20  ;..  p->zName = 
9b40: 28 63 68 61 72 20 2a 29 26 70 5b 31 5d 3b 0a 20  (char *)&p[1];. 
9b50: 20 6d 65 6d 63 70 79 28 70 2d 3e 7a 4e 61 6d 65   memcpy(p->zName
9b60: 2c 20 7a 56 66 73 2c 20 73 74 72 6c 65 6e 28 7a  , zVfs, strlen(z
9b70: 56 66 73 29 2b 31 29 3b 0a 0a 20 20 70 56 66 73  Vfs)+1);..  pVfs
9b80: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 66 73 20   = (sqlite3_vfs 
9b90: 2a 29 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  *)ckalloc(sizeof
9ba0: 28 73 71 6c 69 74 65 33 5f 76 66 73 29 29 3b 0a  (sqlite3_vfs));.
9bb0: 20 20 6d 65 6d 63 70 79 28 70 56 66 73 2c 20 26    memcpy(pVfs, &
9bc0: 74 76 66 73 5f 76 66 73 2c 20 73 69 7a 65 6f 66  tvfs_vfs, sizeof
9bd0: 28 73 71 6c 69 74 65 33 5f 76 66 73 29 29 3b 0a  (sqlite3_vfs));.
9be0: 20 20 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61    pVfs->pAppData
9bf0: 20 3d 20 28 76 6f 69 64 20 2a 29 70 3b 0a 20 20   = (void *)p;.  
9c00: 70 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 20 3d  pVfs->iVersion =
9c10: 20 69 56 65 72 73 69 6f 6e 3b 0a 20 20 70 56 66   iVersion;.  pVf
9c20: 73 2d 3e 7a 4e 61 6d 65 20 3d 20 70 2d 3e 7a 4e  s->zName = p->zN
9c30: 61 6d 65 3b 0a 20 20 70 56 66 73 2d 3e 6d 78 50  ame;.  pVfs->mxP
9c40: 61 74 68 6e 61 6d 65 20 3d 20 70 2d 3e 70 50 61  athname = p->pPa
9c50: 72 65 6e 74 2d 3e 6d 78 50 61 74 68 6e 61 6d 65  rent->mxPathname
9c60: 3b 0a 20 20 69 66 28 20 6d 78 50 61 74 68 6e 61  ;.  if( mxPathna
9c70: 6d 65 3e 3d 30 20 26 26 20 6d 78 50 61 74 68 6e  me>=0 && mxPathn
9c80: 61 6d 65 3c 70 56 66 73 2d 3e 6d 78 50 61 74 68  ame<pVfs->mxPath
9c90: 6e 61 6d 65 20 29 7b 0a 20 20 20 20 70 56 66 73  name ){.    pVfs
9ca0: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 3d 20 6d  ->mxPathname = m
9cb0: 78 50 61 74 68 6e 61 6d 65 3b 0a 20 20 7d 0a 20  xPathname;.  }. 
9cc0: 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20   pVfs->szOsFile 
9cd0: 3d 20 73 7a 4f 73 46 69 6c 65 3b 0a 20 20 70 2d  = szOsFile;.  p-
9ce0: 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20  >pVfs = pVfs;.  
9cf0: 70 2d 3e 69 73 4e 6f 73 68 6d 20 3d 20 69 73 4e  p->isNoshm = isN
9d00: 6f 73 68 6d 3b 0a 20 20 70 2d 3e 6d 61 73 6b 20  oshm;.  p->mask 
9d10: 3d 20 54 45 53 54 56 46 53 5f 41 4c 4c 5f 4d 41  = TESTVFS_ALL_MA
9d20: 53 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 76  SK;..  sqlite3_v
9d30: 66 73 5f 72 65 67 69 73 74 65 72 28 70 56 66 73  fs_register(pVfs
9d40: 2c 20 69 73 44 65 66 61 75 6c 74 29 3b 0a 0a 20  , isDefault);.. 
9d50: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
9d60: 0a 20 62 61 64 5f 61 72 67 73 3a 0a 20 20 54 63  . bad_args:.  Tc
9d70: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
9d80: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
9d90: 22 56 46 53 4e 41 4d 45 20 3f 2d 6e 6f 73 68 6d  "VFSNAME ?-noshm
9da0: 20 42 4f 4f 4c 3f 20 3f 2d 64 65 66 61 75 6c 74   BOOL? ?-default
9db0: 20 42 4f 4f 4c 3f 20 3f 2d 6d 78 70 61 74 68 6e   BOOL? ?-mxpathn
9dc0: 61 6d 65 20 49 4e 54 3f 20 3f 2d 73 7a 6f 73 66  ame INT? ?-szosf
9dd0: 69 6c 65 20 49 4e 54 3f 20 3f 2d 69 76 65 72 73  ile INT? ?-ivers
9de0: 69 6f 6e 20 49 4e 54 3f 22 29 3b 0a 20 20 72 65  ion INT?");.  re
9df0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
9e00: 7d 0a 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73  }..int Sqlitetes
9e10: 74 76 66 73 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  tvfs_Init(Tcl_In
9e20: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20  terp *interp){. 
9e30: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
9e40: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 74  mmand(interp, "t
9e50: 65 73 74 76 66 73 22 2c 20 74 65 73 74 76 66 73  estvfs", testvfs
9e60: 5f 63 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20 72  _cmd, 0, 0);.  r
9e70: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
9e80: 0a 23 65 6e 64 69 66 0a                          .#endif.