/ Hex Artifact Content
Login

Artifact 367e050ebedac89f741dbfdcade3d584a8061dc9:


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 54 65 73  execute */.  Tes
0b70: 74 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66  tvfsBuffer *pBuf
0b80: 66 65 72 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  fer;         /* 
0b90: 4c 69 73 74 20 6f 66 20 73 68 61 72 65 64 20 62  List of shared b
0ba0: 75 66 66 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20  uffers */.  int 
0bb0: 69 73 4e 6f 73 68 6d 3b 0a 0a 20 20 69 6e 74 20  isNoshm;..  int 
0bc0: 6d 61 73 6b 3b 20 20 20 20 20 20 20 20 20 20 20  mask;           
0bd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
0be0: 61 73 6b 20 63 6f 6e 74 72 6f 6c 6c 69 6e 67 20  ask controlling 
0bf0: 5b 73 63 72 69 70 74 5d 20 61 6e 64 20 5b 69 6f  [script] and [io
0c00: 65 72 72 5d 20 2a 2f 0a 0a 20 20 54 65 73 74 46  err] */..  TestF
0c10: 61 75 6c 74 49 6e 6a 65 63 74 20 69 6f 65 72 72  aultInject ioerr
0c20: 5f 65 72 72 3b 0a 20 20 54 65 73 74 46 61 75 6c  _err;.  TestFaul
0c30: 74 49 6e 6a 65 63 74 20 66 75 6c 6c 5f 65 72 72  tInject full_err
0c40: 3b 0a 20 20 54 65 73 74 46 61 75 6c 74 49 6e 6a  ;.  TestFaultInj
0c50: 65 63 74 20 63 61 6e 74 6f 70 65 6e 5f 65 72 72  ect cantopen_err
0c60: 3b 0a 0a 23 69 66 20 30 0a 20 20 69 6e 74 20 69  ;..#if 0.  int i
0c70: 49 6f 65 72 72 43 6e 74 3b 0a 20 20 69 6e 74 20  IoerrCnt;.  int 
0c80: 69 6f 65 72 72 3b 0a 20 20 69 6e 74 20 6e 49 6f  ioerr;.  int nIo
0c90: 65 72 72 46 61 69 6c 3b 0a 20 20 69 6e 74 20 69  errFail;.  int i
0ca0: 46 75 6c 6c 43 6e 74 3b 0a 20 20 69 6e 74 20 66  FullCnt;.  int f
0cb0: 75 6c 6c 65 72 72 3b 0a 20 20 69 6e 74 20 6e 46  ullerr;.  int nF
0cc0: 75 6c 6c 46 61 69 6c 3b 0a 23 65 6e 64 69 66 0a  ullFail;.#endif.
0cd0: 0a 20 20 69 6e 74 20 69 44 65 76 63 68 61 72 3b  .  int iDevchar;
0ce0: 0a 20 20 69 6e 74 20 69 53 65 63 74 6f 72 73 69  .  int iSectorsi
0cf0: 7a 65 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68  ze;.};../*.** Th
0d00: 65 20 54 65 73 74 76 66 73 2e 6d 61 73 6b 20 76  e Testvfs.mask v
0d10: 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 20 74  ariable is set t
0d20: 6f 20 61 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 20  o a combination 
0d30: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
0d40: 2e 0a 2a 2a 20 49 66 20 61 20 62 69 74 20 69 73  ..** If a bit is
0d50: 20 63 6c 65 61 72 20 69 6e 20 54 65 73 74 76 66   clear in Testvf
0d60: 73 2e 6d 61 73 6b 2c 20 74 68 65 6e 20 63 61 6c  s.mask, then cal
0d70: 6c 73 20 6d 61 64 65 20 62 79 20 53 51 4c 69 74  ls made by SQLit
0d80: 65 20 74 6f 20 74 68 65 20 0a 2a 2a 20 63 6f 72  e to the .** cor
0d90: 72 65 73 70 6f 6e 64 69 6e 67 20 56 46 53 20 6d  responding VFS m
0da0: 65 74 68 6f 64 20 69 73 20 69 67 6e 6f 72 65 64  ethod is ignored
0db0: 20 66 6f 72 20 70 75 72 70 6f 73 65 73 20 6f 66   for purposes of
0dc0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 2b 20 53 69 6d 75  :.**.**   + Simu
0dd0: 6c 61 74 69 6e 67 20 49 4f 20 65 72 72 6f 72 73  lating IO errors
0de0: 2c 20 61 6e 64 0a 2a 2a 20 20 20 2b 20 49 6e 76  , and.**   + Inv
0df0: 6f 6b 69 6e 67 20 74 68 65 20 54 63 6c 20 63 61  oking the Tcl ca
0e00: 6c 6c 62 61 63 6b 20 73 63 72 69 70 74 2e 0a 2a  llback script..*
0e10: 2f 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46  /.#define TESTVF
0e20: 53 5f 53 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 20  S_SHMOPEN_MASK  
0e30: 20 20 30 78 30 30 30 30 30 30 30 31 0a 23 64 65    0x00000001.#de
0e40: 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48 4d  fine TESTVFS_SHM
0e50: 4c 4f 43 4b 5f 4d 41 53 4b 20 20 20 20 30 78 30  LOCK_MASK    0x0
0e60: 30 30 30 30 30 31 30 0a 23 64 65 66 69 6e 65 20  0000010.#define 
0e70: 54 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d  TESTVFS_SHMMAP_M
0e80: 41 53 4b 20 20 20 20 20 30 78 30 30 30 30 30 30  ASK     0x000000
0e90: 32 30 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56  20.#define TESTV
0ea0: 46 53 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41  FS_SHMBARRIER_MA
0eb0: 53 4b 20 30 78 30 30 30 30 30 30 34 30 0a 23 64  SK 0x00000040.#d
0ec0: 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f 53 48  efine TESTVFS_SH
0ed0: 4d 43 4c 4f 53 45 5f 4d 41 53 4b 20 20 20 30 78  MCLOSE_MASK   0x
0ee0: 30 30 30 30 30 30 38 30 0a 0a 23 64 65 66 69 6e  00000080..#defin
0ef0: 65 20 54 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d  e TESTVFS_OPEN_M
0f00: 41 53 4b 20 20 20 20 20 20 20 30 78 30 30 30 30  ASK       0x0000
0f10: 30 31 30 30 0a 23 64 65 66 69 6e 65 20 54 45 53  0100.#define TES
0f20: 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b 20 20  TVFS_SYNC_MASK  
0f30: 20 20 20 20 20 30 78 30 30 30 30 30 32 30 30 0a       0x00000200.
0f40: 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53 5f  #define TESTVFS_
0f50: 44 45 4c 45 54 45 5f 4d 41 53 4b 20 20 20 20 20  DELETE_MASK     
0f60: 30 78 30 30 30 30 30 34 30 30 0a 23 64 65 66 69  0x00000400.#defi
0f70: 6e 65 20 54 45 53 54 56 46 53 5f 43 4c 4f 53 45  ne TESTVFS_CLOSE
0f80: 5f 4d 41 53 4b 20 20 20 20 20 20 30 78 30 30 30  _MASK      0x000
0f90: 30 30 38 30 30 0a 23 64 65 66 69 6e 65 20 54 45  00800.#define TE
0fa0: 53 54 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b  STVFS_WRITE_MASK
0fb0: 20 20 20 20 20 20 30 78 30 30 30 30 31 30 30 30        0x00001000
0fc0: 0a 23 64 65 66 69 6e 65 20 54 45 53 54 56 46 53  .#define TESTVFS
0fd0: 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53 4b 20 20  _TRUNCATE_MASK  
0fe0: 20 30 78 30 30 30 30 32 30 30 30 0a 23 64 65 66   0x00002000.#def
0ff0: 69 6e 65 20 54 45 53 54 56 46 53 5f 41 43 43 45  ine TESTVFS_ACCE
1000: 53 53 5f 4d 41 53 4b 20 20 20 20 20 30 78 30 30  SS_MASK     0x00
1010: 30 30 34 30 30 30 0a 23 64 65 66 69 6e 65 20 54  004000.#define T
1020: 45 53 54 56 46 53 5f 41 4c 4c 5f 4d 41 53 4b 20  ESTVFS_ALL_MASK 
1030: 20 20 20 20 20 20 20 30 78 30 30 30 30 37 46 46         0x00007FF
1040: 46 0a 0a 0a 23 64 65 66 69 6e 65 20 54 45 53 54  F...#define TEST
1050: 56 46 53 5f 4d 41 58 5f 50 41 47 45 53 20 31 30  VFS_MAX_PAGES 10
1060: 32 34 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 68 61 72  24../*.** A shar
1070: 65 64 2d 6d 65 6d 6f 72 79 20 62 75 66 66 65 72  ed-memory buffer
1080: 2e 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 6f  . There is one o
1090: 66 20 74 68 65 73 65 20 6f 62 6a 65 63 74 73 20  f these objects 
10a0: 66 6f 72 20 65 61 63 68 20 73 68 61 72 65 64 0a  for each shared.
10b0: 2a 2a 20 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e  ** memory region
10c0: 20 6f 70 65 6e 65 64 20 62 79 20 63 6c 69 65 6e   opened by clien
10d0: 74 73 2e 20 49 66 20 74 77 6f 20 63 6c 69 65 6e  ts. If two clien
10e0: 74 73 20 6f 70 65 6e 20 74 68 65 20 73 61 6d 65  ts open the same
10f0: 20 66 69 6c 65 2c 0a 2a 2a 20 74 68 65 72 65 20   file,.** there 
1100: 61 72 65 20 74 77 6f 20 54 65 73 74 76 66 73 46  are two TestvfsF
1110: 69 6c 65 20 73 74 72 75 63 74 75 72 65 73 20 62  ile structures b
1120: 75 74 20 6f 6e 6c 79 20 6f 6e 65 20 54 65 73 74  ut only one Test
1130: 76 66 73 42 75 66 66 65 72 20 73 74 72 75 63 74  vfsBuffer struct
1140: 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 54  ure..*/.struct T
1150: 65 73 74 76 66 73 42 75 66 66 65 72 20 7b 0a 20  estvfsBuffer {. 
1160: 20 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20 20   char *zFile;   
1170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1180: 20 2f 2a 20 41 73 73 6f 63 69 61 74 65 64 20 66   /* Associated f
1190: 69 6c 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e  ile name */.  in
11a0: 74 20 70 67 73 7a 3b 20 20 20 20 20 20 20 20 20  t pgsz;         
11b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11c0: 20 50 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20   Page size */.  
11d0: 75 38 20 2a 61 50 61 67 65 5b 54 45 53 54 56 46  u8 *aPage[TESTVF
11e0: 53 5f 4d 41 58 5f 50 41 47 45 53 5d 3b 20 20 20  S_MAX_PAGES];   
11f0: 2f 2a 20 41 72 72 61 79 20 6f 66 20 63 6b 61 6c  /* Array of ckal
1200: 6c 6f 63 27 64 20 70 61 67 65 73 20 2a 2f 0a 20  loc'd pages */. 
1210: 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 69 6c   TestvfsFd *pFil
1220: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1230: 20 2f 2a 20 4c 69 73 74 20 6f 66 20 6f 70 65 6e   /* List of open
1240: 20 68 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 54 65   handles */.  Te
1250: 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 4e 65  stvfsBuffer *pNe
1260: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  xt;           /*
1270: 20 4e 65 78 74 20 69 6e 20 6c 69 6e 6b 65 64 20   Next in linked 
1280: 6c 69 73 74 20 6f 66 20 61 6c 6c 20 62 75 66 66  list of all buff
1290: 65 72 73 20 2a 2f 0a 7d 3b 0a 0a 0a 23 64 65 66  ers */.};...#def
12a0: 69 6e 65 20 50 41 52 45 4e 54 56 46 53 28 78 29  ine PARENTVFS(x)
12b0: 20 28 28 28 54 65 73 74 76 66 73 20 2a 29 28 28   (((Testvfs *)((
12c0: 78 29 2d 3e 70 41 70 70 44 61 74 61 29 29 2d 3e  x)->pAppData))->
12d0: 70 50 61 72 65 6e 74 29 0a 0a 23 64 65 66 69 6e  pParent)..#defin
12e0: 65 20 54 45 53 54 56 46 53 5f 4d 41 58 5f 41 52  e TESTVFS_MAX_AR
12f0: 47 53 20 31 32 0a 0a 0a 2f 2a 0a 2a 2a 20 4d 65  GS 12.../*.** Me
1300: 74 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e  thod declaration
1310: 73 20 66 6f 72 20 54 65 73 74 76 66 73 46 69 6c  s for TestvfsFil
1320: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
1330: 20 74 76 66 73 43 6c 6f 73 65 28 73 71 6c 69 74   tvfsClose(sqlit
1340: 65 33 5f 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69  e3_file*);.stati
1350: 63 20 69 6e 74 20 74 76 66 73 52 65 61 64 28 73  c int tvfsRead(s
1360: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 76 6f  qlite3_file*, vo
1370: 69 64 2a 2c 20 69 6e 74 20 69 41 6d 74 2c 20 73  id*, int iAmt, s
1380: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
1390: 73 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  st);.static int 
13a0: 74 76 66 73 57 72 69 74 65 28 73 71 6c 69 74 65  tvfsWrite(sqlite
13b0: 33 5f 66 69 6c 65 2a 2c 63 6f 6e 73 74 20 76 6f  3_file*,const vo
13c0: 69 64 2a 2c 69 6e 74 20 69 41 6d 74 2c 20 73 71  id*,int iAmt, sq
13d0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
13e0: 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74  t);.static int t
13f0: 76 66 73 54 72 75 6e 63 61 74 65 28 73 71 6c 69  vfsTruncate(sqli
1400: 74 65 33 5f 66 69 6c 65 2a 2c 20 73 71 6c 69 74  te3_file*, sqlit
1410: 65 33 5f 69 6e 74 36 34 20 73 69 7a 65 29 3b 0a  e3_int64 size);.
1420: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
1430: 79 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ync(sqlite3_file
1440: 2a 2c 20 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73  *, int flags);.s
1450: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 69  tatic int tvfsFi
1460: 6c 65 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66  leSize(sqlite3_f
1470: 69 6c 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e  ile*, sqlite3_in
1480: 74 36 34 20 2a 70 53 69 7a 65 29 3b 0a 73 74 61  t64 *pSize);.sta
1490: 74 69 63 20 69 6e 74 20 74 76 66 73 4c 6f 63 6b  tic int tvfsLock
14a0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
14b0: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
14c0: 20 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c 69   tvfsUnlock(sqli
14d0: 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b  te3_file*, int);
14e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
14f0: 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63  CheckReservedLoc
1500: 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c  k(sqlite3_file*,
1510: 20 69 6e 74 20 2a 29 3b 0a 73 74 61 74 69 63 20   int *);.static 
1520: 69 6e 74 20 74 76 66 73 46 69 6c 65 43 6f 6e 74  int tvfsFileCont
1530: 72 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  rol(sqlite3_file
1540: 2a 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20  *, int op, void 
1550: 2a 70 41 72 67 29 3b 0a 73 74 61 74 69 63 20 69  *pArg);.static i
1560: 6e 74 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a  nt tvfsSectorSiz
1570: 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29  e(sqlite3_file*)
1580: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66  ;.static int tvf
1590: 73 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72  sDeviceCharacter
15a0: 69 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66  istics(sqlite3_f
15b0: 69 6c 65 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65  ile*);../*.** Me
15c0: 74 68 6f 64 20 64 65 63 6c 61 72 61 74 69 6f 6e  thod declaration
15d0: 73 20 66 6f 72 20 74 76 66 73 5f 76 66 73 2e 0a  s for tvfs_vfs..
15e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
15f0: 66 73 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76  fsOpen(sqlite3_v
1600: 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  fs*, const char 
1610: 2a 2c 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  *, sqlite3_file*
1620: 2c 20 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a  , int , int *);.
1630: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 44  static int tvfsD
1640: 65 6c 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66  elete(sqlite3_vf
1650: 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  s*, const char *
1660: 7a 4e 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44  zName, int syncD
1670: 69 72 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  ir);.static int 
1680: 74 76 66 73 41 63 63 65 73 73 28 73 71 6c 69 74  tvfsAccess(sqlit
1690: 65 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63  e3_vfs*, const c
16a0: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20  har *zName, int 
16b0: 66 6c 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73  flags, int *);.s
16c0: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 75  tatic int tvfsFu
16d0: 6c 6c 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74  llPathname(sqlit
16e0: 65 33 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63  e3_vfs*, const c
16f0: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c  har *zName, int,
1700: 20 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 23 69   char *zOut);.#i
1710: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
1720: 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e  T_LOAD_EXTENSION
1730: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 74 76  .static void *tv
1740: 66 73 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33  fsDlOpen(sqlite3
1750: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
1760: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 73  r *zFilename);.s
1770: 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 44  tatic void tvfsD
1780: 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76  lError(sqlite3_v
1790: 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20  fs*, int nByte, 
17a0: 63 68 61 72 20 2a 7a 45 72 72 4d 73 67 29 3b 0a  char *zErrMsg);.
17b0: 73 74 61 74 69 63 20 76 6f 69 64 20 28 2a 74 76  static void (*tv
17c0: 66 73 44 6c 53 79 6d 28 73 71 6c 69 74 65 33 5f  fsDlSym(sqlite3_
17d0: 76 66 73 2a 2c 76 6f 69 64 2a 2c 20 63 6f 6e 73  vfs*,void*, cons
17e0: 74 20 63 68 61 72 20 2a 7a 53 79 6d 62 6f 6c 29  t char *zSymbol)
17f0: 29 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20  )(void);.static 
1800: 76 6f 69 64 20 74 76 66 73 44 6c 43 6c 6f 73 65  void tvfsDlClose
1810: 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76  (sqlite3_vfs*, v
1820: 6f 69 64 2a 29 3b 0a 23 65 6e 64 69 66 20 2f 2a  oid*);.#endif /*
1830: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c 4f 41   SQLITE_OMIT_LOA
1840: 44 5f 45 58 54 45 4e 53 49 4f 4e 20 2a 2f 0a 73  D_EXTENSION */.s
1850: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 52 61  tatic int tvfsRa
1860: 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33  ndomness(sqlite3
1870: 5f 76 66 73 2a 2c 20 69 6e 74 20 6e 42 79 74 65  _vfs*, int nByte
1880: 2c 20 63 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73  , char *zOut);.s
1890: 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 6c  tatic int tvfsSl
18a0: 65 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  eep(sqlite3_vfs*
18b0: 2c 20 69 6e 74 20 6d 69 63 72 6f 73 65 63 6f 6e  , int microsecon
18c0: 64 73 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  ds);.static int 
18d0: 74 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28  tvfsCurrentTime(
18e0: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 64 6f  sqlite3_vfs*, do
18f0: 75 62 6c 65 2a 29 3b 0a 0a 73 74 61 74 69 63 20  uble*);..static 
1900: 69 6e 74 20 74 76 66 73 53 68 6d 4f 70 65 6e 28  int tvfsShmOpen(
1910: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29 3b 0a  sqlite3_file*);.
1920: 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73 53  static int tvfsS
1930: 68 6d 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  hmLock(sqlite3_f
1940: 69 6c 65 2a 2c 20 69 6e 74 20 2c 20 69 6e 74 2c  ile*, int , int,
1950: 20 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e   int);.static in
1960: 74 20 74 76 66 73 53 68 6d 4d 61 70 28 73 71 6c  t tvfsShmMap(sql
1970: 69 74 65 33 5f 66 69 6c 65 2a 2c 69 6e 74 2c 69  ite3_file*,int,i
1980: 6e 74 2c 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c  nt,int, void vol
1990: 61 74 69 6c 65 20 2a 2a 29 3b 0a 73 74 61 74 69  atile **);.stati
19a0: 63 20 76 6f 69 64 20 74 76 66 73 53 68 6d 42 61  c void tvfsShmBa
19b0: 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69  rrier(sqlite3_fi
19c0: 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  le*);.static int
19d0: 20 74 76 66 73 53 68 6d 55 6e 6d 61 70 28 73 71   tvfsShmUnmap(sq
19e0: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74  lite3_file*, int
19f0: 29 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74  );..static sqlit
1a00: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 74 76  e3_io_methods tv
1a10: 66 73 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 3d 20  fs_io_methods = 
1a20: 7b 0a 20 20 32 2c 20 20 20 20 20 20 20 20 20 20  {.  2,          
1a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a40: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
1a50: 2a 2f 0a 20 20 74 76 66 73 43 6c 6f 73 65 2c 20  */.  tvfsClose, 
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2a       /* xClose *
1a80: 2f 0a 20 20 74 76 66 73 52 65 61 64 2c 20 20 20  /.  tvfsRead,   
1a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1aa0: 20 20 20 20 2f 2a 20 78 52 65 61 64 20 2a 2f 0a      /* xRead */.
1ab0: 20 20 74 76 66 73 57 72 69 74 65 2c 20 20 20 20    tvfsWrite,    
1ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ad0: 20 20 2f 2a 20 78 57 72 69 74 65 20 2a 2f 0a 20    /* xWrite */. 
1ae0: 20 74 76 66 73 54 72 75 6e 63 61 74 65 2c 20 20   tvfsTruncate,  
1af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b00: 20 2f 2a 20 78 54 72 75 6e 63 61 74 65 20 2a 2f   /* xTruncate */
1b10: 0a 20 20 74 76 66 73 53 79 6e 63 2c 20 20 20 20  .  tvfsSync,    
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b30: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20     /* xSync */. 
1b40: 20 74 76 66 73 46 69 6c 65 53 69 7a 65 2c 20 20   tvfsFileSize,  
1b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b60: 20 2f 2a 20 78 46 69 6c 65 53 69 7a 65 20 2a 2f   /* xFileSize */
1b70: 0a 20 20 74 76 66 73 4c 6f 63 6b 2c 20 20 20 20  .  tvfsLock,    
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b90: 20 20 20 2f 2a 20 78 4c 6f 63 6b 20 2a 2f 0a 20     /* xLock */. 
1ba0: 20 74 76 66 73 55 6e 6c 6f 63 6b 2c 20 20 20 20   tvfsUnlock,    
1bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bc0: 20 2f 2a 20 78 55 6e 6c 6f 63 6b 20 2a 2f 0a 20   /* xUnlock */. 
1bd0: 20 74 76 66 73 43 68 65 63 6b 52 65 73 65 72 76   tvfsCheckReserv
1be0: 65 64 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20  edLock,         
1bf0: 20 2f 2a 20 78 43 68 65 63 6b 52 65 73 65 72 76   /* xCheckReserv
1c00: 65 64 4c 6f 63 6b 20 2a 2f 0a 20 20 74 76 66 73  edLock */.  tvfs
1c10: 46 69 6c 65 43 6f 6e 74 72 6f 6c 2c 20 20 20 20  FileControl,    
1c20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1c30: 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 2a 2f 0a 20  FileControl */. 
1c40: 20 74 76 66 73 53 65 63 74 6f 72 53 69 7a 65 2c   tvfsSectorSize,
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c60: 20 2f 2a 20 78 53 65 63 74 6f 72 53 69 7a 65 20   /* xSectorSize 
1c70: 2a 2f 0a 20 20 74 76 66 73 44 65 76 69 63 65 43  */.  tvfsDeviceC
1c80: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 2c 20  haracteristics, 
1c90: 20 20 20 20 20 2f 2a 20 78 44 65 76 69 63 65 43       /* xDeviceC
1ca0: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 20 2a  haracteristics *
1cb0: 2f 0a 20 20 74 76 66 73 53 68 6d 4d 61 70 2c 20  /.  tvfsShmMap, 
1cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cd0: 20 20 20 20 2f 2a 20 78 53 68 6d 4d 61 70 20 2a      /* xShmMap *
1ce0: 2f 0a 20 20 74 76 66 73 53 68 6d 4c 6f 63 6b 2c  /.  tvfsShmLock,
1cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d00: 20 20 20 20 2f 2a 20 78 53 68 6d 4c 6f 63 6b 20      /* xShmLock 
1d10: 2a 2f 0a 20 20 74 76 66 73 53 68 6d 42 61 72 72  */.  tvfsShmBarr
1d20: 69 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  ier,            
1d30: 20 20 20 20 20 2f 2a 20 78 53 68 6d 42 61 72 72       /* xShmBarr
1d40: 69 65 72 20 2a 2f 0a 20 20 74 76 66 73 53 68 6d  ier */.  tvfsShm
1d50: 55 6e 6d 61 70 20 20 20 20 20 20 20 20 20 20 20  Unmap           
1d60: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 6d           /* xShm
1d70: 55 6e 6d 61 70 20 2a 2f 0a 7d 3b 0a 0a 73 74 61  Unmap */.};..sta
1d80: 74 69 63 20 69 6e 74 20 74 76 66 73 52 65 73 75  tic int tvfsResu
1d90: 6c 74 43 6f 64 65 28 54 65 73 74 76 66 73 20 2a  ltCode(Testvfs *
1da0: 70 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20  p, int *pRc){.  
1db0: 73 74 72 75 63 74 20 65 72 72 63 6f 64 65 20 7b  struct errcode {
1dc0: 0a 20 20 20 20 69 6e 74 20 65 43 6f 64 65 3b 0a  .    int eCode;.
1dd0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
1de0: 7a 43 6f 64 65 3b 0a 20 20 7d 20 61 43 6f 64 65  zCode;.  } aCode
1df0: 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 53 51 4c  [] = {.    { SQL
1e00: 49 54 45 5f 4f 4b 2c 20 20 20 20 20 22 53 51 4c  ITE_OK,     "SQL
1e10: 49 54 45 5f 4f 4b 22 20 20 20 20 20 7d 2c 0a 20  ITE_OK"     },. 
1e20: 20 20 20 7b 20 53 51 4c 49 54 45 5f 45 52 52 4f     { SQLITE_ERRO
1e30: 52 2c 20 20 22 53 51 4c 49 54 45 5f 45 52 52 4f  R,  "SQLITE_ERRO
1e40: 52 22 20 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c  R"  },.    { SQL
1e50: 49 54 45 5f 49 4f 45 52 52 2c 20 20 22 53 51 4c  ITE_IOERR,  "SQL
1e60: 49 54 45 5f 49 4f 45 52 52 22 20 20 7d 2c 0a 20  ITE_IOERR"  },. 
1e70: 20 20 20 7b 20 53 51 4c 49 54 45 5f 4c 4f 43 4b     { SQLITE_LOCK
1e80: 45 44 2c 20 22 53 51 4c 49 54 45 5f 4c 4f 43 4b  ED, "SQLITE_LOCK
1e90: 45 44 22 20 7d 2c 0a 20 20 20 20 7b 20 53 51 4c  ED" },.    { SQL
1ea0: 49 54 45 5f 42 55 53 59 2c 20 20 20 22 53 51 4c  ITE_BUSY,   "SQL
1eb0: 49 54 45 5f 42 55 53 59 22 20 20 20 7d 2c 0a 20  ITE_BUSY"   },. 
1ec0: 20 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 63 68 61   };..  const cha
1ed0: 72 20 2a 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a  r *z;.  int i;..
1ee0: 20 20 7a 20 3d 20 54 63 6c 5f 47 65 74 53 74 72    z = Tcl_GetStr
1ef0: 69 6e 67 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  ingResult(p->int
1f00: 65 72 70 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  erp);.  for(i=0;
1f10: 20 69 3c 41 72 72 61 79 53 69 7a 65 28 61 43 6f   i<ArraySize(aCo
1f20: 64 65 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  de); i++){.    i
1f30: 66 28 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20  f( 0==strcmp(z, 
1f40: 61 43 6f 64 65 5b 69 5d 2e 7a 43 6f 64 65 29 20  aCode[i].zCode) 
1f50: 29 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20  ){.      *pRc = 
1f60: 61 43 6f 64 65 5b 69 5d 2e 65 43 6f 64 65 3b 0a  aCode[i].eCode;.
1f70: 20 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a        return 1;.
1f80: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
1f90: 75 72 6e 20 30 3b 0a 7d 0a 0a 73 74 61 74 69 63  urn 0;.}..static
1fa0: 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46   int tvfsInjectF
1fb0: 61 75 6c 74 28 54 65 73 74 46 61 75 6c 74 49 6e  ault(TestFaultIn
1fc0: 6a 65 63 74 20 2a 70 29 7b 0a 20 20 69 6e 74 20  ject *p){.  int 
1fd0: 72 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 70  ret = 0;.  if( p
1fe0: 2d 3e 65 46 61 75 6c 74 20 29 7b 0a 20 20 20 20  ->eFault ){.    
1ff0: 70 2d 3e 69 43 6e 74 2d 2d 3b 0a 20 20 20 20 69  p->iCnt--;.    i
2000: 66 28 20 70 2d 3e 69 43 6e 74 3d 3d 30 20 7c 7c  f( p->iCnt==0 ||
2010: 20 28 70 2d 3e 69 43 6e 74 3c 30 20 26 26 20 70   (p->iCnt<0 && p
2020: 2d 3e 65 46 61 75 6c 74 3d 3d 46 41 55 4c 54 5f  ->eFault==FAULT_
2030: 49 4e 4a 45 43 54 5f 50 45 52 53 49 53 54 45 4e  INJECT_PERSISTEN
2040: 54 20 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74  T ) ){.      ret
2050: 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d 3e 6e   = 1;.      p->n
2060: 46 61 69 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20  Fail++;.    }.  
2070: 7d 0a 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a  }.  return ret;.
2080: 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  }...static int t
2090: 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28 54  vfsInjectIoerr(T
20a0: 65 73 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65  estvfs *p){.  re
20b0: 74 75 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46  turn tvfsInjectF
20c0: 61 75 6c 74 28 26 70 2d 3e 69 6f 65 72 72 5f 65  ault(&p->ioerr_e
20d0: 72 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  rr);.}..static i
20e0: 6e 74 20 74 76 66 73 49 6e 6a 65 63 74 46 75 6c  nt tvfsInjectFul
20f0: 6c 65 72 72 28 54 65 73 74 76 66 73 20 2a 70 29  lerr(Testvfs *p)
2100: 7b 0a 20 20 72 65 74 75 72 6e 20 74 76 66 73 49  {.  return tvfsI
2110: 6e 6a 65 63 74 46 61 75 6c 74 28 26 70 2d 3e 66  njectFault(&p->f
2120: 75 6c 6c 5f 65 72 72 29 3b 0a 7d 0a 73 74 61 74  ull_err);.}.stat
2130: 69 63 20 69 6e 74 20 74 76 66 73 49 6e 6a 65 63  ic int tvfsInjec
2140: 74 43 61 6e 74 6f 70 65 6e 65 72 72 28 54 65 73  tCantopenerr(Tes
2150: 74 76 66 73 20 2a 70 29 7b 0a 20 20 72 65 74 75  tvfs *p){.  retu
2160: 72 6e 20 74 76 66 73 49 6e 6a 65 63 74 46 61 75  rn tvfsInjectFau
2170: 6c 74 28 26 70 2d 3e 63 61 6e 74 6f 70 65 6e 5f  lt(&p->cantopen_
2180: 65 72 72 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63  err);.}...static
2190: 20 76 6f 69 64 20 74 76 66 73 45 78 65 63 54 63   void tvfsExecTc
21a0: 6c 28 0a 20 20 54 65 73 74 76 66 73 20 2a 70 2c  l(.  Testvfs *p,
21b0: 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a   .  const char *
21c0: 7a 4d 65 74 68 6f 64 2c 0a 20 20 54 63 6c 5f 4f  zMethod,.  Tcl_O
21d0: 62 6a 20 2a 61 72 67 31 2c 0a 20 20 54 63 6c 5f  bj *arg1,.  Tcl_
21e0: 4f 62 6a 20 2a 61 72 67 32 2c 0a 20 20 54 63 6c  Obj *arg2,.  Tcl
21f0: 5f 4f 62 6a 20 2a 61 72 67 33 0a 29 7b 0a 20 20  _Obj *arg3.){.  
2200: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
2210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2220: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66  /* Return code f
2230: 72 6f 6d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 28  rom Tcl_EvalObj(
2240: 29 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  ) */.  Tcl_Obj *
2250: 70 45 76 61 6c 3b 0a 20 20 61 73 73 65 72 74 28  pEval;.  assert(
2260: 20 70 2d 3e 70 53 63 72 69 70 74 20 29 3b 0a 0a   p->pScript );..
2270: 20 20 61 73 73 65 72 74 28 20 7a 4d 65 74 68 6f    assert( zMetho
2280: 64 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  d );.  assert( p
2290: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 72   );.  assert( ar
22a0: 67 32 3d 3d 30 20 7c 7c 20 61 72 67 31 21 3d 30  g2==0 || arg1!=0
22b0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 72   );.  assert( ar
22c0: 67 33 3d 3d 30 20 7c 7c 20 61 72 67 32 21 3d 30  g3==0 || arg2!=0
22d0: 20 29 3b 0a 0a 20 20 70 45 76 61 6c 20 3d 20 54   );..  pEval = T
22e0: 63 6c 5f 44 75 70 6c 69 63 61 74 65 4f 62 6a 28  cl_DuplicateObj(
22f0: 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 54  p->pScript);.  T
2300: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
2310: 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 54  p->pScript);.  T
2320: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
2330: 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72  Element(p->inter
2340: 70 2c 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65  p, pEval, Tcl_Ne
2350: 77 53 74 72 69 6e 67 4f 62 6a 28 7a 4d 65 74 68  wStringObj(zMeth
2360: 6f 64 2c 20 2d 31 29 29 3b 0a 20 20 69 66 28 20  od, -1));.  if( 
2370: 61 72 67 31 20 29 20 54 63 6c 5f 4c 69 73 74 4f  arg1 ) Tcl_ListO
2380: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
2390: 70 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c  p->interp, pEval
23a0: 2c 20 61 72 67 31 29 3b 0a 20 20 69 66 28 20 61  , arg1);.  if( a
23b0: 72 67 32 20 29 20 54 63 6c 5f 4c 69 73 74 4f 62  rg2 ) Tcl_ListOb
23c0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70  jAppendElement(p
23d0: 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  ->interp, pEval,
23e0: 20 61 72 67 32 29 3b 0a 20 20 69 66 28 20 61 72   arg2);.  if( ar
23f0: 67 33 20 29 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  g3 ) Tcl_ListObj
2400: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d  AppendElement(p-
2410: 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20  >interp, pEval, 
2420: 61 72 67 33 29 3b 0a 0a 20 20 72 63 20 3d 20 54  arg3);..  rc = T
2430: 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 70 2d 3e  cl_EvalObjEx(p->
2440: 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 54  interp, pEval, T
2450: 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 3b  CL_EVAL_GLOBAL);
2460: 0a 20 20 69 66 28 20 72 63 21 3d 54 43 4c 5f 4f  .  if( rc!=TCL_O
2470: 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 42 61 63  K ){.    Tcl_Bac
2480: 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70 2d 3e  kgroundError(p->
2490: 69 6e 74 65 72 70 29 3b 0a 20 20 20 20 54 63 6c  interp);.    Tcl
24a0: 5f 52 65 73 65 74 52 65 73 75 6c 74 28 70 2d 3e  _ResetResult(p->
24b0: 69 6e 74 65 72 70 29 3b 0a 20 20 7d 0a 7d 0a 0a  interp);.  }.}..
24c0: 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20  ./*.** Close an 
24d0: 74 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74  tvfs-file..*/.st
24e0: 61 74 69 63 20 69 6e 74 20 74 76 66 73 43 6c 6f  atic int tvfsClo
24f0: 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  se(sqlite3_file 
2500: 2a 70 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 72  *pFile){.  int r
2510: 63 3b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65  c;.  TestvfsFile
2520: 20 2a 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54   *pTestfile = (T
2530: 65 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69  estvfsFile *)pFi
2540: 6c 65 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20  le;.  TestvfsFd 
2550: 2a 70 46 64 20 3d 20 70 54 65 73 74 66 69 6c 65  *pFd = pTestfile
2560: 2d 3e 70 46 64 3b 0a 20 20 54 65 73 74 76 66 73  ->pFd;.  Testvfs
2570: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
2580: 29 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70  )pFd->pVfs->pApp
2590: 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  Data;..  if( p->
25a0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
25b0: 73 6b 26 54 45 53 54 56 46 53 5f 43 4c 4f 53 45  sk&TESTVFS_CLOSE
25c0: 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66  _MASK ){.    tvf
25d0: 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 43 6c  sExecTcl(p, "xCl
25e0: 6f 73 65 22 2c 20 0a 20 20 20 20 20 20 20 20 54  ose", .        T
25f0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2600: 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  pFd->zFilename, 
2610: 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64  -1), pFd->pShmId
2620: 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a  , 0.    );.  }..
2630: 20 20 69 66 28 20 70 46 64 2d 3e 70 53 68 6d 49    if( pFd->pShmI
2640: 64 20 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63  d ){.    Tcl_Dec
2650: 72 52 65 66 43 6f 75 6e 74 28 70 46 64 2d 3e 70  rRefCount(pFd->p
2660: 53 68 6d 49 64 29 3b 0a 20 20 20 20 70 46 64 2d  ShmId);.    pFd-
2670: 3e 70 53 68 6d 49 64 20 3d 20 30 3b 0a 20 20 7d  >pShmId = 0;.  }
2680: 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4d  .  if( pFile->pM
2690: 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20 63 6b  ethods ){.    ck
26a0: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 46 69  free((char *)pFi
26b0: 6c 65 2d 3e 70 4d 65 74 68 6f 64 73 29 3b 0a 20  le->pMethods);. 
26c0: 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65   }.  rc = sqlite
26d0: 33 4f 73 43 6c 6f 73 65 28 70 46 64 2d 3e 70 52  3OsClose(pFd->pR
26e0: 65 61 6c 29 3b 0a 20 20 63 6b 66 72 65 65 28 28  eal);.  ckfree((
26f0: 63 68 61 72 20 2a 29 70 46 64 29 3b 0a 20 20 70  char *)pFd);.  p
2700: 54 65 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20  Testfile->pFd = 
2710: 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
2720: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 64 61  }../*.** Read da
2730: 74 61 20 66 72 6f 6d 20 61 6e 20 74 76 66 73 2d  ta from an tvfs-
2740: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
2750: 69 6e 74 20 74 76 66 73 52 65 61 64 28 0a 20 20  int tvfsRead(.  
2760: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46  sqlite3_file *pF
2770: 69 6c 65 2c 20 0a 20 20 76 6f 69 64 20 2a 7a 42  ile, .  void *zB
2780: 75 66 2c 20 0a 20 20 69 6e 74 20 69 41 6d 74 2c  uf, .  int iAmt,
2790: 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36 34   .  sqlite_int64
27a0: 20 69 4f 66 73 74 0a 29 7b 0a 20 20 54 65 73 74   iOfst.){.  Test
27b0: 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47  vfsFd *p = tvfsG
27c0: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72  etFd(pFile);.  r
27d0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52  eturn sqlite3OsR
27e0: 65 61 64 28 70 2d 3e 70 52 65 61 6c 2c 20 7a 42  ead(p->pReal, zB
27f0: 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29  uf, iAmt, iOfst)
2800: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  ;.}../*.** Write
2810: 20 64 61 74 61 20 74 6f 20 61 6e 20 74 76 66 73   data to an tvfs
2820: 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  -file..*/.static
2830: 20 69 6e 74 20 74 76 66 73 57 72 69 74 65 28 0a   int tvfsWrite(.
2840: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
2850: 70 46 69 6c 65 2c 20 0a 20 20 63 6f 6e 73 74 20  pFile, .  const 
2860: 76 6f 69 64 20 2a 7a 42 75 66 2c 20 0a 20 20 69  void *zBuf, .  i
2870: 6e 74 20 69 41 6d 74 2c 20 0a 20 20 73 71 6c 69  nt iAmt, .  sqli
2880: 74 65 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29  te_int64 iOfst.)
2890: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
28a0: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
28b0: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
28c0: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
28d0: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
28e0: 74 76 66 73 20 2a 29 70 46 64 2d 3e 70 56 66 73  tvfs *)pFd->pVfs
28f0: 2d 3e 70 41 70 70 44 61 74 61 3b 0a 0a 20 20 69  ->pAppData;..  i
2900: 66 28 20 70 2d 3e 70 53 63 72 69 70 74 20 26 26  f( p->pScript &&
2910: 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46 53   p->mask&TESTVFS
2920: 5f 57 52 49 54 45 5f 4d 41 53 4b 20 29 7b 0a 20  _WRITE_MASK ){. 
2930: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
2940: 2c 20 22 78 57 72 69 74 65 22 2c 20 0a 20 20 20  , "xWrite", .   
2950: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
2960: 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65  ngObj(pFd->zFile
2970: 6e 61 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e  name, -1), pFd->
2980: 70 53 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b  pShmId, 0.    );
2990: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
29a0: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
29b0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
29c0: 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49 6e 6a  TE_OK && tvfsInj
29d0: 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20 29 7b  ectFullerr(p) ){
29e0: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
29f0: 5f 46 55 4c 4c 3b 0a 20 20 7d 0a 20 20 69 66 28  _FULL;.  }.  if(
2a00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
2a10: 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56 46  & p->mask&TESTVF
2a20: 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20 26 26 20  S_WRITE_MASK && 
2a30: 74 76 66 73 49 6e 6a 65 63 74 49 6f 65 72 72 28  tvfsInjectIoerr(
2a40: 70 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  p) ){.    rc = S
2a50: 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a 20 20 7d  QLITE_IOERR;.  }
2a60: 0a 20 20 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  .  .  if( rc==SQ
2a70: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
2a80: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
2a90: 74 65 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 7a  te(pFd->pReal, z
2aa0: 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74  Buf, iAmt, iOfst
2ab0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
2ac0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75  rc;.}../*.** Tru
2ad0: 6e 63 61 74 65 20 61 6e 20 74 76 66 73 2d 66 69  ncate an tvfs-fi
2ae0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2af0: 74 20 74 76 66 73 54 72 75 6e 63 61 74 65 28 73  t tvfsTruncate(s
2b00: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2b10: 6c 65 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  le, sqlite_int64
2b20: 20 73 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63   size){.  int rc
2b30: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
2b40: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
2b50: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
2b60: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
2b70: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
2b80: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
2b90: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
2ba0: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
2bb0: 45 53 54 56 46 53 5f 54 52 55 4e 43 41 54 45 5f  ESTVFS_TRUNCATE_
2bc0: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73  MASK ){.    tvfs
2bd0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 54 72 75  ExecTcl(p, "xTru
2be0: 6e 63 61 74 65 22 2c 20 0a 20 20 20 20 20 20 20  ncate", .       
2bf0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
2c00: 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65  j(pFd->zFilename
2c10: 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53 68 6d  , -1), pFd->pShm
2c20: 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20  Id, 0.    );.   
2c30: 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28   tvfsResultCode(
2c40: 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 20 20 0a  p, &rc);.  }.  .
2c50: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2c60: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
2c70: 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74  sqlite3OsTruncat
2c80: 65 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 73 69  e(pFd->pReal, si
2c90: 7a 65 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ze);.  }.  retur
2ca0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  n rc;.}../*.** S
2cb0: 79 6e 63 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ync an tvfs-file
2cc0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2cd0: 74 76 66 73 53 79 6e 63 28 73 71 6c 69 74 65 33  tvfsSync(sqlite3
2ce0: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e  _file *pFile, in
2cf0: 74 20 66 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20  t flags){.  int 
2d00: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
2d10: 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64    TestvfsFd *pFd
2d20: 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69   = tvfsGetFd(pFi
2d30: 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  le);.  Testvfs *
2d40: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
2d50: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
2d60: 74 61 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53  ta;..  if( p->pS
2d70: 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b  cript && p->mask
2d80: 26 54 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41  &TESTVFS_SYNC_MA
2d90: 53 4b 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  SK ){.    char *
2da0: 7a 46 6c 61 67 73 3b 0a 0a 20 20 20 20 73 77 69  zFlags;..    swi
2db0: 74 63 68 28 20 66 6c 61 67 73 20 29 7b 0a 20 20  tch( flags ){.  
2dc0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
2dd0: 53 59 4e 43 5f 4e 4f 52 4d 41 4c 3a 0a 20 20 20  SYNC_NORMAL:.   
2de0: 20 20 20 20 20 7a 46 6c 61 67 73 20 3d 20 22 6e       zFlags = "n
2df0: 6f 72 6d 61 6c 22 3b 0a 20 20 20 20 20 20 20 20  ormal";.        
2e00: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73  break;.      cas
2e10: 65 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f 46 55  e SQLITE_SYNC_FU
2e20: 4c 4c 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c 61  LL:.        zFla
2e30: 67 73 20 3d 20 22 66 75 6c 6c 22 3b 0a 20 20 20  gs = "full";.   
2e40: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2e50: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 53 59    case SQLITE_SY
2e60: 4e 43 5f 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45  NC_NORMAL|SQLITE
2e70: 5f 53 59 4e 43 5f 44 41 54 41 4f 4e 4c 59 3a 0a  _SYNC_DATAONLY:.
2e80: 20 20 20 20 20 20 20 20 7a 46 6c 61 67 73 20 3d          zFlags =
2e90: 20 22 6e 6f 72 6d 61 6c 7c 64 61 74 61 6f 6e 6c   "normal|dataonl
2ea0: 79 22 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  y";.        brea
2eb0: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 53 51  k;.      case SQ
2ec0: 4c 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 7c 53  LITE_SYNC_FULL|S
2ed0: 51 4c 49 54 45 5f 53 59 4e 43 5f 44 41 54 41 4f  QLITE_SYNC_DATAO
2ee0: 4e 4c 59 3a 0a 20 20 20 20 20 20 20 20 7a 46 6c  NLY:.        zFl
2ef0: 61 67 73 20 3d 20 22 66 75 6c 6c 7c 64 61 74 61  ags = "full|data
2f00: 6f 6e 6c 79 22 3b 0a 20 20 20 20 20 20 20 20 62  only";.        b
2f10: 72 65 61 6b 3b 0a 20 20 20 20 20 20 64 65 66 61  reak;.      defa
2f20: 75 6c 74 3a 0a 20 20 20 20 20 20 20 20 61 73 73  ult:.        ass
2f30: 65 72 74 28 30 29 3b 0a 20 20 20 20 7d 0a 0a 20  ert(0);.    }.. 
2f40: 20 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70     tvfsExecTcl(p
2f50: 2c 20 22 78 53 79 6e 63 22 2c 20 0a 20 20 20 20  , "xSync", .    
2f60: 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e      Tcl_NewStrin
2f70: 67 4f 62 6a 28 70 46 64 2d 3e 7a 46 69 6c 65 6e  gObj(pFd->zFilen
2f80: 61 6d 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70  ame, -1), pFd->p
2f90: 53 68 6d 49 64 2c 0a 20 20 20 20 20 20 20 20 54  ShmId,.        T
2fa0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2fb0: 7a 46 6c 61 67 73 2c 20 2d 31 29 0a 20 20 20 20  zFlags, -1).    
2fc0: 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c  );.    tvfsResul
2fd0: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20  tCode(p, &rc);. 
2fe0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
2ff0: 4c 49 54 45 5f 4f 4b 20 26 26 20 74 76 66 73 49  LITE_OK && tvfsI
3000: 6e 6a 65 63 74 46 75 6c 6c 65 72 72 28 70 29 20  njectFullerr(p) 
3010: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55  ) rc = SQLITE_FU
3020: 4c 4c 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53  LL;..  if( rc==S
3030: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
3040: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79  rc = sqlite3OsSy
3050: 6e 63 28 70 46 64 2d 3e 70 52 65 61 6c 2c 20 66  nc(pFd->pReal, f
3060: 6c 61 67 73 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  lags);.  }..  re
3070: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
3080: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72  * Return the cur
3090: 72 65 6e 74 20 66 69 6c 65 2d 73 69 7a 65 20 6f  rent file-size o
30a0: 66 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  f an tvfs-file..
30b0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
30c0: 66 73 46 69 6c 65 53 69 7a 65 28 73 71 6c 69 74  fsFileSize(sqlit
30d0: 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20  e3_file *pFile, 
30e0: 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 53  sqlite_int64 *pS
30f0: 69 7a 65 29 7b 0a 20 20 54 65 73 74 76 66 73 46  ize){.  TestvfsF
3100: 64 20 2a 70 20 3d 20 74 76 66 73 47 65 74 46 64  d *p = tvfsGetFd
3110: 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72  (pFile);.  retur
3120: 6e 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53  n sqlite3OsFileS
3130: 69 7a 65 28 70 2d 3e 70 52 65 61 6c 2c 20 70 53  ize(p->pReal, pS
3140: 69 7a 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c  ize);.}../*.** L
3150: 6f 63 6b 20 61 6e 20 74 76 66 73 2d 66 69 6c 65  ock an tvfs-file
3160: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3170: 74 76 66 73 4c 6f 63 6b 28 73 71 6c 69 74 65 33  tvfsLock(sqlite3
3180: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 20 69 6e  _file *pFile, in
3190: 74 20 65 4c 6f 63 6b 29 7b 0a 20 20 54 65 73 74  t eLock){.  Test
31a0: 76 66 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47  vfsFd *p = tvfsG
31b0: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72  etFd(pFile);.  r
31c0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 4c  eturn sqlite3OsL
31d0: 6f 63 6b 28 70 2d 3e 70 52 65 61 6c 2c 20 65 4c  ock(p->pReal, eL
31e0: 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  ock);.}../*.** U
31f0: 6e 6c 6f 63 6b 20 61 6e 20 74 76 66 73 2d 66 69  nlock an tvfs-fi
3200: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
3210: 74 20 74 76 66 73 55 6e 6c 6f 63 6b 28 73 71 6c  t tvfsUnlock(sql
3220: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
3230: 2c 20 69 6e 74 20 65 4c 6f 63 6b 29 7b 0a 20 20  , int eLock){.  
3240: 54 65 73 74 76 66 73 46 64 20 2a 70 20 3d 20 74  TestvfsFd *p = t
3250: 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b  vfsGetFd(pFile);
3260: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
3270: 33 4f 73 55 6e 6c 6f 63 6b 28 70 2d 3e 70 52 65  3OsUnlock(p->pRe
3280: 61 6c 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a 0a 2f  al, eLock);.}../
3290: 2a 0a 2a 2a 20 43 68 65 63 6b 20 69 66 20 61 6e  *.** Check if an
32a0: 6f 74 68 65 72 20 66 69 6c 65 2d 68 61 6e 64 6c  other file-handl
32b0: 65 20 68 6f 6c 64 73 20 61 20 52 45 53 45 52 56  e holds a RESERV
32c0: 45 44 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 74 76  ED lock on an tv
32d0: 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74  fs-file..*/.stat
32e0: 69 63 20 69 6e 74 20 74 76 66 73 43 68 65 63 6b  ic int tvfsCheck
32f0: 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c  ReservedLock(sql
3300: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
3310: 2c 20 69 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b  , int *pResOut){
3320: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 20  .  TestvfsFd *p 
3330: 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c  = tvfsGetFd(pFil
3340: 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  e);.  return sql
3350: 69 74 65 33 4f 73 43 68 65 63 6b 52 65 73 65 72  ite3OsCheckReser
3360: 76 65 64 4c 6f 63 6b 28 70 2d 3e 70 52 65 61 6c  vedLock(p->pReal
3370: 2c 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f  , pResOut);.}../
3380: 2a 0a 2a 2a 20 46 69 6c 65 20 63 6f 6e 74 72 6f  *.** File contro
3390: 6c 20 6d 65 74 68 6f 64 2e 20 46 6f 72 20 63 75  l method. For cu
33a0: 73 74 6f 6d 20 6f 70 65 72 61 74 69 6f 6e 73 20  stom operations 
33b0: 6f 6e 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e  on an tvfs-file.
33c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
33d0: 76 66 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73  vfsFileControl(s
33e0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
33f0: 6c 65 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64  le, int op, void
3400: 20 2a 70 41 72 67 29 7b 0a 20 20 54 65 73 74 76   *pArg){.  Testv
3410: 66 73 46 64 20 2a 70 20 3d 20 74 76 66 73 47 65  fsFd *p = tvfsGe
3420: 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 72 65  tFd(pFile);.  re
3430: 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 46 69  turn sqlite3OsFi
3440: 6c 65 43 6f 6e 74 72 6f 6c 28 70 2d 3e 70 52 65  leControl(p->pRe
3450: 61 6c 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d  al, op, pArg);.}
3460: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
3470: 68 65 20 73 65 63 74 6f 72 2d 73 69 7a 65 20 69  he sector-size i
3480: 6e 20 62 79 74 65 73 20 66 6f 72 20 61 6e 20 74  n bytes for an t
3490: 76 66 73 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  vfs-file..*/.sta
34a0: 74 69 63 20 69 6e 74 20 74 76 66 73 53 65 63 74  tic int tvfsSect
34b0: 6f 72 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66  orSize(sqlite3_f
34c0: 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20 54  ile *pFile){.  T
34d0: 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20  estvfsFd *pFd = 
34e0: 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65 29  tvfsGetFd(pFile)
34f0: 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d  ;.  Testvfs *p =
3500: 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64 2d   (Testvfs *)pFd-
3510: 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 3b  >pVfs->pAppData;
3520: 0a 20 20 69 66 28 20 70 2d 3e 69 53 65 63 74 6f  .  if( p->iSecto
3530: 72 73 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20  rsize>=0 ){.    
3540: 72 65 74 75 72 6e 20 70 2d 3e 69 53 65 63 74 6f  return p->iSecto
3550: 72 73 69 7a 65 3b 0a 20 20 7d 0a 20 20 72 65 74  rsize;.  }.  ret
3560: 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 65 63  urn sqlite3OsSec
3570: 74 6f 72 53 69 7a 65 28 70 46 64 2d 3e 70 52 65  torSize(pFd->pRe
3580: 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  al);.}../*.** Re
3590: 74 75 72 6e 20 74 68 65 20 64 65 76 69 63 65 20  turn the device 
35a0: 63 68 61 72 61 63 74 65 72 69 73 74 69 63 20 66  characteristic f
35b0: 6c 61 67 73 20 73 75 70 70 6f 72 74 65 64 20 62  lags supported b
35c0: 79 20 61 6e 20 74 76 66 73 2d 66 69 6c 65 2e 0a  y an tvfs-file..
35d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  */.static int tv
35e0: 66 73 44 65 76 69 63 65 43 68 61 72 61 63 74 65  fsDeviceCharacte
35f0: 72 69 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f  ristics(sqlite3_
3600: 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20  file *pFile){.  
3610: 54 65 73 74 76 66 73 46 64 20 2a 70 46 64 20 3d  TestvfsFd *pFd =
3620: 20 74 76 66 73 47 65 74 46 64 28 70 46 69 6c 65   tvfsGetFd(pFile
3630: 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a 70 20  );.  Testvfs *p 
3640: 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70 46 64  = (Testvfs *)pFd
3650: 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61  ->pVfs->pAppData
3660: 3b 0a 20 20 69 66 28 20 70 2d 3e 69 44 65 76 63  ;.  if( p->iDevc
3670: 68 61 72 3e 3d 30 20 29 7b 0a 20 20 20 20 72 65  har>=0 ){.    re
3680: 74 75 72 6e 20 70 2d 3e 69 44 65 76 63 68 61 72  turn p->iDevchar
3690: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 73  ;.  }.  return s
36a0: 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65 43 68  qlite3OsDeviceCh
36b0: 61 72 61 63 74 65 72 69 73 74 69 63 73 28 70 46  aracteristics(pF
36c0: 64 2d 3e 70 52 65 61 6c 29 3b 0a 7d 0a 0a 2f 2a  d->pReal);.}../*
36d0: 0a 2a 2a 20 4f 70 65 6e 20 61 6e 20 74 76 66 73  .** Open an tvfs
36e0: 20 66 69 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f   file handle..*/
36f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76 66 73  .static int tvfs
3700: 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  Open(.  sqlite3_
3710: 76 66 73 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e  vfs *pVfs,.  con
3720: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a  st char *zName,.
3730: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3740: 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61  pFile,.  int fla
3750: 67 73 2c 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46  gs,.  int *pOutF
3760: 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74 20 72 63  lags.){.  int rc
3770: 3b 0a 20 20 54 65 73 74 76 66 73 46 69 6c 65 20  ;.  TestvfsFile 
3780: 2a 70 54 65 73 74 66 69 6c 65 20 3d 20 28 54 65  *pTestfile = (Te
3790: 73 74 76 66 73 46 69 6c 65 20 2a 29 70 46 69 6c  stvfsFile *)pFil
37a0: 65 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a  e;.  TestvfsFd *
37b0: 70 46 64 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  pFd;.  Tcl_Obj *
37c0: 70 49 64 20 3d 20 30 3b 0a 20 20 54 65 73 74 76  pId = 0;.  Testv
37d0: 66 73 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73  fs *p = (Testvfs
37e0: 20 2a 29 70 56 66 73 2d 3e 70 41 70 70 44 61 74   *)pVfs->pAppDat
37f0: 61 3b 0a 0a 20 20 70 46 64 20 3d 20 28 54 65 73  a;..  pFd = (Tes
3800: 74 76 66 73 46 64 20 2a 29 63 6b 61 6c 6c 6f 63  tvfsFd *)ckalloc
3810: 28 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73 46  (sizeof(TestvfsF
3820: 64 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28 70  d) + PARENTVFS(p
3830: 56 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b  Vfs)->szOsFile);
3840: 0a 20 20 6d 65 6d 73 65 74 28 70 46 64 2c 20 30  .  memset(pFd, 0
3850: 2c 20 73 69 7a 65 6f 66 28 54 65 73 74 76 66 73  , sizeof(Testvfs
3860: 46 64 29 20 2b 20 50 41 52 45 4e 54 56 46 53 28  Fd) + PARENTVFS(
3870: 70 56 66 73 29 2d 3e 73 7a 4f 73 46 69 6c 65 29  pVfs)->szOsFile)
3880: 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 20 3d 20  ;.  pFd->pShm = 
3890: 30 3b 0a 20 20 70 46 64 2d 3e 70 53 68 6d 49 64  0;.  pFd->pShmId
38a0: 20 3d 20 30 3b 0a 20 20 70 46 64 2d 3e 7a 46 69   = 0;.  pFd->zFi
38b0: 6c 65 6e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a  lename = zName;.
38c0: 20 20 70 46 64 2d 3e 70 56 66 73 20 3d 20 70 56    pFd->pVfs = pV
38d0: 66 73 3b 0a 20 20 70 46 64 2d 3e 70 52 65 61 6c  fs;.  pFd->pReal
38e0: 20 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65   = (sqlite3_file
38f0: 20 2a 29 26 70 46 64 5b 31 5d 3b 0a 20 20 70 54   *)&pFd[1];.  pT
3900: 65 73 74 66 69 6c 65 2d 3e 70 46 64 20 3d 20 70  estfile->pFd = p
3910: 46 64 3b 0a 0a 20 20 2f 2a 20 45 76 61 6c 75 61  Fd;..  /* Evalua
3920: 74 65 20 74 68 65 20 54 63 6c 20 73 63 72 69 70  te the Tcl scrip
3930: 74 3a 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  t: .  **.  **   
3940: 53 43 52 49 50 54 20 78 4f 70 65 6e 20 46 49 4c  SCRIPT xOpen FIL
3950: 45 4e 41 4d 45 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ENAME.  **.  ** 
3960: 49 66 20 74 68 65 20 73 63 72 69 70 74 20 72 65  If the script re
3970: 74 75 72 6e 73 20 61 6e 20 53 51 4c 69 74 65 20  turns an SQLite 
3980: 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
3990: 20 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c   than SQLITE_OK,
39a0: 20 61 6e 0a 20 20 2a 2a 20 65 72 72 6f 72 20 69   an.  ** error i
39b0: 73 20 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68  s returned to th
39c0: 65 20 63 61 6c 6c 65 72 2e 20 49 66 20 69 74 20  e caller. If it 
39d0: 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f  returns SQLITE_O
39e0: 4b 2c 20 74 68 65 20 6e 65 77 0a 20 20 2a 2a 20  K, the new.  ** 
39f0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20 6e 61  connection is na
3a00: 6d 65 64 20 22 61 6e 6f 6e 22 2e 20 4f 74 68 65  med "anon". Othe
3a10: 72 77 69 73 65 2c 20 74 68 65 20 76 61 6c 75 65  rwise, the value
3a20: 20 72 65 74 75 72 6e 65 64 20 62 79 20 74 68 65   returned by the
3a30: 0a 20 20 2a 2a 20 73 63 72 69 70 74 20 69 73 20  .  ** script is 
3a40: 75 73 65 64 20 61 73 20 74 68 65 20 63 6f 6e 6e  used as the conn
3a50: 65 63 74 69 6f 6e 20 6e 61 6d 65 2e 0a 20 20 2a  ection name..  *
3a60: 2f 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73  /.  Tcl_ResetRes
3a70: 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a  ult(p->interp);.
3a80: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
3a90: 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54   && p->mask&TEST
3aa0: 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20 29 7b  VFS_OPEN_MASK ){
3ab0: 0a 20 20 20 20 74 76 66 73 45 78 65 63 54 63 6c  .    tvfsExecTcl
3ac0: 28 70 2c 20 22 78 4f 70 65 6e 22 2c 20 54 63 6c  (p, "xOpen", Tcl
3ad0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46  _NewStringObj(pF
3ae0: 64 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31  d->zFilename, -1
3af0: 29 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 69 66  ), 0, 0);.    if
3b00: 28 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64 65  ( tvfsResultCode
3b10: 28 70 2c 20 26 72 63 29 20 29 7b 0a 20 20 20 20  (p, &rc) ){.    
3b20: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
3b30: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
3b40: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
3b50: 20 20 70 49 64 20 3d 20 54 63 6c 5f 47 65 74 4f    pId = Tcl_GetO
3b60: 62 6a 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74 65  bjResult(p->inte
3b70: 72 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  rp);.    }.  }..
3b80: 20 20 69 66 28 20 28 70 2d 3e 6d 61 73 6b 26 54    if( (p->mask&T
3b90: 45 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b  ESTVFS_OPEN_MASK
3ba0: 29 20 26 26 20 20 74 76 66 73 49 6e 6a 65 63 74  ) &&  tvfsInject
3bb0: 49 6f 65 72 72 28 70 29 20 29 20 72 65 74 75 72  Ioerr(p) ) retur
3bc0: 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a  n SQLITE_IOERR;.
3bd0: 20 20 69 66 28 20 74 76 66 73 49 6e 6a 65 63 74    if( tvfsInject
3be0: 43 61 6e 74 6f 70 65 6e 65 72 72 28 70 29 20 29  Cantopenerr(p) )
3bf0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43   return SQLITE_C
3c00: 41 4e 54 4f 50 45 4e 3b 0a 20 20 69 66 28 20 74  ANTOPEN;.  if( t
3c10: 76 66 73 49 6e 6a 65 63 74 46 75 6c 6c 65 72 72  vfsInjectFullerr
3c20: 28 70 29 20 29 20 72 65 74 75 72 6e 20 53 51 4c  (p) ) return SQL
3c30: 49 54 45 5f 46 55 4c 4c 3b 0a 0a 20 20 69 66 28  ITE_FULL;..  if(
3c40: 20 21 70 49 64 20 29 7b 0a 20 20 20 20 70 49 64   !pId ){.    pId
3c50: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
3c60: 4f 62 6a 28 22 61 6e 6f 6e 22 2c 20 2d 31 29 3b  Obj("anon", -1);
3c70: 0a 20 20 7d 0a 20 20 54 63 6c 5f 49 6e 63 72 52  .  }.  Tcl_IncrR
3c80: 65 66 43 6f 75 6e 74 28 70 49 64 29 3b 0a 20 20  efCount(pId);.  
3c90: 70 46 64 2d 3e 70 53 68 6d 49 64 20 3d 20 70 49  pFd->pShmId = pI
3ca0: 64 3b 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65  d;.  Tcl_ResetRe
3cb0: 73 75 6c 74 28 70 2d 3e 69 6e 74 65 72 70 29 3b  sult(p->interp);
3cc0: 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ..  rc = sqlite3
3cd0: 4f 73 4f 70 65 6e 28 50 41 52 45 4e 54 56 46 53  OsOpen(PARENTVFS
3ce0: 28 70 56 66 73 29 2c 20 7a 4e 61 6d 65 2c 20 70  (pVfs), zName, p
3cf0: 46 64 2d 3e 70 52 65 61 6c 2c 20 66 6c 61 67 73  Fd->pReal, flags
3d00: 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20  , pOutFlags);.  
3d10: 69 66 28 20 70 46 64 2d 3e 70 52 65 61 6c 2d 3e  if( pFd->pReal->
3d20: 70 4d 65 74 68 6f 64 73 20 29 7b 0a 20 20 20 20  pMethods ){.    
3d30: 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f  sqlite3_io_metho
3d40: 64 73 20 2a 70 4d 65 74 68 6f 64 73 3b 0a 20 20  ds *pMethods;.  
3d50: 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 0a 20 20    int nByte;..  
3d60: 20 20 69 66 28 20 70 56 66 73 2d 3e 69 56 65 72    if( pVfs->iVer
3d70: 73 69 6f 6e 3e 31 20 29 7b 0a 20 20 20 20 20 20  sion>1 ){.      
3d80: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 73  nByte = sizeof(s
3d90: 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64  qlite3_io_method
3da0: 73 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  s);.    }else{. 
3db0: 20 20 20 20 20 6e 42 79 74 65 20 3d 20 6f 66 66       nByte = off
3dc0: 73 65 74 6f 66 28 73 71 6c 69 74 65 33 5f 69 6f  setof(sqlite3_io
3dd0: 5f 6d 65 74 68 6f 64 73 2c 20 78 53 68 6d 4d 61  _methods, xShmMa
3de0: 70 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70  p);.    }..    p
3df0: 4d 65 74 68 6f 64 73 20 3d 20 28 73 71 6c 69 74  Methods = (sqlit
3e00: 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 2a 29  e3_io_methods *)
3e10: 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a  ckalloc(nByte);.
3e20: 20 20 20 20 6d 65 6d 63 70 79 28 70 4d 65 74 68      memcpy(pMeth
3e30: 6f 64 73 2c 20 26 74 76 66 73 5f 69 6f 5f 6d 65  ods, &tvfs_io_me
3e40: 74 68 6f 64 73 2c 20 6e 42 79 74 65 29 3b 0a 20  thods, nByte);. 
3e50: 20 20 20 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65     pMethods->iVe
3e60: 72 73 69 6f 6e 20 3d 20 70 56 66 73 2d 3e 69 56  rsion = pVfs->iV
3e70: 65 72 73 69 6f 6e 3b 0a 20 20 20 20 69 66 28 20  ersion;.    if( 
3e80: 70 56 66 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 31  pVfs->iVersion>1
3e90: 20 26 26 20 28 28 54 65 73 74 76 66 73 20 2a 29   && ((Testvfs *)
3ea0: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29 2d  pVfs->pAppData)-
3eb0: 3e 69 73 4e 6f 73 68 6d 20 29 7b 0a 20 20 20 20  >isNoshm ){.    
3ec0: 20 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d    pMethods->xShm
3ed0: 55 6e 6d 61 70 20 3d 20 30 3b 0a 20 20 20 20 20  Unmap = 0;.     
3ee0: 20 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c   pMethods->xShmL
3ef0: 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 70  ock = 0;.      p
3f00: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72  Methods->xShmBar
3f10: 72 69 65 72 20 3d 20 30 3b 0a 20 20 20 20 20 20  rier = 0;.      
3f20: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61  pMethods->xShmMa
3f30: 70 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  p = 0;.    }.   
3f40: 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73   pFile->pMethods
3f50: 20 3d 20 70 4d 65 74 68 6f 64 73 3b 0a 20 20 7d   = pMethods;.  }
3f60: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
3f70: 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 74  ../*.** Delete t
3f80: 68 65 20 66 69 6c 65 20 6c 6f 63 61 74 65 64 20  he file located 
3f90: 61 74 20 7a 50 61 74 68 2e 20 49 66 20 74 68 65  at zPath. If the
3fa0: 20 64 69 72 53 79 6e 63 20 61 72 67 75 6d 65 6e   dirSync argumen
3fb0: 74 20 69 73 20 74 72 75 65 2c 0a 2a 2a 20 65 6e  t is true,.** en
3fc0: 73 75 72 65 20 74 68 65 20 66 69 6c 65 2d 73 79  sure the file-sy
3fd0: 73 74 65 6d 20 6d 6f 64 69 66 69 63 61 74 69 6f  stem modificatio
3fe0: 6e 73 20 61 72 65 20 73 79 6e 63 65 64 20 74 6f  ns are synced to
3ff0: 20 64 69 73 6b 20 62 65 66 6f 72 65 0a 2a 2a 20   disk before.** 
4000: 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74  returning..*/.st
4010: 61 74 69 63 20 69 6e 74 20 74 76 66 73 44 65 6c  atic int tvfsDel
4020: 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ete(sqlite3_vfs 
4030: 2a 70 56 66 73 2c 20 63 6f 6e 73 74 20 63 68 61  *pVfs, const cha
4040: 72 20 2a 7a 50 61 74 68 2c 20 69 6e 74 20 64 69  r *zPath, int di
4050: 72 53 79 6e 63 29 7b 0a 20 20 69 6e 74 20 72 63  rSync){.  int rc
4060: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
4070: 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65  Testvfs *p = (Te
4080: 73 74 76 66 73 20 2a 29 70 56 66 73 2d 3e 70 41  stvfs *)pVfs->pA
4090: 70 70 44 61 74 61 3b 0a 0a 20 20 69 66 28 20 70  ppData;..  if( p
40a0: 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e  ->pScript && p->
40b0: 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 44 45 4c  mask&TESTVFS_DEL
40c0: 45 54 45 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20  ETE_MASK ){.    
40d0: 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22  tvfsExecTcl(p, "
40e0: 78 44 65 6c 65 74 65 22 2c 20 0a 20 20 20 20 20  xDelete", .     
40f0: 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67     Tcl_NewString
4100: 4f 62 6a 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20  Obj(zPath, -1), 
4110: 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 64 69  Tcl_NewIntObj(di
4120: 72 53 79 6e 63 29 2c 20 30 0a 20 20 20 20 29 3b  rSync), 0.    );
4130: 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c 74 43  .    tvfsResultC
4140: 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d  ode(p, &rc);.  }
4150: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
4160: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
4170: 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65   sqlite3OsDelete
4180: 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29  (PARENTVFS(pVfs)
4190: 2c 20 7a 50 61 74 68 2c 20 64 69 72 53 79 6e 63  , zPath, dirSync
41a0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
41b0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 73  rc;.}../*.** Tes
41c0: 74 20 66 6f 72 20 61 63 63 65 73 73 20 70 65 72  t for access per
41d0: 6d 69 73 73 69 6f 6e 73 2e 20 52 65 74 75 72 6e  missions. Return
41e0: 20 74 72 75 65 20 69 66 20 74 68 65 20 72 65 71   true if the req
41f0: 75 65 73 74 65 64 20 70 65 72 6d 69 73 73 69 6f  uested permissio
4200: 6e 0a 2a 2a 20 69 73 20 61 76 61 69 6c 61 62 6c  n.** is availabl
4210: 65 2c 20 6f 72 20 66 61 6c 73 65 20 6f 74 68 65  e, or false othe
4220: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
4230: 20 69 6e 74 20 74 76 66 73 41 63 63 65 73 73 28   int tvfsAccess(
4240: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
4250: 70 56 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63  pVfs, .  const c
4260: 68 61 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69  har *zPath, .  i
4270: 6e 74 20 66 6c 61 67 73 2c 20 0a 20 20 69 6e 74  nt flags, .  int
4280: 20 2a 70 52 65 73 4f 75 74 0a 29 7b 0a 20 20 54   *pResOut.){.  T
4290: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
42a0: 74 76 66 73 20 2a 29 70 56 66 73 2d 3e 70 41 70  tvfs *)pVfs->pAp
42b0: 70 44 61 74 61 3b 0a 20 20 69 66 28 20 70 2d 3e  pData;.  if( p->
42c0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
42d0: 73 6b 26 54 45 53 54 56 46 53 5f 41 43 43 45 53  sk&TESTVFS_ACCES
42e0: 53 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 69 6e  S_MASK ){.    in
42f0: 74 20 72 63 3b 0a 20 20 20 20 63 68 61 72 20 2a  t rc;.    char *
4300: 7a 41 72 67 20 3d 20 30 3b 0a 20 20 20 20 69 66  zArg = 0;.    if
4310: 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f  ( flags==SQLITE_
4320: 41 43 43 45 53 53 5f 45 58 49 53 54 53 20 29 20  ACCESS_EXISTS ) 
4330: 7a 41 72 67 20 3d 20 22 53 51 4c 49 54 45 5f 41  zArg = "SQLITE_A
4340: 43 43 45 53 53 5f 45 58 49 53 54 53 22 3b 0a 20  CCESS_EXISTS";. 
4350: 20 20 20 69 66 28 20 66 6c 61 67 73 3d 3d 53 51     if( flags==SQ
4360: 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45 41 44  LITE_ACCESS_READ
4370: 57 52 49 54 45 20 29 20 7a 41 72 67 20 3d 20 22  WRITE ) zArg = "
4380: 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 52 45  SQLITE_ACCESS_RE
4390: 41 44 57 52 49 54 45 22 3b 0a 20 20 20 20 69 66  ADWRITE";.    if
43a0: 28 20 66 6c 61 67 73 3d 3d 53 51 4c 49 54 45 5f  ( flags==SQLITE_
43b0: 41 43 43 45 53 53 5f 52 45 41 44 20 29 20 7a 41  ACCESS_READ ) zA
43c0: 72 67 20 3d 20 22 53 51 4c 49 54 45 5f 41 43 43  rg = "SQLITE_ACC
43d0: 45 53 53 5f 52 45 41 44 22 3b 0a 20 20 20 20 74  ESS_READ";.    t
43e0: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
43f0: 41 63 63 65 73 73 22 2c 20 0a 20 20 20 20 20 20  Access", .      
4400: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
4410: 62 6a 28 7a 50 61 74 68 2c 20 2d 31 29 2c 20 54  bj(zPath, -1), T
4420: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
4430: 7a 41 72 67 2c 20 2d 31 29 2c 20 30 0a 20 20 20  zArg, -1), 0.   
4440: 20 29 3b 0a 20 20 20 20 69 66 28 20 74 76 66 73   );.    if( tvfs
4450: 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20 26 72  ResultCode(p, &r
4460: 63 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  c) ){.      if( 
4470: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
4480: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
4490: 65 6c 73 65 7b 0a 20 20 20 20 20 20 54 63 6c 5f  else{.      Tcl_
44a0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d  Interp *interp =
44b0: 20 70 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 20 20   p->interp;.    
44c0: 20 20 69 66 28 20 54 43 4c 5f 4f 4b 3d 3d 54 63    if( TCL_OK==Tc
44d0: 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d  l_GetBooleanFrom
44e0: 4f 62 6a 28 30 2c 20 54 63 6c 5f 47 65 74 4f 62  Obj(0, Tcl_GetOb
44f0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c  jResult(interp),
4500: 20 70 52 65 73 4f 75 74 29 20 29 7b 0a 20 20 20   pResOut) ){.   
4510: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
4520: 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20  TE_OK;.      }. 
4530: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
4540: 6e 20 73 71 6c 69 74 65 33 4f 73 41 63 63 65 73  n sqlite3OsAcces
4550: 73 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  s(PARENTVFS(pVfs
4560: 29 2c 20 7a 50 61 74 68 2c 20 66 6c 61 67 73 2c  ), zPath, flags,
4570: 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a   pResOut);.}../*
4580: 0a 2a 2a 20 50 6f 70 75 6c 61 74 65 20 62 75 66  .** Populate buf
4590: 66 65 72 20 7a 4f 75 74 20 77 69 74 68 20 74 68  fer zOut with th
45a0: 65 20 66 75 6c 6c 20 63 61 6e 6f 6e 69 63 61 6c  e full canonical
45b0: 20 70 61 74 68 6e 61 6d 65 20 63 6f 72 72 65 73   pathname corres
45c0: 70 6f 6e 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68  ponding.** to th
45d0: 65 20 70 61 74 68 6e 61 6d 65 20 69 6e 20 7a 50  e pathname in zP
45e0: 61 74 68 2e 20 7a 4f 75 74 20 69 73 20 67 75 61  ath. zOut is gua
45f0: 72 61 6e 74 65 65 64 20 74 6f 20 70 6f 69 6e 74  ranteed to point
4600: 20 74 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20   to a buffer.** 
4610: 6f 66 20 61 74 20 6c 65 61 73 74 20 28 44 45 56  of at least (DEV
4620: 53 59 4d 5f 4d 41 58 5f 50 41 54 48 4e 41 4d 45  SYM_MAX_PATHNAME
4630: 2b 31 29 20 62 79 74 65 73 2e 0a 2a 2f 0a 73 74  +1) bytes..*/.st
4640: 61 74 69 63 20 69 6e 74 20 74 76 66 73 46 75 6c  atic int tvfsFul
4650: 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 73 71 6c  lPathname(.  sql
4660: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4670: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
4680: 50 61 74 68 2c 20 0a 20 20 69 6e 74 20 6e 4f 75  Path, .  int nOu
4690: 74 2c 20 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74  t, .  char *zOut
46a0: 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  .){.  return sql
46b0: 69 74 65 33 4f 73 46 75 6c 6c 50 61 74 68 6e 61  ite3OsFullPathna
46c0: 6d 65 28 50 41 52 45 4e 54 56 46 53 28 70 56 66  me(PARENTVFS(pVf
46d0: 73 29 2c 20 7a 50 61 74 68 2c 20 6e 4f 75 74 2c  s), zPath, nOut,
46e0: 20 7a 4f 75 74 29 3b 0a 7d 0a 0a 23 69 66 6e 64   zOut);.}..#ifnd
46f0: 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 4c  ef SQLITE_OMIT_L
4700: 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e 0a 2f 2a  OAD_EXTENSION./*
4710: 0a 2a 2a 20 4f 70 65 6e 20 74 68 65 20 64 79 6e  .** Open the dyn
4720: 61 6d 69 63 20 6c 69 62 72 61 72 79 20 6c 6f 63  amic library loc
4730: 61 74 65 64 20 61 74 20 7a 50 61 74 68 20 61 6e  ated at zPath an
4740: 64 20 72 65 74 75 72 6e 20 61 20 68 61 6e 64 6c  d return a handl
4750: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
4760: 64 20 2a 74 76 66 73 44 6c 4f 70 65 6e 28 73 71  d *tvfsDlOpen(sq
4770: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
4780: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61   const char *zPa
4790: 74 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  th){.  return sq
47a0: 6c 69 74 65 33 4f 73 44 6c 4f 70 65 6e 28 50 41  lite3OsDlOpen(PA
47b0: 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 7a  RENTVFS(pVfs), z
47c0: 50 61 74 68 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Path);.}../*.** 
47d0: 50 6f 70 75 6c 61 74 65 20 74 68 65 20 62 75 66  Populate the buf
47e0: 66 65 72 20 7a 45 72 72 4d 73 67 20 28 73 69 7a  fer zErrMsg (siz
47f0: 65 20 6e 42 79 74 65 20 62 79 74 65 73 29 20 77  e nByte bytes) w
4800: 69 74 68 20 61 20 68 75 6d 61 6e 20 72 65 61 64  ith a human read
4810: 61 62 6c 65 0a 2a 2a 20 75 74 66 2d 38 20 73 74  able.** utf-8 st
4820: 72 69 6e 67 20 64 65 73 63 72 69 62 69 6e 67 20  ring describing 
4830: 74 68 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 20  the most recent 
4840: 65 72 72 6f 72 20 65 6e 63 6f 75 6e 74 65 72 65  error encountere
4850: 64 20 61 73 73 6f 63 69 61 74 65 64 20 0a 2a 2a  d associated .**
4860: 20 77 69 74 68 20 64 79 6e 61 6d 69 63 20 6c 69   with dynamic li
4870: 62 72 61 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74  braries..*/.stat
4880: 69 63 20 76 6f 69 64 20 74 76 66 73 44 6c 45 72  ic void tvfsDlEr
4890: 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66 73 20  ror(sqlite3_vfs 
48a0: 2a 70 56 66 73 2c 20 69 6e 74 20 6e 42 79 74 65  *pVfs, int nByte
48b0: 2c 20 63 68 61 72 20 2a 7a 45 72 72 4d 73 67 29  , char *zErrMsg)
48c0: 7b 0a 20 20 73 71 6c 69 74 65 33 4f 73 44 6c 45  {.  sqlite3OsDlE
48d0: 72 72 6f 72 28 50 41 52 45 4e 54 56 46 53 28 70  rror(PARENTVFS(p
48e0: 56 66 73 29 2c 20 6e 42 79 74 65 2c 20 7a 45 72  Vfs), nByte, zEr
48f0: 72 4d 73 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rMsg);.}../*.** 
4900: 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72  Return a pointer
4910: 20 74 6f 20 74 68 65 20 73 79 6d 62 6f 6c 20 7a   to the symbol z
4920: 53 79 6d 62 6f 6c 20 69 6e 20 74 68 65 20 64 79  Symbol in the dy
4930: 6e 61 6d 69 63 20 6c 69 62 72 61 72 79 20 70 48  namic library pH
4940: 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  andle..*/.static
4950: 20 76 6f 69 64 20 28 2a 74 76 66 73 44 6c 53 79   void (*tvfsDlSy
4960: 6d 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  m(sqlite3_vfs *p
4970: 56 66 73 2c 20 76 6f 69 64 20 2a 70 2c 20 63 6f  Vfs, void *p, co
4980: 6e 73 74 20 63 68 61 72 20 2a 7a 53 79 6d 29 29  nst char *zSym))
4990: 28 76 6f 69 64 29 7b 0a 20 20 72 65 74 75 72 6e  (void){.  return
49a0: 20 73 71 6c 69 74 65 33 4f 73 44 6c 53 79 6d 28   sqlite3OsDlSym(
49b0: 50 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c  PARENTVFS(pVfs),
49c0: 20 70 2c 20 7a 53 79 6d 29 3b 0a 7d 0a 0a 2f 2a   p, zSym);.}../*
49d0: 0a 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20 64 79  .** Close the dy
49e0: 6e 61 6d 69 63 20 6c 69 62 72 61 72 79 20 68 61  namic library ha
49f0: 6e 64 6c 65 20 70 48 61 6e 64 6c 65 2e 0a 2a 2f  ndle pHandle..*/
4a00: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 76 66  .static void tvf
4a10: 73 44 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  sDlClose(sqlite3
4a20: 5f 76 66 73 20 2a 70 56 66 73 2c 20 76 6f 69 64  _vfs *pVfs, void
4a30: 20 2a 70 48 61 6e 64 6c 65 29 7b 0a 20 20 73 71   *pHandle){.  sq
4a40: 6c 69 74 65 33 4f 73 44 6c 43 6c 6f 73 65 28 50  lite3OsDlClose(P
4a50: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20  ARENTVFS(pVfs), 
4a60: 70 48 61 6e 64 6c 65 29 3b 0a 7d 0a 23 65 6e 64  pHandle);.}.#end
4a70: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49  if /* SQLITE_OMI
4a80: 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53 49 4f 4e  T_LOAD_EXTENSION
4a90: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 6f 70 75 6c   */../*.** Popul
4aa0: 61 74 65 20 74 68 65 20 62 75 66 66 65 72 20 70  ate the buffer p
4ab0: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 42 75  ointed to by zBu
4ac0: 66 4f 75 74 20 77 69 74 68 20 6e 42 79 74 65 20  fOut with nByte 
4ad0: 62 79 74 65 73 20 6f 66 20 0a 2a 2a 20 72 61 6e  bytes of .** ran
4ae0: 64 6f 6d 20 64 61 74 61 2e 0a 2a 2f 0a 73 74 61  dom data..*/.sta
4af0: 74 69 63 20 69 6e 74 20 74 76 66 73 52 61 6e 64  tic int tvfsRand
4b00: 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f 76  omness(sqlite3_v
4b10: 66 73 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 42  fs *pVfs, int nB
4b20: 79 74 65 2c 20 63 68 61 72 20 2a 7a 42 75 66 4f  yte, char *zBufO
4b30: 75 74 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71  ut){.  return sq
4b40: 6c 69 74 65 33 4f 73 52 61 6e 64 6f 6d 6e 65 73  lite3OsRandomnes
4b50: 73 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  s(PARENTVFS(pVfs
4b60: 29 2c 20 6e 42 79 74 65 2c 20 7a 42 75 66 4f 75  ), nByte, zBufOu
4b70: 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6c 65  t);.}../*.** Sle
4b80: 65 70 20 66 6f 72 20 6e 4d 69 63 72 6f 20 6d 69  ep for nMicro mi
4b90: 63 72 6f 73 65 63 6f 6e 64 73 2e 20 52 65 74 75  croseconds. Retu
4ba0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
4bb0: 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 0a 2a   microseconds .*
4bc0: 2a 20 61 63 74 75 61 6c 6c 79 20 73 6c 65 70 74  * actually slept
4bd0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4be0: 74 76 66 73 53 6c 65 65 70 28 73 71 6c 69 74 65  tvfsSleep(sqlite
4bf0: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69 6e 74  3_vfs *pVfs, int
4c00: 20 6e 4d 69 63 72 6f 29 7b 0a 20 20 72 65 74 75   nMicro){.  retu
4c10: 72 6e 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65  rn sqlite3OsSlee
4c20: 70 28 50 41 52 45 4e 54 56 46 53 28 70 56 66 73  p(PARENTVFS(pVfs
4c30: 29 2c 20 6e 4d 69 63 72 6f 29 3b 0a 7d 0a 0a 2f  ), nMicro);.}../
4c40: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
4c50: 63 75 72 72 65 6e 74 20 74 69 6d 65 20 61 73 20  current time as 
4c60: 61 20 4a 75 6c 69 61 6e 20 44 61 79 20 6e 75 6d  a Julian Day num
4c70: 62 65 72 20 69 6e 20 2a 70 54 69 6d 65 4f 75 74  ber in *pTimeOut
4c80: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4c90: 74 76 66 73 43 75 72 72 65 6e 74 54 69 6d 65 28  tvfsCurrentTime(
4ca0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4cb0: 73 2c 20 64 6f 75 62 6c 65 20 2a 70 54 69 6d 65  s, double *pTime
4cc0: 4f 75 74 29 7b 0a 20 20 72 65 74 75 72 6e 20 50  Out){.  return P
4cd0: 41 52 45 4e 54 56 46 53 28 70 56 66 73 29 2d 3e  ARENTVFS(pVfs)->
4ce0: 78 43 75 72 72 65 6e 74 54 69 6d 65 28 50 41 52  xCurrentTime(PAR
4cf0: 45 4e 54 56 46 53 28 70 56 66 73 29 2c 20 70 54  ENTVFS(pVfs), pT
4d00: 69 6d 65 4f 75 74 29 3b 0a 7d 0a 0a 73 74 61 74  imeOut);.}..stat
4d10: 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d 4f 70  ic int tvfsShmOp
4d20: 65 6e 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  en(sqlite3_file 
4d30: 2a 70 46 69 6c 65 29 7b 0a 20 20 54 65 73 74 76  *pFile){.  Testv
4d40: 66 73 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 20  fs *p;.  int rc 
4d50: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
4d60: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
4d70: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 54 65 73  rn code */.  Tes
4d80: 74 76 66 73 42 75 66 66 65 72 20 2a 70 42 75 66  tvfsBuffer *pBuf
4d90: 66 65 72 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  fer;         /* 
4da0: 42 75 66 66 65 72 20 74 6f 20 6f 70 65 6e 20 63  Buffer to open c
4db0: 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 2a 2f 0a  onnection to */.
4dc0: 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64    TestvfsFd *pFd
4dd0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4de0: 20 20 2f 2a 20 54 68 65 20 74 65 73 74 76 66 73    /* The testvfs
4df0: 20 66 69 6c 65 20 73 74 72 75 63 74 75 72 65 20   file structure 
4e00: 2a 2f 0a 0a 20 20 70 46 64 20 3d 20 74 76 66 73  */..  pFd = tvfs
4e10: 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20  GetFd(pFile);.  
4e20: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 70  p = (Testvfs *)p
4e30: 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44 61  Fd->pVfs->pAppDa
4e40: 74 61 3b 0a 20 20 61 73 73 65 72 74 28 20 70 46  ta;.  assert( pF
4e50: 64 2d 3e 70 53 68 6d 49 64 20 26 26 20 70 46 64  d->pShmId && pFd
4e60: 2d 3e 70 53 68 6d 3d 3d 30 20 26 26 20 70 46 64  ->pShm==0 && pFd
4e70: 2d 3e 70 4e 65 78 74 3d 3d 30 20 29 3b 0a 0a 20  ->pNext==0 );.. 
4e80: 20 2f 2a 20 45 76 61 6c 75 61 74 65 20 74 68 65   /* Evaluate the
4e90: 20 54 63 6c 20 73 63 72 69 70 74 3a 20 0a 20 20   Tcl script: .  
4ea0: 2a 2a 0a 20 20 2a 2a 20 20 20 53 43 52 49 50 54  **.  **   SCRIPT
4eb0: 20 78 53 68 6d 4f 70 65 6e 20 46 49 4c 45 4e 41   xShmOpen FILENA
4ec0: 4d 45 0a 20 20 2a 2f 0a 20 20 54 63 6c 5f 52 65  ME.  */.  Tcl_Re
4ed0: 73 65 74 52 65 73 75 6c 74 28 70 2d 3e 69 6e 74  setResult(p->int
4ee0: 65 72 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 70  erp);.  if( p->p
4ef0: 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61 73  Script && p->mas
4f00: 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4f 50 45  k&TESTVFS_SHMOPE
4f10: 4e 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76  N_MASK ){.    tv
4f20: 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53  fsExecTcl(p, "xS
4f30: 68 6d 4f 70 65 6e 22 2c 20 54 63 6c 5f 4e 65 77  hmOpen", Tcl_New
4f40: 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 7a  StringObj(pFd->z
4f50: 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29 2c 20 30  Filename, -1), 0
4f60: 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 74 76  , 0);.    if( tv
4f70: 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c 20  fsResultCode(p, 
4f80: 26 72 63 29 20 29 7b 0a 20 20 20 20 20 20 69 66  &rc) ){.      if
4f90: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
4fa0: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20  ) return rc;.   
4fb0: 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74   }.  }..  assert
4fc0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4fd0: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6d 61 73 6b  );.  if( p->mask
4fe0: 26 54 45 53 54 56 46 53 5f 53 48 4d 4f 50 45 4e  &TESTVFS_SHMOPEN
4ff0: 5f 4d 41 53 4b 20 26 26 20 74 76 66 73 49 6e 6a  _MASK && tvfsInj
5000: 65 63 74 49 6f 65 72 72 28 70 29 20 29 7b 0a 20  ectIoerr(p) ){. 
5010: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
5020: 5f 49 4f 45 52 52 3b 0a 20 20 7d 0a 0a 20 20 2f  _IOERR;.  }..  /
5030: 2a 20 53 65 61 72 63 68 20 66 6f 72 20 61 20 54  * Search for a T
5040: 65 73 74 76 66 73 42 75 66 66 65 72 2e 20 43 72  estvfsBuffer. Cr
5050: 65 61 74 65 20 61 20 6e 65 77 20 6f 6e 65 20 69  eate a new one i
5060: 66 20 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20  f required. */. 
5070: 20 66 6f 72 28 70 42 75 66 66 65 72 3d 70 2d 3e   for(pBuffer=p->
5080: 70 42 75 66 66 65 72 3b 20 70 42 75 66 66 65 72  pBuffer; pBuffer
5090: 3b 20 70 42 75 66 66 65 72 3d 70 42 75 66 66 65  ; pBuffer=pBuffe
50a0: 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  r->pNext){.    i
50b0: 66 28 20 30 3d 3d 73 74 72 63 6d 70 28 70 46 64  f( 0==strcmp(pFd
50c0: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 70 42 75  ->zFilename, pBu
50d0: 66 66 65 72 2d 3e 7a 46 69 6c 65 29 20 29 20 62  ffer->zFile) ) b
50e0: 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20  reak;.  }.  if( 
50f0: 21 70 42 75 66 66 65 72 20 29 7b 0a 20 20 20 20  !pBuffer ){.    
5100: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  int nByte = size
5110: 6f 66 28 54 65 73 74 76 66 73 42 75 66 66 65 72  of(TestvfsBuffer
5120: 29 20 2b 20 73 74 72 6c 65 6e 28 70 46 64 2d 3e  ) + strlen(pFd->
5130: 7a 46 69 6c 65 6e 61 6d 65 29 20 2b 20 31 3b 0a  zFilename) + 1;.
5140: 20 20 20 20 70 42 75 66 66 65 72 20 3d 20 28 54      pBuffer = (T
5150: 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 29 63  estvfsBuffer *)c
5160: 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  kalloc(nByte);. 
5170: 20 20 20 6d 65 6d 73 65 74 28 70 42 75 66 66 65     memset(pBuffe
5180: 72 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20  r, 0, nByte);.  
5190: 20 20 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c 65    pBuffer->zFile
51a0: 20 3d 20 28 63 68 61 72 20 2a 29 26 70 42 75 66   = (char *)&pBuf
51b0: 66 65 72 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63  fer[1];.    strc
51c0: 70 79 28 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c  py(pBuffer->zFil
51d0: 65 2c 20 70 46 64 2d 3e 7a 46 69 6c 65 6e 61 6d  e, pFd->zFilenam
51e0: 65 29 3b 0a 20 20 20 20 70 42 75 66 66 65 72 2d  e);.    pBuffer-
51f0: 3e 70 4e 65 78 74 20 3d 20 70 2d 3e 70 42 75 66  >pNext = p->pBuf
5200: 66 65 72 3b 0a 20 20 20 20 70 2d 3e 70 42 75 66  fer;.    p->pBuf
5210: 66 65 72 20 3d 20 70 42 75 66 66 65 72 3b 0a 20  fer = pBuffer;. 
5220: 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6e 6e 65 63 74   }..  /* Connect
5230: 20 74 68 65 20 54 65 73 74 76 66 73 42 75 66 66   the TestvfsBuff
5240: 65 72 20 74 6f 20 74 68 65 20 6e 65 77 20 54 65  er to the new Te
5250: 73 74 76 66 73 53 68 6d 20 68 61 6e 64 6c 65 20  stvfsShm handle 
5260: 61 6e 64 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20  and return. */. 
5270: 20 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20 70 42   pFd->pNext = pB
5280: 75 66 66 65 72 2d 3e 70 46 69 6c 65 3b 0a 20 20  uffer->pFile;.  
5290: 70 42 75 66 66 65 72 2d 3e 70 46 69 6c 65 20 3d  pBuffer->pFile =
52a0: 20 70 46 64 3b 0a 20 20 70 46 64 2d 3e 70 53 68   pFd;.  pFd->pSh
52b0: 6d 20 3d 20 70 42 75 66 66 65 72 3b 0a 20 20 72  m = pBuffer;.  r
52c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
52d0: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
52e0: 74 76 66 73 41 6c 6c 6f 63 50 61 67 65 28 54 65  tvfsAllocPage(Te
52f0: 73 74 76 66 73 42 75 66 66 65 72 20 2a 70 2c 20  stvfsBuffer *p, 
5300: 69 6e 74 20 69 50 61 67 65 2c 20 69 6e 74 20 70  int iPage, int p
5310: 67 73 7a 29 7b 0a 20 20 61 73 73 65 72 74 28 20  gsz){.  assert( 
5320: 69 50 61 67 65 3c 54 45 53 54 56 46 53 5f 4d 41  iPage<TESTVFS_MA
5330: 58 5f 50 41 47 45 53 20 29 3b 0a 20 20 69 66 28  X_PAGES );.  if(
5340: 20 70 2d 3e 61 50 61 67 65 5b 69 50 61 67 65 5d   p->aPage[iPage]
5350: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 61 50  ==0 ){.    p->aP
5360: 61 67 65 5b 69 50 61 67 65 5d 20 3d 20 28 75 38  age[iPage] = (u8
5370: 20 2a 29 63 6b 61 6c 6c 6f 63 28 70 67 73 7a 29   *)ckalloc(pgsz)
5380: 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 2d 3e  ;.    memset(p->
5390: 61 50 61 67 65 5b 69 50 61 67 65 5d 2c 20 30 2c  aPage[iPage], 0,
53a0: 20 70 67 73 7a 29 3b 0a 20 20 20 20 70 2d 3e 70   pgsz);.    p->p
53b0: 67 73 7a 20 3d 20 70 67 73 7a 3b 0a 20 20 7d 0a  gsz = pgsz;.  }.
53c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 76  }..static int tv
53d0: 66 73 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69  fsShmMap(.  sqli
53e0: 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c  te3_file *pFile,
53f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
5400: 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61  andle open on da
5410: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
5420: 20 69 6e 74 20 69 50 61 67 65 2c 20 20 20 20 20   int iPage,     
5430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5440: 20 2f 2a 20 50 61 67 65 20 74 6f 20 72 65 74 72   /* Page to retr
5450: 69 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20 70 67  ieve */.  int pg
5460: 73 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  sz,             
5470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
5480: 65 20 6f 66 20 70 61 67 65 73 20 2a 2f 0a 20 20  e of pages */.  
5490: 69 6e 74 20 69 73 57 72 69 74 65 2c 20 20 20 20  int isWrite,    
54a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54b0: 2f 2a 20 54 72 75 65 20 74 6f 20 65 78 74 65 6e  /* True to exten
54c0: 64 20 66 69 6c 65 20 69 66 20 6e 65 63 65 73 73  d file if necess
54d0: 61 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f  ary */.  void vo
54e0: 6c 61 74 69 6c 65 20 2a 2a 70 70 20 20 20 20 20  latile **pp     
54f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
5500: 20 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a   Mapped memory *
5510: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
5520: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73  SQLITE_OK;.  Tes
5530: 74 76 66 73 46 64 20 2a 70 46 64 20 3d 20 74 76  tvfsFd *pFd = tv
5540: 66 73 47 65 74 46 64 28 70 46 69 6c 65 29 3b 0a  fsGetFd(pFile);.
5550: 20 20 54 65 73 74 76 66 73 20 2a 70 20 3d 20 28    Testvfs *p = (
5560: 54 65 73 74 76 66 73 20 2a 29 28 70 46 64 2d 3e  Testvfs *)(pFd->
5570: 70 56 66 73 2d 3e 70 41 70 70 44 61 74 61 29 3b  pVfs->pAppData);
5580: 0a 0a 20 20 69 66 28 20 30 3d 3d 70 46 64 2d 3e  ..  if( 0==pFd->
5590: 70 53 68 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d  pShm ){.    rc =
55a0: 20 74 76 66 73 53 68 6d 4f 70 65 6e 28 70 46 69   tvfsShmOpen(pFi
55b0: 6c 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  le);.    if( rc!
55c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
55d0: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
55e0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
55f0: 70 2d 3e 70 53 63 72 69 70 74 20 26 26 20 70 2d  p->pScript && p-
5600: 3e 6d 61 73 6b 26 54 45 53 54 56 46 53 5f 53 48  >mask&TESTVFS_SH
5610: 4d 4d 41 50 5f 4d 41 53 4b 20 29 7b 0a 20 20 20  MMAP_MASK ){.   
5620: 20 54 63 6c 5f 4f 62 6a 20 2a 70 41 72 67 20 3d   Tcl_Obj *pArg =
5630: 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20   Tcl_NewObj();. 
5640: 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f     Tcl_IncrRefCo
5650: 75 6e 74 28 70 41 72 67 29 3b 0a 20 20 20 20 54  unt(pArg);.    T
5660: 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64  cl_ListObjAppend
5670: 45 6c 65 6d 65 6e 74 28 70 2d 3e 69 6e 74 65 72  Element(p->inter
5680: 70 2c 20 70 41 72 67 2c 20 54 63 6c 5f 4e 65 77  p, pArg, Tcl_New
5690: 49 6e 74 4f 62 6a 28 69 50 61 67 65 29 29 3b 0a  IntObj(iPage));.
56a0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
56b0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 70 2d 3e  ppendElement(p->
56c0: 69 6e 74 65 72 70 2c 20 70 41 72 67 2c 20 54 63  interp, pArg, Tc
56d0: 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 67 73 7a  l_NewIntObj(pgsz
56e0: 29 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74  ));.    Tcl_List
56f0: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
5700: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 41 72 67  (p->interp, pArg
5710: 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28  , Tcl_NewIntObj(
5720: 69 73 57 72 69 74 65 29 29 3b 0a 20 20 20 20 74  isWrite));.    t
5730: 76 66 73 45 78 65 63 54 63 6c 28 70 2c 20 22 78  vfsExecTcl(p, "x
5740: 53 68 6d 4d 61 70 22 2c 20 0a 20 20 20 20 20 20  ShmMap", .      
5750: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
5760: 62 6a 28 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46  bj(pFd->pShm->zF
5770: 69 6c 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70  ile, -1), pFd->p
5780: 53 68 6d 49 64 2c 20 70 41 72 67 0a 20 20 20 20  ShmId, pArg.    
5790: 29 3b 0a 20 20 20 20 74 76 66 73 52 65 73 75 6c  );.    tvfsResul
57a0: 74 43 6f 64 65 28 70 2c 20 26 72 63 29 3b 0a 20  tCode(p, &rc);. 
57b0: 20 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f     Tcl_DecrRefCo
57c0: 75 6e 74 28 70 41 72 67 29 3b 0a 20 20 7d 0a 20  unt(pArg);.  }. 
57d0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
57e0: 4f 4b 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45  OK && p->mask&TE
57f0: 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41 53  STVFS_SHMMAP_MAS
5800: 4b 20 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49  K && tvfsInjectI
5810: 6f 65 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72  oerr(p) ){.    r
5820: 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52  c = SQLITE_IOERR
5830: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
5840: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 73  =SQLITE_OK && is
5850: 57 72 69 74 65 20 26 26 20 21 70 46 64 2d 3e 70  Write && !pFd->p
5860: 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50 61 67 65  Shm->aPage[iPage
5870: 5d 20 29 7b 0a 20 20 20 20 74 76 66 73 41 6c 6c  ] ){.    tvfsAll
5880: 6f 63 50 61 67 65 28 70 46 64 2d 3e 70 53 68 6d  ocPage(pFd->pShm
5890: 2c 20 69 50 61 67 65 2c 20 70 67 73 7a 29 3b 0a  , iPage, pgsz);.
58a0: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 28 76 6f 69    }.  *pp = (voi
58b0: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 29 70 46 64  d volatile *)pFd
58c0: 2d 3e 70 53 68 6d 2d 3e 61 50 61 67 65 5b 69 50  ->pShm->aPage[iP
58d0: 61 67 65 5d 3b 0a 0a 20 20 72 65 74 75 72 6e 20  age];..  return 
58e0: 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69  rc;.}...static i
58f0: 6e 74 20 74 76 66 73 53 68 6d 4c 6f 63 6b 28 0a  nt tvfsShmLock(.
5900: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
5910: 70 46 69 6c 65 2c 0a 20 20 69 6e 74 20 6f 66 73  pFile,.  int ofs
5920: 74 2c 0a 20 20 69 6e 74 20 6e 2c 0a 20 20 69 6e  t,.  int n,.  in
5930: 74 20 66 6c 61 67 73 0a 29 7b 0a 20 20 69 6e 74  t flags.){.  int
5940: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
5950: 0a 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46  .  TestvfsFd *pF
5960: 64 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46  d = tvfsGetFd(pF
5970: 69 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20  ile);.  Testvfs 
5980: 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29  *p = (Testvfs *)
5990: 28 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70  (pFd->pVfs->pApp
59a0: 44 61 74 61 29 3b 0a 20 20 69 6e 74 20 6e 4c 6f  Data);.  int nLo
59b0: 63 6b 3b 0a 20 20 63 68 61 72 20 7a 4c 6f 63 6b  ck;.  char zLock
59c0: 5b 38 30 5d 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  [80];..  if( p->
59d0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
59e0: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 4c 4f  sk&TESTVFS_SHMLO
59f0: 43 4b 5f 4d 41 53 4b 20 29 7b 0a 20 20 20 20 73  CK_MASK ){.    s
5a00: 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28  qlite3_snprintf(
5a10: 73 69 7a 65 6f 66 28 7a 4c 6f 63 6b 29 2c 20 7a  sizeof(zLock), z
5a20: 4c 6f 63 6b 2c 20 22 25 64 20 25 64 22 2c 20 6f  Lock, "%d %d", o
5a30: 66 73 74 2c 20 6e 29 3b 0a 20 20 20 20 6e 4c 6f  fst, n);.    nLo
5a40: 63 6b 20 3d 20 73 74 72 6c 65 6e 28 7a 4c 6f 63  ck = strlen(zLoc
5a50: 6b 29 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67  k);.    if( flag
5a60: 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c  s & SQLITE_SHM_L
5a70: 4f 43 4b 20 29 7b 0a 20 20 20 20 20 20 73 74 72  OCK ){.      str
5a80: 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b  cpy(&zLock[nLock
5a90: 5d 2c 20 22 20 6c 6f 63 6b 22 29 3b 0a 20 20 20  ], " lock");.   
5aa0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 74   }else{.      st
5ab0: 72 63 70 79 28 26 7a 4c 6f 63 6b 5b 6e 4c 6f 63  rcpy(&zLock[nLoc
5ac0: 6b 5d 2c 20 22 20 75 6e 6c 6f 63 6b 22 29 3b 0a  k], " unlock");.
5ad0: 20 20 20 20 7d 0a 20 20 20 20 6e 4c 6f 63 6b 20      }.    nLock 
5ae0: 2b 3d 20 73 74 72 6c 65 6e 28 26 7a 4c 6f 63 6b  += strlen(&zLock
5af0: 5b 6e 4c 6f 63 6b 5d 29 3b 0a 20 20 20 20 69 66  [nLock]);.    if
5b00: 28 20 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45  ( flags & SQLITE
5b10: 5f 53 48 4d 5f 53 48 41 52 45 44 20 29 7b 0a 20  _SHM_SHARED ){. 
5b20: 20 20 20 20 20 73 74 72 63 70 79 28 26 7a 4c 6f       strcpy(&zLo
5b30: 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20 73 68 61  ck[nLock], " sha
5b40: 72 65 64 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65  red");.    }else
5b50: 7b 0a 20 20 20 20 20 20 73 74 72 63 70 79 28 26  {.      strcpy(&
5b60: 7a 4c 6f 63 6b 5b 6e 4c 6f 63 6b 5d 2c 20 22 20  zLock[nLock], " 
5b70: 65 78 63 6c 75 73 69 76 65 22 29 3b 0a 20 20 20  exclusive");.   
5b80: 20 7d 0a 20 20 20 20 74 76 66 73 45 78 65 63 54   }.    tvfsExecT
5b90: 63 6c 28 70 2c 20 22 78 53 68 6d 4c 6f 63 6b 22  cl(p, "xShmLock"
5ba0: 2c 20 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e  , .        Tcl_N
5bb0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d  ewStringObj(pFd-
5bc0: 3e 70 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31  >pShm->zFile, -1
5bd0: 29 2c 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 0a  ), pFd->pShmId,.
5be0: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
5bf0: 74 72 69 6e 67 4f 62 6a 28 7a 4c 6f 63 6b 2c 20  tringObj(zLock, 
5c00: 2d 31 29 0a 20 20 20 20 29 3b 0a 20 20 20 20 74  -1).    );.    t
5c10: 76 66 73 52 65 73 75 6c 74 43 6f 64 65 28 70 2c  vfsResultCode(p,
5c20: 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 69 66   &rc);.  }..  if
5c30: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5c40: 26 26 20 70 2d 3e 6d 61 73 6b 26 54 45 53 54 56  && p->mask&TESTV
5c50: 46 53 5f 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20  FS_SHMLOCK_MASK 
5c60: 26 26 20 74 76 66 73 49 6e 6a 65 63 74 49 6f 65  && tvfsInjectIoe
5c70: 72 72 28 70 29 20 29 7b 0a 20 20 20 20 72 63 20  rr(p) ){.    rc 
5c80: 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b 0a  = SQLITE_IOERR;.
5c90: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
5ca0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5cb0: 69 6e 74 20 69 73 4c 6f 63 6b 20 3d 20 28 66 6c  int isLock = (fl
5cc0: 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53 48 4d  ags & SQLITE_SHM
5cd0: 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 69 6e 74 20  _LOCK);.    int 
5ce0: 69 73 45 78 63 6c 20 3d 20 28 66 6c 61 67 73 20  isExcl = (flags 
5cf0: 26 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43  & SQLITE_SHM_EXC
5d00: 4c 55 53 49 56 45 29 3b 0a 20 20 20 20 75 33 32  LUSIVE);.    u32
5d10: 20 6d 61 73 6b 20 3d 20 28 28 28 31 3c 3c 6e 29   mask = (((1<<n)
5d20: 2d 31 29 20 3c 3c 20 6f 66 73 74 29 3b 0a 20 20  -1) << ofst);.  
5d30: 20 20 69 66 28 20 69 73 4c 6f 63 6b 20 29 7b 0a    if( isLock ){.
5d40: 20 20 20 20 20 20 54 65 73 74 76 66 73 46 64 20        TestvfsFd 
5d50: 2a 70 32 3b 0a 20 20 20 20 20 20 66 6f 72 28 70  *p2;.      for(p
5d60: 32 3d 70 46 64 2d 3e 70 53 68 6d 2d 3e 70 46 69  2=pFd->pShm->pFi
5d70: 6c 65 3b 20 70 32 3b 20 70 32 3d 70 32 2d 3e 70  le; p2; p2=p2->p
5d80: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 20 20 69  Next){.        i
5d90: 66 28 20 70 32 3d 3d 70 46 64 20 29 20 63 6f 6e  f( p2==pFd ) con
5da0: 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 69  tinue;.        i
5db0: 66 28 20 28 70 32 2d 3e 65 78 63 6c 6c 6f 63 6b  f( (p2->excllock
5dc0: 26 6d 61 73 6b 29 20 7c 7c 20 28 69 73 45 78 63  &mask) || (isExc
5dd0: 6c 20 26 26 20 70 32 2d 3e 73 68 61 72 65 64 6c  l && p2->sharedl
5de0: 6f 63 6b 26 6d 61 73 6b 29 20 29 7b 0a 20 20 20  ock&mask) ){.   
5df0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
5e00: 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 20 20 20  TE_BUSY;.       
5e10: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
5e20: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
5e30: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
5e40: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
5e50: 66 28 20 69 73 45 78 63 6c 20 29 20 20 70 46 64  f( isExcl )  pFd
5e60: 2d 3e 65 78 63 6c 6c 6f 63 6b 20 7c 3d 20 6d 61  ->excllock |= ma
5e70: 73 6b 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  sk;.        if( 
5e80: 21 69 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73  !isExcl ) pFd->s
5e90: 68 61 72 65 64 6c 6f 63 6b 20 7c 3d 20 6d 61 73  haredlock |= mas
5ea0: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
5eb0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
5ec0: 69 73 45 78 63 6c 20 29 20 20 70 46 64 2d 3e 65  isExcl )  pFd->e
5ed0: 78 63 6c 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73  xcllock &= (~mas
5ee0: 6b 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69  k);.      if( !i
5ef0: 73 45 78 63 6c 20 29 20 70 46 64 2d 3e 73 68 61  sExcl ) pFd->sha
5f00: 72 65 64 6c 6f 63 6b 20 26 3d 20 28 7e 6d 61 73  redlock &= (~mas
5f10: 6b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  k);.    }.  }.. 
5f20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
5f30: 74 61 74 69 63 20 76 6f 69 64 20 74 76 66 73 53  tatic void tvfsS
5f40: 68 6d 42 61 72 72 69 65 72 28 73 71 6c 69 74 65  hmBarrier(sqlite
5f50: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
5f60: 20 20 54 65 73 74 76 66 73 46 64 20 2a 70 46 64    TestvfsFd *pFd
5f70: 20 3d 20 74 76 66 73 47 65 74 46 64 28 70 46 69   = tvfsGetFd(pFi
5f80: 6c 65 29 3b 0a 20 20 54 65 73 74 76 66 73 20 2a  le);.  Testvfs *
5f90: 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 28  p = (Testvfs *)(
5fa0: 70 46 64 2d 3e 70 56 66 73 2d 3e 70 41 70 70 44  pFd->pVfs->pAppD
5fb0: 61 74 61 29 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  ata);..  if( p->
5fc0: 70 53 63 72 69 70 74 20 26 26 20 70 2d 3e 6d 61  pScript && p->ma
5fd0: 73 6b 26 54 45 53 54 56 46 53 5f 53 48 4d 42 41  sk&TESTVFS_SHMBA
5fe0: 52 52 49 45 52 5f 4d 41 53 4b 20 29 7b 0a 20 20  RRIER_MASK ){.  
5ff0: 20 20 74 76 66 73 45 78 65 63 54 63 6c 28 70 2c    tvfsExecTcl(p,
6000: 20 22 78 53 68 6d 42 61 72 72 69 65 72 22 2c 20   "xShmBarrier", 
6010: 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77  .        Tcl_New
6020: 53 74 72 69 6e 67 4f 62 6a 28 70 46 64 2d 3e 70  StringObj(pFd->p
6030: 53 68 6d 2d 3e 7a 46 69 6c 65 2c 20 2d 31 29 2c  Shm->zFile, -1),
6040: 20 70 46 64 2d 3e 70 53 68 6d 49 64 2c 20 30 0a   pFd->pShmId, 0.
6050: 20 20 20 20 29 3b 0a 20 20 7d 0a 7d 0a 0a 73 74      );.  }.}..st
6060: 61 74 69 63 20 69 6e 74 20 74 76 66 73 53 68 6d  atic int tvfsShm
6070: 55 6e 6d 61 70 28 0a 20 20 73 71 6c 69 74 65 33  Unmap(.  sqlite3
6080: 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20  _file *pFile,.  
6090: 69 6e 74 20 64 65 6c 65 74 65 46 6c 61 67 0a 29  int deleteFlag.)
60a0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
60b0: 49 54 45 5f 4f 4b 3b 0a 20 20 54 65 73 74 76 66  ITE_OK;.  Testvf
60c0: 73 46 64 20 2a 70 46 64 20 3d 20 74 76 66 73 47  sFd *pFd = tvfsG
60d0: 65 74 46 64 28 70 46 69 6c 65 29 3b 0a 20 20 54  etFd(pFile);.  T
60e0: 65 73 74 76 66 73 20 2a 70 20 3d 20 28 54 65 73  estvfs *p = (Tes
60f0: 74 76 66 73 20 2a 29 28 70 46 64 2d 3e 70 56 66  tvfs *)(pFd->pVf
6100: 73 2d 3e 70 41 70 70 44 61 74 61 29 3b 0a 20 20  s->pAppData);.  
6110: 54 65 73 74 76 66 73 42 75 66 66 65 72 20 2a 70  TestvfsBuffer *p
6120: 42 75 66 66 65 72 20 3d 20 70 46 64 2d 3e 70 53  Buffer = pFd->pS
6130: 68 6d 3b 0a 20 20 54 65 73 74 76 66 73 46 64 20  hm;.  TestvfsFd 
6140: 2a 2a 70 70 46 64 3b 0a 0a 20 20 69 66 28 20 21  **ppFd;..  if( !
6150: 70 42 75 66 66 65 72 20 29 20 72 65 74 75 72 6e  pBuffer ) return
6160: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61 73   SQLITE_OK;.  as
6170: 73 65 72 74 28 20 70 46 64 2d 3e 70 53 68 6d 49  sert( pFd->pShmI
6180: 64 20 26 26 20 70 46 64 2d 3e 70 53 68 6d 20 29  d && pFd->pShm )
6190: 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72  ;..  if( p->pScr
61a0: 69 70 74 20 26 26 20 70 2d 3e 6d 61 73 6b 26 54  ipt && p->mask&T
61b0: 45 53 54 56 46 53 5f 53 48 4d 43 4c 4f 53 45 5f  ESTVFS_SHMCLOSE_
61c0: 4d 41 53 4b 20 29 7b 0a 20 20 20 20 74 76 66 73  MASK ){.    tvfs
61d0: 45 78 65 63 54 63 6c 28 70 2c 20 22 78 53 68 6d  ExecTcl(p, "xShm
61e0: 55 6e 6d 61 70 22 2c 20 0a 20 20 20 20 20 20 20  Unmap", .       
61f0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
6200: 6a 28 70 46 64 2d 3e 70 53 68 6d 2d 3e 7a 46 69  j(pFd->pShm->zFi
6210: 6c 65 2c 20 2d 31 29 2c 20 70 46 64 2d 3e 70 53  le, -1), pFd->pS
6220: 68 6d 49 64 2c 20 30 0a 20 20 20 20 29 3b 0a 20  hmId, 0.    );. 
6230: 20 20 20 74 76 66 73 52 65 73 75 6c 74 43 6f 64     tvfsResultCod
6240: 65 28 70 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  e(p, &rc);.  }..
6250: 20 20 66 6f 72 28 70 70 46 64 3d 26 70 42 75 66    for(ppFd=&pBuf
6260: 66 65 72 2d 3e 70 46 69 6c 65 3b 20 2a 70 70 46  fer->pFile; *ppF
6270: 64 21 3d 70 46 64 3b 20 70 70 46 64 3d 26 28 28  d!=pFd; ppFd=&((
6280: 2a 70 70 46 64 29 2d 3e 70 4e 65 78 74 29 29 3b  *ppFd)->pNext));
6290: 0a 20 20 61 73 73 65 72 74 28 20 28 2a 70 70 46  .  assert( (*ppF
62a0: 64 29 3d 3d 70 46 64 20 29 3b 0a 20 20 2a 70 70  d)==pFd );.  *pp
62b0: 46 64 20 3d 20 70 46 64 2d 3e 70 4e 65 78 74 3b  Fd = pFd->pNext;
62c0: 0a 20 20 70 46 64 2d 3e 70 4e 65 78 74 20 3d 20  .  pFd->pNext = 
62d0: 30 3b 0a 0a 20 20 69 66 28 20 70 42 75 66 66 65  0;..  if( pBuffe
62e0: 72 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  r->pFile==0 ){. 
62f0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 54 65     int i;.    Te
6300: 73 74 76 66 73 42 75 66 66 65 72 20 2a 2a 70 70  stvfsBuffer **pp
6310: 3b 0a 20 20 20 20 66 6f 72 28 70 70 3d 26 70 2d  ;.    for(pp=&p-
6320: 3e 70 42 75 66 66 65 72 3b 20 2a 70 70 21 3d 70  >pBuffer; *pp!=p
6330: 42 75 66 66 65 72 3b 20 70 70 3d 26 28 28 2a 70  Buffer; pp=&((*p
6340: 70 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20  p)->pNext));.   
6350: 20 2a 70 70 20 3d 20 28 2a 70 70 29 2d 3e 70 4e   *pp = (*pp)->pN
6360: 65 78 74 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  ext;.    for(i=0
6370: 3b 20 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65  ; pBuffer->aPage
6380: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  [i]; i++){.     
6390: 20 63 6b 66 72 65 65 28 28 63 68 61 72 20 2a 29   ckfree((char *)
63a0: 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65 5b 69  pBuffer->aPage[i
63b0: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 6b  ]);.    }.    ck
63c0: 66 72 65 65 28 28 63 68 61 72 20 2a 29 70 42 75  free((char *)pBu
63d0: 66 66 65 72 29 3b 0a 20 20 7d 0a 20 20 70 46 64  ffer);.  }.  pFd
63e0: 2d 3e 70 53 68 6d 20 3d 20 30 3b 0a 0a 20 20 72  ->pShm = 0;..  r
63f0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
6400: 74 69 63 20 69 6e 74 20 74 65 73 74 76 66 73 5f  tic int testvfs_
6410: 6f 62 6a 5f 63 6d 64 28 0a 20 20 43 6c 69 65 6e  obj_cmd(.  Clien
6420: 74 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c 5f  tData cd,.  Tcl_
6430: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
6440: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
6450: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
6460: 76 5b 5d 0a 29 7b 0a 20 20 54 65 73 74 76 66 73  v[].){.  Testvfs
6470: 20 2a 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a   *p = (Testvfs *
6480: 29 63 64 3b 0a 0a 20 20 65 6e 75 6d 20 44 42 5f  )cd;..  enum DB_
6490: 65 6e 75 6d 20 7b 20 0a 20 20 20 20 43 4d 44 5f  enum { .    CMD_
64a0: 53 48 4d 2c 20 43 4d 44 5f 44 45 4c 45 54 45 2c  SHM, CMD_DELETE,
64b0: 20 43 4d 44 5f 46 49 4c 54 45 52 2c 20 43 4d 44   CMD_FILTER, CMD
64c0: 5f 49 4f 45 52 52 2c 20 43 4d 44 5f 53 43 52 49  _IOERR, CMD_SCRI
64d0: 50 54 2c 20 0a 20 20 20 20 43 4d 44 5f 44 45 56  PT, .    CMD_DEV
64e0: 43 48 41 52 2c 20 43 4d 44 5f 53 45 43 54 4f 52  CHAR, CMD_SECTOR
64f0: 53 49 5a 45 2c 20 43 4d 44 5f 46 55 4c 4c 45 52  SIZE, CMD_FULLER
6500: 52 2c 20 43 4d 44 5f 43 41 4e 54 4f 50 45 4e 45  R, CMD_CANTOPENE
6510: 52 52 0a 20 20 7d 3b 0a 20 20 73 74 72 75 63 74  RR.  };.  struct
6520: 20 54 65 73 74 76 66 73 53 75 62 63 6d 64 20 7b   TestvfsSubcmd {
6530: 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  .    char *zName
6540: 3b 0a 20 20 20 20 65 6e 75 6d 20 44 42 5f 65 6e  ;.    enum DB_en
6550: 75 6d 20 65 43 6d 64 3b 0a 20 20 7d 20 61 53 75  um eCmd;.  } aSu
6560: 62 63 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b  bcmd[] = {.    {
6570: 20 22 73 68 6d 22 2c 20 20 20 20 20 20 20 20 20   "shm",         
6580: 43 4d 44 5f 53 48 4d 20 20 20 20 20 20 20 20 20  CMD_SHM         
6590: 7d 2c 0a 20 20 20 20 7b 20 22 64 65 6c 65 74 65  },.    { "delete
65a0: 22 2c 20 20 20 20 20 20 43 4d 44 5f 44 45 4c 45  ",      CMD_DELE
65b0: 54 45 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  TE      },.    {
65c0: 20 22 66 69 6c 74 65 72 22 2c 20 20 20 20 20 20   "filter",      
65d0: 43 4d 44 5f 46 49 4c 54 45 52 20 20 20 20 20 20  CMD_FILTER      
65e0: 7d 2c 0a 20 20 20 20 7b 20 22 69 6f 65 72 72 22  },.    { "ioerr"
65f0: 2c 20 20 20 20 20 20 20 43 4d 44 5f 49 4f 45 52  ,       CMD_IOER
6600: 52 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  R       },.    {
6610: 20 22 66 75 6c 6c 65 72 72 22 2c 20 20 20 20 20   "fullerr",     
6620: 43 4d 44 5f 46 55 4c 4c 45 52 52 20 20 20 20 20  CMD_FULLERR     
6630: 7d 2c 0a 20 20 20 20 7b 20 22 63 61 6e 74 6f 70  },.    { "cantop
6640: 65 6e 65 72 72 22 2c 20 43 4d 44 5f 43 41 4e 54  enerr", CMD_CANT
6650: 4f 50 45 4e 45 52 52 20 7d 2c 0a 20 20 20 20 7b  OPENERR },.    {
6660: 20 22 73 63 72 69 70 74 22 2c 20 20 20 20 20 20   "script",      
6670: 43 4d 44 5f 53 43 52 49 50 54 20 20 20 20 20 20  CMD_SCRIPT      
6680: 7d 2c 0a 20 20 20 20 7b 20 22 64 65 76 63 68 61  },.    { "devcha
6690: 72 22 2c 20 20 20 20 20 43 4d 44 5f 44 45 56 43  r",     CMD_DEVC
66a0: 48 41 52 20 20 20 20 20 7d 2c 0a 20 20 20 20 7b  HAR     },.    {
66b0: 20 22 73 65 63 74 6f 72 73 69 7a 65 22 2c 20 20   "sectorsize",  
66c0: 43 4d 44 5f 53 45 43 54 4f 52 53 49 5a 45 20 20  CMD_SECTORSIZE  
66d0: 7d 2c 0a 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a  },.    { 0, 0 }.
66e0: 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20    };.  int i;.  
66f0: 0a 20 20 69 66 28 20 6f 62 6a 63 3c 32 20 29 7b  .  if( objc<2 ){
6700: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
6710: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
6720: 20 6f 62 6a 76 2c 20 22 53 55 42 43 4f 4d 4d 41   objv, "SUBCOMMA
6730: 4e 44 20 2e 2e 2e 22 29 3b 0a 20 20 20 20 72 65  ND ...");.    re
6740: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
6750: 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65    }.  if( Tcl_Ge
6760: 74 49 6e 64 65 78 46 72 6f 6d 4f 62 6a 53 74 72  tIndexFromObjStr
6770: 75 63 74 28 0a 20 20 20 20 20 20 20 20 69 6e 74  uct(.        int
6780: 65 72 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 61 53  erp, objv[1], aS
6790: 75 62 63 6d 64 2c 20 73 69 7a 65 6f 66 28 61 53  ubcmd, sizeof(aS
67a0: 75 62 63 6d 64 5b 30 5d 29 2c 20 22 73 75 62 63  ubcmd[0]), "subc
67b0: 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69 29 20  ommand", 0, &i) 
67c0: 0a 20 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  .  ){.    return
67d0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
67e0: 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c    Tcl_ResetResul
67f0: 74 28 69 6e 74 65 72 70 29 3b 0a 0a 20 20 73 77  t(interp);..  sw
6800: 69 74 63 68 28 20 61 53 75 62 63 6d 64 5b 69 5d  itch( aSubcmd[i]
6810: 2e 65 43 6d 64 20 29 7b 0a 20 20 20 20 63 61 73  .eCmd ){.    cas
6820: 65 20 43 4d 44 5f 53 48 4d 3a 20 7b 0a 20 20 20  e CMD_SHM: {.   
6830: 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4f 62 6a     Tcl_Obj *pObj
6840: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20  ;.      int i;. 
6850: 20 20 20 20 20 54 65 73 74 76 66 73 42 75 66 66       TestvfsBuff
6860: 65 72 20 2a 70 42 75 66 66 65 72 3b 0a 20 20 20  er *pBuffer;.   
6870: 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a     char *zName;.
6880: 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 21 3d        if( objc!=
6890: 33 20 26 26 20 6f 62 6a 63 21 3d 34 20 29 7b 0a  3 && objc!=4 ){.
68a0: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
68b0: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
68c0: 20 32 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45 20   2, objv, "FILE 
68d0: 3f 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20  ?VALUE?");.     
68e0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
68f0: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
6900: 20 20 20 7a 4e 61 6d 65 20 3d 20 63 6b 61 6c 6c     zName = ckall
6910: 6f 63 28 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d  oc(p->pParent->m
6920: 78 50 61 74 68 6e 61 6d 65 29 3b 0a 20 20 20 20  xPathname);.    
6930: 20 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 78 46    p->pParent->xF
6940: 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20 20 20  ullPathname(.   
6950: 20 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e         p->pParen
6960: 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  t, Tcl_GetString
6970: 28 6f 62 6a 76 5b 32 5d 29 2c 20 0a 20 20 20 20  (objv[2]), .    
6980: 20 20 20 20 20 20 70 2d 3e 70 50 61 72 65 6e 74        p->pParent
6990: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 2c 20 7a 4e  ->mxPathname, zN
69a0: 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ame.      );.   
69b0: 20 20 20 66 6f 72 28 70 42 75 66 66 65 72 3d 70     for(pBuffer=p
69c0: 2d 3e 70 42 75 66 66 65 72 3b 20 70 42 75 66 66  ->pBuffer; pBuff
69d0: 65 72 3b 20 70 42 75 66 66 65 72 3d 70 42 75 66  er; pBuffer=pBuf
69e0: 66 65 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  fer->pNext){.   
69f0: 20 20 20 20 20 69 66 28 20 30 3d 3d 73 74 72 63       if( 0==strc
6a00: 6d 70 28 70 42 75 66 66 65 72 2d 3e 7a 46 69 6c  mp(pBuffer->zFil
6a10: 65 2c 20 7a 4e 61 6d 65 29 20 29 20 62 72 65 61  e, zName) ) brea
6a20: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  k;.      }.     
6a30: 20 63 6b 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a   ckfree(zName);.
6a40: 20 20 20 20 20 20 69 66 28 20 21 70 42 75 66 66        if( !pBuff
6a50: 65 72 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63  er ){.        Tc
6a60: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
6a70: 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68 20  nterp, "no such 
6a80: 66 69 6c 65 3a 20 22 2c 20 54 63 6c 5f 47 65 74  file: ", Tcl_Get
6a90: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c  String(objv[2]),
6aa0: 20 30 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74   0);.        ret
6ab0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
6ac0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
6ad0: 20 6f 62 6a 63 3d 3d 34 20 29 7b 0a 20 20 20 20   objc==4 ){.    
6ae0: 20 20 20 20 69 6e 74 20 6e 3b 0a 20 20 20 20 20      int n;.     
6af0: 20 20 20 75 38 20 2a 61 20 3d 20 54 63 6c 5f 47     u8 *a = Tcl_G
6b00: 65 74 42 79 74 65 41 72 72 61 79 46 72 6f 6d 4f  etByteArrayFromO
6b10: 62 6a 28 6f 62 6a 76 5b 33 5d 2c 20 26 6e 29 3b  bj(objv[3], &n);
6b20: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 70 67 73  .        int pgs
6b30: 7a 20 3d 20 70 42 75 66 66 65 72 2d 3e 70 67 73  z = pBuffer->pgs
6b40: 7a 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  z;.        if( p
6b50: 67 73 7a 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20  gsz==0 ) pgsz = 
6b60: 36 35 35 33 36 3b 0a 20 20 20 20 20 20 20 20 66  65536;.        f
6b70: 6f 72 28 69 3d 30 3b 20 69 2a 70 67 73 7a 3c 6e  or(i=0; i*pgsz<n
6b80: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
6b90: 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 70 67    int nByte = pg
6ba0: 73 7a 3b 0a 20 20 20 20 20 20 20 20 20 20 74 76  sz;.          tv
6bb0: 66 73 41 6c 6c 6f 63 50 61 67 65 28 70 42 75 66  fsAllocPage(pBuf
6bc0: 66 65 72 2c 20 69 2c 20 70 67 73 7a 29 3b 0a 20  fer, i, pgsz);. 
6bd0: 20 20 20 20 20 20 20 20 20 69 66 28 20 6e 2d 69           if( n-i
6be0: 2a 70 67 73 7a 3c 70 67 73 7a 20 29 7b 0a 20 20  *pgsz<pgsz ){.  
6bf0: 20 20 20 20 20 20 20 20 20 20 6e 42 79 74 65 20            nByte 
6c00: 3d 20 6e 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = n;.          }
6c10: 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
6c20: 79 28 70 42 75 66 66 65 72 2d 3e 61 50 61 67 65  y(pBuffer->aPage
6c30: 5b 69 5d 2c 20 26 61 5b 69 2a 70 67 73 7a 5d 2c  [i], &a[i*pgsz],
6c40: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 20   nByte);.       
6c50: 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20   }.      }..    
6c60: 20 20 70 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77    pObj = Tcl_New
6c70: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 66 6f 72  Obj();.      for
6c80: 28 69 3d 30 3b 20 70 42 75 66 66 65 72 2d 3e 61  (i=0; pBuffer->a
6c90: 50 61 67 65 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  Page[i]; i++){. 
6ca0: 20 20 20 20 20 20 20 69 6e 74 20 70 67 73 7a 20         int pgsz 
6cb0: 3d 20 70 42 75 66 66 65 72 2d 3e 70 67 73 7a 3b  = pBuffer->pgsz;
6cc0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 67 73  .        if( pgs
6cd0: 7a 3d 3d 30 20 29 20 70 67 73 7a 20 3d 20 36 35  z==0 ) pgsz = 65
6ce0: 35 33 36 3b 0a 20 20 20 20 20 20 20 20 54 63 6c  536;.        Tcl
6cf0: 5f 41 70 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28  _AppendObjToObj(
6d00: 70 4f 62 6a 2c 20 54 63 6c 5f 4e 65 77 42 79 74  pObj, Tcl_NewByt
6d10: 65 41 72 72 61 79 4f 62 6a 28 70 42 75 66 66 65  eArrayObj(pBuffe
6d20: 72 2d 3e 61 50 61 67 65 5b 69 5d 2c 20 70 67 73  r->aPage[i], pgs
6d30: 7a 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  z));.      }.   
6d40: 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73     Tcl_SetObjRes
6d50: 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 4f 62 6a  ult(interp, pObj
6d60: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
6d70: 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20      }..    case 
6d80: 43 4d 44 5f 46 49 4c 54 45 52 3a 20 7b 0a 20 20  CMD_FILTER: {.  
6d90: 20 20 20 20 73 74 61 74 69 63 20 73 74 72 75 63      static struc
6da0: 74 20 56 66 73 4d 65 74 68 6f 64 20 7b 0a 20 20  t VfsMethod {.  
6db0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d        char *zNam
6dc0: 65 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6d  e;.        int m
6dd0: 61 73 6b 3b 0a 20 20 20 20 20 20 7d 20 76 66 73  ask;.      } vfs
6de0: 6d 65 74 68 6f 64 20 5b 5d 20 3d 20 7b 0a 20 20  method [] = {.  
6df0: 20 20 20 20 20 20 7b 20 22 78 53 68 6d 4f 70 65        { "xShmOpe
6e00: 6e 22 2c 20 20 20 20 54 45 53 54 56 46 53 5f 53  n",    TESTVFS_S
6e10: 48 4d 4f 50 45 4e 5f 4d 41 53 4b 20 7d 2c 0a 20  HMOPEN_MASK },. 
6e20: 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 4c 6f         { "xShmLo
6e30: 63 6b 22 2c 20 20 20 20 54 45 53 54 56 46 53 5f  ck",    TESTVFS_
6e40: 53 48 4d 4c 4f 43 4b 5f 4d 41 53 4b 20 7d 2c 0a  SHMLOCK_MASK },.
6e50: 20 20 20 20 20 20 20 20 7b 20 22 78 53 68 6d 42          { "xShmB
6e60: 61 72 72 69 65 72 22 2c 20 54 45 53 54 56 46 53  arrier", TESTVFS
6e70: 5f 53 48 4d 42 41 52 52 49 45 52 5f 4d 41 53 4b  _SHMBARRIER_MASK
6e80: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
6e90: 53 68 6d 55 6e 6d 61 70 22 2c 20 20 20 54 45 53  ShmUnmap",   TES
6ea0: 54 56 46 53 5f 53 48 4d 43 4c 4f 53 45 5f 4d 41  TVFS_SHMCLOSE_MA
6eb0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
6ec0: 22 78 53 68 6d 4d 61 70 22 2c 20 20 20 20 20 54  "xShmMap",     T
6ed0: 45 53 54 56 46 53 5f 53 48 4d 4d 41 50 5f 4d 41  ESTVFS_SHMMAP_MA
6ee0: 53 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  SK },.        { 
6ef0: 22 78 53 79 6e 63 22 2c 20 20 20 20 20 20 20 54  "xSync",       T
6f00: 45 53 54 56 46 53 5f 53 59 4e 43 5f 4d 41 53 4b  ESTVFS_SYNC_MASK
6f10: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
6f20: 44 65 6c 65 74 65 22 2c 20 20 20 20 20 54 45 53  Delete",     TES
6f30: 54 56 46 53 5f 44 45 4c 45 54 45 5f 4d 41 53 4b  TVFS_DELETE_MASK
6f40: 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78   },.        { "x
6f50: 57 72 69 74 65 22 2c 20 20 20 20 20 20 54 45 53  Write",      TES
6f60: 54 56 46 53 5f 57 52 49 54 45 5f 4d 41 53 4b 20  TVFS_WRITE_MASK 
6f70: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 54  },.        { "xT
6f80: 72 75 6e 63 61 74 65 22 2c 20 20 20 54 45 53 54  runcate",   TEST
6f90: 56 46 53 5f 54 52 55 4e 43 41 54 45 5f 4d 41 53  VFS_TRUNCATE_MAS
6fa0: 4b 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  K },.        { "
6fb0: 78 4f 70 65 6e 22 2c 20 20 20 20 20 20 20 54 45  xOpen",       TE
6fc0: 53 54 56 46 53 5f 4f 50 45 4e 5f 4d 41 53 4b 20  STVFS_OPEN_MASK 
6fd0: 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 43  },.        { "xC
6fe0: 6c 6f 73 65 22 2c 20 20 20 20 20 20 54 45 53 54  lose",      TEST
6ff0: 56 46 53 5f 43 4c 4f 53 45 5f 4d 41 53 4b 20 7d  VFS_CLOSE_MASK }
7000: 2c 0a 20 20 20 20 20 20 20 20 7b 20 22 78 41 63  ,.        { "xAc
7010: 63 65 73 73 22 2c 20 20 20 20 20 54 45 53 54 56  cess",     TESTV
7020: 46 53 5f 41 43 43 45 53 53 5f 4d 41 53 4b 20 7d  FS_ACCESS_MASK }
7030: 2c 0a 20 20 20 20 20 20 7d 3b 0a 20 20 20 20 20  ,.      };.     
7040: 20 54 63 6c 5f 4f 62 6a 20 2a 2a 61 70 45 6c 65   Tcl_Obj **apEle
7050: 6d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 6e 74  m = 0;.      int
7060: 20 6e 45 6c 65 6d 20 3d 20 30 3b 0a 20 20 20 20   nElem = 0;.    
7070: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 69    int i;.      i
7080: 6e 74 20 6d 61 73 6b 20 3d 20 30 3b 0a 20 20 20  nt mask = 0;.   
7090: 20 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29     if( objc!=3 )
70a0: 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72  {.        Tcl_Wr
70b0: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
70c0: 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 4c 49 53  p, 2, objv, "LIS
70d0: 54 22 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  T");.        ret
70e0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
70f0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
7100: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45   Tcl_ListObjGetE
7110: 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20  lements(interp, 
7120: 6f 62 6a 76 5b 32 5d 2c 20 26 6e 45 6c 65 6d 2c  objv[2], &nElem,
7130: 20 26 61 70 45 6c 65 6d 29 20 29 7b 0a 20 20 20   &apElem) ){.   
7140: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
7150: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
7160: 20 20 20 20 20 54 63 6c 5f 52 65 73 65 74 52 65       Tcl_ResetRe
7170: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20 20  sult(interp);.  
7180: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
7190: 45 6c 65 6d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Elem; i++){.    
71a0: 20 20 20 20 69 6e 74 20 69 4d 65 74 68 6f 64 3b      int iMethod;
71b0: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a  .        char *z
71c0: 45 6c 65 6d 20 3d 20 54 63 6c 5f 47 65 74 53 74  Elem = Tcl_GetSt
71d0: 72 69 6e 67 28 61 70 45 6c 65 6d 5b 69 5d 29 3b  ring(apElem[i]);
71e0: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 4d 65  .        for(iMe
71f0: 74 68 6f 64 3d 30 3b 20 69 4d 65 74 68 6f 64 3c  thod=0; iMethod<
7200: 41 72 72 61 79 53 69 7a 65 28 76 66 73 6d 65 74  ArraySize(vfsmet
7210: 68 6f 64 29 3b 20 69 4d 65 74 68 6f 64 2b 2b 29  hod); iMethod++)
7220: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
7230: 73 74 72 63 6d 70 28 7a 45 6c 65 6d 2c 20 76 66  strcmp(zElem, vf
7240: 73 6d 65 74 68 6f 64 5b 69 4d 65 74 68 6f 64 5d  smethod[iMethod]
7250: 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20  .zName)==0 ){.  
7260: 20 20 20 20 20 20 20 20 20 20 6d 61 73 6b 20 7c            mask |
7270: 3d 20 76 66 73 6d 65 74 68 6f 64 5b 69 4d 65 74  = vfsmethod[iMet
7280: 68 6f 64 5d 2e 6d 61 73 6b 3b 0a 20 20 20 20 20  hod].mask;.     
7290: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
72a0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
72b0: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20    }.        if( 
72c0: 69 4d 65 74 68 6f 64 3d 3d 41 72 72 61 79 53 69  iMethod==ArraySi
72d0: 7a 65 28 76 66 73 6d 65 74 68 6f 64 29 20 29 7b  ze(vfsmethod) ){
72e0: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 41  .          Tcl_A
72f0: 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65  ppendResult(inte
7300: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 20 6d 65 74  rp, "unknown met
7310: 68 6f 64 3a 20 22 2c 20 7a 45 6c 65 6d 2c 20 30  hod: ", zElem, 0
7320: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74  );.          ret
7330: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
7340: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
7350: 0a 20 20 20 20 20 20 70 2d 3e 6d 61 73 6b 20 3d  .      p->mask =
7360: 20 6d 61 73 6b 3b 0a 20 20 20 20 20 20 62 72 65   mask;.      bre
7370: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
7380: 61 73 65 20 43 4d 44 5f 53 43 52 49 50 54 3a 20  ase CMD_SCRIPT: 
7390: 7b 0a 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63  {.      if( objc
73a0: 3d 3d 33 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==3 ){.        i
73b0: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20  nt nByte;.      
73c0: 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69 70 74    if( p->pScript
73d0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 54 63   ){.          Tc
73e0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
73f0: 2d 3e 70 53 63 72 69 70 74 29 3b 0a 20 20 20 20  ->pScript);.    
7400: 20 20 20 20 20 20 70 2d 3e 70 53 63 72 69 70 74        p->pScript
7410: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 0;.        }.
7420: 20 20 20 20 20 20 20 20 54 63 6c 5f 47 65 74 53          Tcl_GetS
7430: 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 6f 62 6a  tringFromObj(obj
7440: 76 5b 32 5d 2c 20 26 6e 42 79 74 65 29 3b 0a 20  v[2], &nByte);. 
7450: 20 20 20 20 20 20 20 69 66 28 20 6e 42 79 74 65         if( nByte
7460: 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  >0 ){.          
7470: 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 54 63 6c  p->pScript = Tcl
7480: 5f 44 75 70 6c 69 63 61 74 65 4f 62 6a 28 6f 62  _DuplicateObj(ob
7490: 6a 76 5b 32 5d 29 3b 0a 20 20 20 20 20 20 20 20  jv[2]);.        
74a0: 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75    Tcl_IncrRefCou
74b0: 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b 0a  nt(p->pScript);.
74c0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
74d0: 7d 65 6c 73 65 20 69 66 28 20 6f 62 6a 63 21 3d  }else if( objc!=
74e0: 32 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c  2 ){.        Tcl
74f0: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
7500: 74 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22  terp, 2, objv, "
7510: 3f 53 43 52 49 50 54 3f 22 29 3b 0a 20 20 20 20  ?SCRIPT?");.    
7520: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
7530: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  RROR;.      }.. 
7540: 20 20 20 20 20 54 63 6c 5f 52 65 73 65 74 52 65       Tcl_ResetRe
7550: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 20 20  sult(interp);.  
7560: 20 20 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69      if( p->pScri
7570: 70 74 20 29 20 54 63 6c 5f 53 65 74 4f 62 6a 52  pt ) Tcl_SetObjR
7580: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 2d  esult(interp, p-
7590: 3e 70 53 63 72 69 70 74 29 3b 0a 0a 20 20 20 20  >pScript);..    
75a0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
75b0: 20 20 20 20 2f 2a 0a 20 20 20 20 2a 2a 20 54 45      /*.    ** TE
75c0: 53 54 56 46 53 20 69 6f 65 72 72 20 3f 49 46 41  STVFS ioerr ?IFA
75d0: 49 4c 20 50 45 52 53 49 53 54 3f 0a 20 20 20 20  IL PERSIST?.    
75e0: 2a 2a 0a 20 20 20 20 2a 2a 20 20 20 57 68 65 72  **.    **   Wher
75f0: 65 20 49 46 41 49 4c 20 69 73 20 61 6e 20 69 6e  e IFAIL is an in
7600: 74 65 67 65 72 20 61 6e 64 20 50 45 52 53 49 53  teger and PERSIS
7610: 54 20 69 73 20 62 6f 6f 6c 65 61 6e 2e 0a 20 20  T is boolean..  
7620: 20 20 2a 2f 0a 20 20 20 20 63 61 73 65 20 43 4d    */.    case CM
7630: 44 5f 43 41 4e 54 4f 50 45 4e 45 52 52 3a 0a 20  D_CANTOPENERR:. 
7640: 20 20 20 63 61 73 65 20 43 4d 44 5f 49 4f 45 52     case CMD_IOER
7650: 52 3a 0a 20 20 20 20 63 61 73 65 20 43 4d 44 5f  R:.    case CMD_
7660: 46 55 4c 4c 45 52 52 3a 20 7b 0a 20 20 20 20 20  FULLERR: {.     
7670: 20 54 65 73 74 46 61 75 6c 74 49 6e 6a 65 63 74   TestFaultInject
7680: 20 2a 70 54 65 73 74 3b 0a 20 20 20 20 20 20 69   *pTest;.      i
7690: 6e 74 20 69 52 65 74 3b 0a 0a 20 20 20 20 20 20  nt iRet;..      
76a0: 73 77 69 74 63 68 28 20 61 53 75 62 63 6d 64 5b  switch( aSubcmd[
76b0: 69 5d 2e 65 43 6d 64 20 29 7b 0a 20 20 20 20 20  i].eCmd ){.     
76c0: 20 20 20 63 61 73 65 20 43 4d 44 5f 49 4f 45 52     case CMD_IOER
76d0: 52 3a 20 70 54 65 73 74 20 3d 20 26 70 2d 3e 69  R: pTest = &p->i
76e0: 6f 65 72 72 5f 65 72 72 3b 20 62 72 65 61 6b 3b  oerr_err; break;
76f0: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 43 4d  .        case CM
7700: 44 5f 46 55 4c 4c 45 52 52 3a 20 70 54 65 73 74  D_FULLERR: pTest
7710: 20 3d 20 26 70 2d 3e 66 75 6c 6c 5f 65 72 72 3b   = &p->full_err;
7720: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
7730: 63 61 73 65 20 43 4d 44 5f 43 41 4e 54 4f 50 45  case CMD_CANTOPE
7740: 4e 45 52 52 3a 20 70 54 65 73 74 20 3d 20 26 70  NERR: pTest = &p
7750: 2d 3e 63 61 6e 74 6f 70 65 6e 5f 65 72 72 3b 20  ->cantopen_err; 
7760: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 64  break;.        d
7770: 65 66 61 75 6c 74 3a 20 61 73 73 65 72 74 28 30  efault: assert(0
7780: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
7790: 20 69 52 65 74 20 3d 20 70 54 65 73 74 2d 3e 6e   iRet = pTest->n
77a0: 46 61 69 6c 3b 0a 20 20 20 20 20 20 70 54 65 73  Fail;.      pTes
77b0: 74 2d 3e 6e 46 61 69 6c 20 3d 20 30 3b 0a 20 20  t->nFail = 0;.  
77c0: 20 20 20 20 70 54 65 73 74 2d 3e 65 46 61 75 6c      pTest->eFaul
77d0: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 54 65  t = 0;.      pTe
77e0: 73 74 2d 3e 69 43 6e 74 20 3d 20 30 3b 0a 0a 20  st->iCnt = 0;.. 
77f0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 34       if( objc==4
7800: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
7810: 69 43 6e 74 2c 20 69 50 65 72 73 69 73 74 3b 0a  iCnt, iPersist;.
7820: 20 20 20 20 20 20 20 20 69 66 28 20 54 43 4c 5f          if( TCL_
7830: 4f 4b 21 3d 54 63 6c 5f 47 65 74 49 6e 74 46 72  OK!=Tcl_GetIntFr
7840: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
7850: 6a 76 5b 32 5d 2c 20 26 69 43 6e 74 29 0a 20 20  jv[2], &iCnt).  
7860: 20 20 20 20 20 20 20 7c 7c 20 54 43 4c 5f 4f 4b         || TCL_OK
7870: 21 3d 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e  !=Tcl_GetBoolean
7880: 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20  FromObj(interp, 
7890: 6f 62 6a 76 5b 33 5d 2c 20 26 69 50 65 72 73 69  objv[3], &iPersi
78a0: 73 74 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20  st).        ){. 
78b0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
78c0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  TCL_ERROR;.     
78d0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 54 65     }.        pTe
78e0: 73 74 2d 3e 65 46 61 75 6c 74 20 3d 20 69 50 65  st->eFault = iPe
78f0: 72 73 69 73 74 3f 46 41 55 4c 54 5f 49 4e 4a 45  rsist?FAULT_INJE
7900: 43 54 5f 50 45 52 53 49 53 54 45 4e 54 3a 46 41  CT_PERSISTENT:FA
7910: 55 4c 54 5f 49 4e 4a 45 43 54 5f 54 52 41 4e 53  ULT_INJECT_TRANS
7920: 49 45 4e 54 3b 0a 20 20 20 20 20 20 20 20 70 54  IENT;.        pT
7930: 65 73 74 2d 3e 69 43 6e 74 20 3d 20 69 43 6e 74  est->iCnt = iCnt
7940: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
7950: 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20  ( objc!=2 ){.   
7960: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
7970: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 32 2c  mArgs(interp, 2,
7980: 20 6f 62 6a 76 2c 20 22 3f 43 4e 54 20 50 45 52   objv, "?CNT PER
7990: 53 49 53 54 3f 22 29 3b 0a 20 20 20 20 20 20 20  SIST?");.       
79a0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
79b0: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
79c0: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
79d0: 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65  t(interp, Tcl_Ne
79e0: 77 49 6e 74 4f 62 6a 28 69 52 65 74 29 29 3b 0a  wIntObj(iRet));.
79f0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
7a00: 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d 44   }..    case CMD
7a10: 5f 44 45 4c 45 54 45 3a 20 7b 0a 20 20 20 20 20  _DELETE: {.     
7a20: 20 54 63 6c 5f 44 65 6c 65 74 65 43 6f 6d 6d 61   Tcl_DeleteComma
7a30: 6e 64 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  nd(interp, Tcl_G
7a40: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 30 5d  etString(objv[0]
7a50: 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  ));.      break;
7a60: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
7a70: 20 43 4d 44 5f 44 45 56 43 48 41 52 3a 20 7b 0a   CMD_DEVCHAR: {.
7a80: 20 20 20 20 20 20 73 74 72 75 63 74 20 44 65 76        struct Dev
7a90: 69 63 65 46 6c 61 67 20 7b 0a 20 20 20 20 20 20  iceFlag {.      
7aa0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
7ab0: 20 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c 75         int iValu
7ac0: 65 3b 0a 20 20 20 20 20 20 7d 20 61 46 6c 61 67  e;.      } aFlag
7ad0: 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 7b  [] = {.        {
7ae0: 20 22 64 65 66 61 75 6c 74 22 2c 20 20 20 20 20   "default",     
7af0: 20 20 20 20 20 20 20 20 20 20 2d 31 20 7d 2c 0a            -1 },.
7b00: 20 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69          { "atomi
7b10: 63 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  c",             
7b20: 20 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f     SQLITE_IOCAP_
7b30: 41 54 4f 4d 49 43 20 20 20 20 20 20 7d 2c 0a 20  ATOMIC      },. 
7b40: 20 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63         { "atomic
7b50: 35 31 32 22 2c 20 20 20 20 20 20 20 20 20 20 20  512",           
7b60: 20 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41    SQLITE_IOCAP_A
7b70: 54 4f 4d 49 43 35 31 32 20 20 20 7d 2c 0a 20 20  TOMIC512   },.  
7b80: 20 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 31        { "atomic1
7b90: 6b 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  k",             
7ba0: 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54   SQLITE_IOCAP_AT
7bb0: 4f 4d 49 43 31 4b 20 20 20 20 7d 2c 0a 20 20 20  OMIC1K    },.   
7bc0: 20 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 32 6b       { "atomic2k
7bd0: 22 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ",              
7be0: 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f  SQLITE_IOCAP_ATO
7bf0: 4d 49 43 32 4b 20 20 20 20 7d 2c 0a 20 20 20 20  MIC2K    },.    
7c00: 20 20 20 20 7b 20 22 61 74 6f 6d 69 63 34 6b 22      { "atomic4k"
7c10: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53  ,              S
7c20: 51 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d  QLITE_IOCAP_ATOM
7c30: 49 43 34 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20  IC4K    },.     
7c40: 20 20 20 7b 20 22 61 74 6f 6d 69 63 38 6b 22 2c     { "atomic8k",
7c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
7c60: 4c 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49  LITE_IOCAP_ATOMI
7c70: 43 38 4b 20 20 20 20 7d 2c 0a 20 20 20 20 20 20  C8K    },.      
7c80: 20 20 7b 20 22 61 74 6f 6d 69 63 31 36 6b 22 2c    { "atomic16k",
7c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
7ca0: 49 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43  ITE_IOCAP_ATOMIC
7cb0: 31 36 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20  16K   },.       
7cc0: 20 7b 20 22 61 74 6f 6d 69 63 33 32 6b 22 2c 20   { "atomic32k", 
7cd0: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7ce0: 54 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 33  TE_IOCAP_ATOMIC3
7cf0: 32 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20  2K   },.        
7d00: 7b 20 22 61 74 6f 6d 69 63 36 34 6b 22 2c 20 20  { "atomic64k",  
7d10: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
7d20: 45 5f 49 4f 43 41 50 5f 41 54 4f 4d 49 43 36 34  E_IOCAP_ATOMIC64
7d30: 4b 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b  K   },.        {
7d40: 20 22 73 65 71 75 65 6e 74 69 61 6c 22 2c 20 20   "sequential",  
7d50: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7d60: 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41  _IOCAP_SEQUENTIA
7d70: 4c 20 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20  L  },.        { 
7d80: 22 73 61 66 65 5f 61 70 70 65 6e 64 22 2c 20 20  "safe_append",  
7d90: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7da0: 49 4f 43 41 50 5f 53 41 46 45 5f 41 50 50 45 4e  IOCAP_SAFE_APPEN
7db0: 44 20 7d 2c 0a 20 20 20 20 20 20 20 20 7b 20 22  D },.        { "
7dc0: 75 6e 64 65 6c 65 74 61 62 6c 65 5f 77 68 65 6e  undeletable_when
7dd0: 5f 6f 70 65 6e 22 2c 20 53 51 4c 49 54 45 5f 49  _open", SQLITE_I
7de0: 4f 43 41 50 5f 55 4e 44 45 4c 45 54 41 42 4c 45  OCAP_UNDELETABLE
7df0: 5f 57 48 45 4e 5f 4f 50 45 4e 20 7d 2c 0a 20 20  _WHEN_OPEN },.  
7e00: 20 20 20 20 20 20 7b 20 30 2c 20 30 20 7d 0a 20        { 0, 0 }. 
7e10: 20 20 20 20 20 7d 3b 0a 20 20 20 20 20 20 54 63       };.      Tc
7e20: 6c 5f 4f 62 6a 20 2a 70 52 65 74 3b 0a 20 20 20  l_Obj *pRet;.   
7e30: 20 20 20 69 6e 74 20 69 46 6c 61 67 3b 0a 0a 20     int iFlag;.. 
7e40: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3e 33 20       if( objc>3 
7e50: 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 57  ){.        Tcl_W
7e60: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
7e70: 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f 41  rp, 2, objv, "?A
7e80: 54 54 52 2d 4c 49 53 54 3f 22 29 3b 0a 20 20 20  TTR-LIST?");.   
7e90: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
7ea0: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
7eb0: 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33       if( objc==3
7ec0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
7ed0: 6a 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  j;.        int i
7ee0: 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  New = 0;.       
7ef0: 20 54 63 6c 5f 4f 62 6a 20 2a 2a 66 6c 61 67 73   Tcl_Obj **flags
7f00: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69 6e   = 0;.        in
7f10: 74 20 6e 46 6c 61 67 73 20 3d 20 30 3b 0a 0a 20  t nFlags = 0;.. 
7f20: 20 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 4c         if( Tcl_L
7f30: 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74  istObjGetElement
7f40: 73 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32  s(interp, objv[2
7f50: 5d 2c 20 26 6e 46 6c 61 67 73 2c 20 26 66 6c 61  ], &nFlags, &fla
7f60: 67 73 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  gs) ){.         
7f70: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
7f80: 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  R;.        }..  
7f90: 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a        for(j=0; j
7fa0: 3c 6e 46 6c 61 67 73 3b 20 6a 2b 2b 29 7b 0a 20  <nFlags; j++){. 
7fb0: 20 20 20 20 20 20 20 20 20 69 6e 74 20 69 64 78           int idx
7fc0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20   = 0;.          
7fd0: 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 64 65 78  if( Tcl_GetIndex
7fe0: 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 69 6e  FromObjStruct(in
7ff0: 74 65 72 70 2c 20 66 6c 61 67 73 5b 6a 5d 2c 20  terp, flags[j], 
8000: 61 46 6c 61 67 2c 20 0a 20 20 20 20 20 20 20 20  aFlag, .        
8010: 20 20 20 20 20 20 20 20 73 69 7a 65 6f 66 28 61          sizeof(a
8020: 46 6c 61 67 5b 30 5d 29 2c 20 22 66 6c 61 67 22  Flag[0]), "flag"
8030: 2c 20 30 2c 20 26 69 64 78 29 20 0a 20 20 20 20  , 0, &idx) .    
8040: 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20 20        ){.       
8050: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
8060: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 20  ERROR;.         
8070: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66 28   }.          if(
8080: 20 61 46 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c   aFlag[idx].iVal
8090: 75 65 3c 30 20 26 26 20 6e 46 6c 61 67 73 3e 31  ue<0 && nFlags>1
80a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
80b0: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
80c0: 28 69 6e 74 65 72 70 2c 20 22 62 61 64 20 66 6c  (interp, "bad fl
80d0: 61 67 73 3a 20 22 2c 20 54 63 6c 5f 47 65 74 53  ags: ", Tcl_GetS
80e0: 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20  tring(objv[2]), 
80f0: 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  0);.            
8100: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
8110: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
8120: 20 20 20 20 20 20 20 20 69 4e 65 77 20 7c 3d 20          iNew |= 
8130: 61 46 6c 61 67 5b 69 64 78 5d 2e 69 56 61 6c 75  aFlag[idx].iValu
8140: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  e;.        }..  
8150: 20 20 20 20 20 20 70 2d 3e 69 44 65 76 63 68 61        p->iDevcha
8160: 72 20 3d 20 69 4e 65 77 3b 0a 20 20 20 20 20 20  r = iNew;.      
8170: 7d 0a 0a 20 20 20 20 20 20 70 52 65 74 20 3d 20  }..      pRet = 
8180: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
8190: 20 20 20 20 66 6f 72 28 69 46 6c 61 67 3d 30 3b      for(iFlag=0;
81a0: 20 69 46 6c 61 67 3c 73 69 7a 65 6f 66 28 61 46   iFlag<sizeof(aF
81b0: 6c 61 67 29 2f 73 69 7a 65 6f 66 28 61 46 6c 61  lag)/sizeof(aFla
81c0: 67 5b 30 5d 29 3b 20 69 46 6c 61 67 2b 2b 29 7b  g[0]); iFlag++){
81d0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 2d 3e  .        if( p->
81e0: 69 44 65 76 63 68 61 72 20 26 20 61 46 6c 61 67  iDevchar & aFlag
81f0: 5b 69 46 6c 61 67 5d 2e 69 56 61 6c 75 65 20 29  [iFlag].iValue )
8200: 7b 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f  {.          Tcl_
8210: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
8220: 6d 65 6e 74 28 0a 20 20 20 20 20 20 20 20 20 20  ment(.          
8230: 20 20 20 20 69 6e 74 65 72 70 2c 20 70 52 65 74      interp, pRet
8240: 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  , Tcl_NewStringO
8250: 62 6a 28 61 46 6c 61 67 5b 69 46 6c 61 67 5d 2e  bj(aFlag[iFlag].
8260: 7a 4e 61 6d 65 2c 20 2d 31 29 0a 20 20 20 20 20  zName, -1).     
8270: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20       );.        
8280: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
8290: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
82a0: 28 69 6e 74 65 72 70 2c 20 70 52 65 74 29 3b 0a  (interp, pRet);.
82b0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
82c0: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 43 4d    }..    case CM
82d0: 44 5f 53 45 43 54 4f 52 53 49 5a 45 3a 20 7b 0a  D_SECTORSIZE: {.
82e0: 20 20 20 20 20 20 69 66 28 20 6f 62 6a 63 3e 33        if( objc>3
82f0: 20 29 7b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f   ){.        Tcl_
8300: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
8310: 65 72 70 2c 20 32 2c 20 6f 62 6a 76 2c 20 22 3f  erp, 2, objv, "?
8320: 56 41 4c 55 45 3f 22 29 3b 0a 20 20 20 20 20 20  VALUE?");.      
8330: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
8340: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
8350: 20 20 69 66 28 20 6f 62 6a 63 3d 3d 33 20 29 7b    if( objc==3 ){
8360: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65  .        int iNe
8370: 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  w = 0;.        i
8380: 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  f( Tcl_GetIntFro
8390: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
83a0: 76 5b 32 5d 2c 20 26 69 4e 65 77 29 20 29 7b 0a  v[2], &iNew) ){.
83b0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
83c0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
83d0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 70 2d      }.        p-
83e0: 3e 69 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 69  >iSectorsize = i
83f0: 4e 65 77 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  New;.      }.   
8400: 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73     Tcl_SetObjRes
8410: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
8420: 4e 65 77 49 6e 74 4f 62 6a 28 70 2d 3e 69 53 65  NewIntObj(p->iSe
8430: 63 74 6f 72 73 69 7a 65 29 29 3b 0a 20 20 20 20  ctorsize));.    
8440: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
8450: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c   }..  return TCL
8460: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  _OK;.}..static v
8470: 6f 69 64 20 74 65 73 74 76 66 73 5f 6f 62 6a 5f  oid testvfs_obj_
8480: 64 65 6c 28 43 6c 69 65 6e 74 44 61 74 61 20 63  del(ClientData c
8490: 64 29 7b 0a 20 20 54 65 73 74 76 66 73 20 2a 70  d){.  Testvfs *p
84a0: 20 3d 20 28 54 65 73 74 76 66 73 20 2a 29 63 64   = (Testvfs *)cd
84b0: 3b 0a 20 20 69 66 28 20 70 2d 3e 70 53 63 72 69  ;.  if( p->pScri
84c0: 70 74 20 29 20 54 63 6c 5f 44 65 63 72 52 65 66  pt ) Tcl_DecrRef
84d0: 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74  Count(p->pScript
84e0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  );.  sqlite3_vfs
84f0: 5f 75 6e 72 65 67 69 73 74 65 72 28 70 2d 3e 70  _unregister(p->p
8500: 56 66 73 29 3b 0a 20 20 63 6b 66 72 65 65 28 28  Vfs);.  ckfree((
8510: 63 68 61 72 20 2a 29 70 2d 3e 70 56 66 73 29 3b  char *)p->pVfs);
8520: 0a 20 20 63 6b 66 72 65 65 28 28 63 68 61 72 20  .  ckfree((char 
8530: 2a 29 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  *)p);.}../*.** U
8540: 73 61 67 65 3a 20 20 74 65 73 74 76 66 73 20 56  sage:  testvfs V
8550: 46 53 4e 41 4d 45 20 3f 53 57 49 54 43 48 45 53  FSNAME ?SWITCHES
8560: 3f 0a 2a 2a 0a 2a 2a 20 53 77 69 74 63 68 65 73  ?.**.** Switches
8570: 20 61 72 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 2d 6e   are:.**.**   -n
8580: 6f 73 68 6d 20 20 20 42 4f 4f 4c 45 41 4e 20 20  oshm   BOOLEAN  
8590: 20 20 20 20 20 20 20 20 20 20 20 28 54 72 75 65             (True
85a0: 20 74 6f 20 6f 6d 69 74 20 73 68 6d 20 6d 65 74   to omit shm met
85b0: 68 6f 64 73 2e 20 44 65 66 61 75 6c 74 20 66 61  hods. Default fa
85c0: 6c 73 65 29 0a 2a 2a 20 20 20 2d 64 65 66 61 75  lse).**   -defau
85d0: 6c 74 20 42 4f 4f 4c 45 41 4e 20 20 20 20 20 20  lt BOOLEAN      
85e0: 20 20 20 20 20 20 20 28 54 72 75 65 20 74 6f 20         (True to 
85f0: 6d 61 6b 65 20 74 68 65 20 76 66 73 20 64 65 66  make the vfs def
8600: 61 75 6c 74 2e 20 44 65 66 61 75 6c 74 20 66 61  ault. Default fa
8610: 6c 73 65 29 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  lse).**.** This 
8620: 63 6f 6d 6d 61 6e 64 20 63 72 65 61 74 65 73 20  command creates 
8630: 74 77 6f 20 74 68 69 6e 67 73 20 77 68 65 6e 20  two things when 
8640: 69 74 20 69 73 20 69 6e 76 6f 6b 65 64 3a 20 61  it is invoked: a
8650: 6e 20 53 51 4c 69 74 65 20 56 46 53 2c 20 61 6e  n SQLite VFS, an
8660: 64 0a 2a 2a 20 61 20 54 63 6c 20 63 6f 6d 6d 61  d.** a Tcl comma
8670: 6e 64 2e 20 42 6f 74 68 20 61 72 65 20 6e 61 6d  nd. Both are nam
8680: 65 64 20 56 46 53 4e 41 4d 45 2e 20 54 68 65 20  ed VFSNAME. The 
8690: 56 46 53 20 69 73 20 69 6e 73 74 61 6c 6c 65 64  VFS is installed
86a0: 2e 20 49 74 20 69 73 20 6e 6f 74 0a 2a 2a 20 69  . It is not.** i
86b0: 6e 73 74 61 6c 6c 65 64 20 61 73 20 74 68 65 20  nstalled as the 
86c0: 64 65 66 61 75 6c 74 20 56 46 53 2e 0a 2a 2a 0a  default VFS..**.
86d0: 2a 2a 20 54 68 65 20 56 46 53 20 70 61 73 73 65  ** The VFS passe
86e0: 73 20 61 6c 6c 20 66 69 6c 65 20 49 2f 4f 20 63  s all file I/O c
86f0: 61 6c 6c 73 20 74 68 72 6f 75 67 68 20 74 6f 20  alls through to 
8700: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 56  the underlying V
8710: 46 53 2e 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 65 76  FS..**.** Whenev
8720: 65 72 20 74 68 65 20 78 53 68 6d 4d 61 70 20 6d  er the xShmMap m
8730: 65 74 68 6f 64 20 6f 66 20 74 68 65 20 56 46 53  ethod of the VFS
8740: 0a 2a 2a 20 69 73 20 69 6e 76 6f 6b 65 64 2c 20  .** is invoked, 
8750: 74 68 65 20 53 43 52 49 50 54 20 69 73 20 65 78  the SCRIPT is ex
8760: 65 63 75 74 65 64 20 61 73 20 66 6f 6c 6c 6f 77  ecuted as follow
8770: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 43 52 49 50  s:.**.**   SCRIP
8780: 54 20 78 53 68 6d 4d 61 70 20 20 20 20 46 49 4c  T xShmMap    FIL
8790: 45 4e 41 4d 45 20 49 44 0a 2a 2a 0a 2a 2a 20 54  ENAME ID.**.** T
87a0: 68 65 20 76 61 6c 75 65 20 72 65 74 75 72 6e 65  he value returne
87b0: 64 20 62 79 20 74 68 65 20 69 6e 76 6f 63 61 74  d by the invocat
87c0: 69 6f 6e 20 6f 66 20 53 43 52 49 50 54 20 61 62  ion of SCRIPT ab
87d0: 6f 76 65 20 69 73 20 69 6e 74 65 72 70 72 65 74  ove is interpret
87e0: 65 64 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 69  ed as.** an SQLi
87f0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 61 6e  te error code an
8800: 64 20 72 65 74 75 72 6e 65 64 20 74 6f 20 53 51  d returned to SQ
8810: 4c 69 74 65 2e 20 45 69 74 68 65 72 20 61 20 73  Lite. Either a s
8820: 79 6d 62 6f 6c 69 63 20 0a 2a 2a 20 22 53 51 4c  ymbolic .** "SQL
8830: 49 54 45 5f 4f 4b 22 20 6f 72 20 6e 75 6d 65 72  ITE_OK" or numer
8840: 69 63 20 22 30 22 20 76 61 6c 75 65 20 6d 61 79  ic "0" value may
8850: 20 62 65 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   be returned..**
8860: 0a 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 73  .** The contents
8870: 20 6f 66 20 74 68 65 20 73 68 61 72 65 64 2d 6d   of the shared-m
8880: 65 6d 6f 72 79 20 62 75 66 66 65 72 20 61 73 73  emory buffer ass
8890: 6f 63 69 61 74 65 64 20 77 69 74 68 20 61 20 67  ociated with a g
88a0: 69 76 65 6e 20 66 69 6c 65 0a 2a 2a 20 6d 61 79  iven file.** may
88b0: 20 62 65 20 72 65 61 64 20 61 6e 64 20 73 65 74   be read and set
88c0: 20 75 73 69 6e 67 20 74 68 65 20 66 6f 6c 6c 6f   using the follo
88d0: 77 69 6e 67 20 63 6f 6d 6d 61 6e 64 3a 0a 2a 2a  wing command:.**
88e0: 0a 2a 2a 20 20 20 56 46 53 4e 41 4d 45 20 73 68  .**   VFSNAME sh
88f0: 6d 20 46 49 4c 45 4e 41 4d 45 20 3f 4e 45 57 56  m FILENAME ?NEWV
8900: 41 4c 55 45 3f 0a 2a 2a 0a 2a 2a 20 57 68 65 6e  ALUE?.**.** When
8910: 20 74 68 65 20 78 53 68 6d 4c 6f 63 6b 20 6d 65   the xShmLock me
8920: 74 68 6f 64 20 69 73 20 69 6e 76 6f 6b 65 64 20  thod is invoked 
8930: 62 79 20 53 51 4c 69 74 65 2c 20 74 68 65 20 66  by SQLite, the f
8940: 6f 6c 6c 6f 77 69 6e 67 20 73 63 72 69 70 74 20  ollowing script 
8950: 69 73 0a 2a 2a 20 72 75 6e 3a 0a 2a 2a 0a 2a 2a  is.** run:.**.**
8960: 20 20 20 53 43 52 49 50 54 20 78 53 68 6d 4c 6f     SCRIPT xShmLo
8970: 63 6b 20 20 20 20 46 49 4c 45 4e 41 4d 45 20 49  ck    FILENAME I
8980: 44 20 4c 4f 43 4b 0a 2a 2a 0a 2a 2a 20 77 68 65  D LOCK.**.** whe
8990: 72 65 20 4c 4f 43 4b 20 69 73 20 6f 66 20 74 68  re LOCK is of th
89a0: 65 20 66 6f 72 6d 20 22 4f 46 46 53 45 54 20 4e  e form "OFFSET N
89b0: 42 59 54 45 20 6c 6f 63 6b 2f 75 6e 6c 6f 63 6b  BYTE lock/unlock
89c0: 20 73 68 61 72 65 64 2f 65 78 63 6c 75 73 69 76   shared/exclusiv
89d0: 65 22 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e".*/.static int
89e0: 20 74 65 73 74 76 66 73 5f 63 6d 64 28 0a 20 20   testvfs_cmd(.  
89f0: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a 20  ClientData cd,. 
8a00: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
8a10: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
8a20: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
8a30: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 73 74  T objv[].){.  st
8a40: 61 74 69 63 20 73 71 6c 69 74 65 33 5f 76 66 73  atic sqlite3_vfs
8a50: 20 74 76 66 73 5f 76 66 73 20 3d 20 7b 0a 20 20   tvfs_vfs = {.  
8a60: 20 20 32 2c 20 20 20 20 20 20 20 20 20 20 20 20    2,            
8a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a80: 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20  /* iVersion */. 
8a90: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
8aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ab0: 20 2f 2a 20 73 7a 4f 73 46 69 6c 65 20 2a 2f 0a   /* szOsFile */.
8ac0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
8ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ae0: 20 20 2f 2a 20 6d 78 50 61 74 68 6e 61 6d 65 20    /* mxPathname 
8af0: 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20  */.    0,       
8b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b10: 20 20 20 20 20 2f 2a 20 70 4e 65 78 74 20 2a 2f       /* pNext */
8b20: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
8b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b40: 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20     /* zName */. 
8b50: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
8b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b70: 20 2f 2a 20 70 41 70 70 44 61 74 61 20 2a 2f 0a   /* pAppData */.
8b80: 20 20 20 20 74 76 66 73 4f 70 65 6e 2c 20 20 20      tvfsOpen,   
8b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ba0: 20 20 2f 2a 20 78 4f 70 65 6e 20 2a 2f 0a 20 20    /* xOpen */.  
8bb0: 20 20 74 76 66 73 44 65 6c 65 74 65 2c 20 20 20    tvfsDelete,   
8bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8bd0: 2f 2a 20 78 44 65 6c 65 74 65 20 2a 2f 0a 20 20  /* xDelete */.  
8be0: 20 20 74 76 66 73 41 63 63 65 73 73 2c 20 20 20    tvfsAccess,   
8bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8c00: 2f 2a 20 78 41 63 63 65 73 73 20 2a 2f 0a 20 20  /* xAccess */.  
8c10: 20 20 74 76 66 73 46 75 6c 6c 50 61 74 68 6e 61    tvfsFullPathna
8c20: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
8c30: 2f 2a 20 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65  /* xFullPathname
8c40: 20 2a 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49   */.#ifndef SQLI
8c50: 54 45 5f 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54  TE_OMIT_LOAD_EXT
8c60: 45 4e 53 49 4f 4e 0a 20 20 20 20 74 76 66 73 44  ENSION.    tvfsD
8c70: 6c 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  lOpen,          
8c80: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 4f           /* xDlO
8c90: 70 65 6e 20 2a 2f 0a 20 20 20 20 74 76 66 73 44  pen */.    tvfsD
8ca0: 6c 45 72 72 6f 72 2c 20 20 20 20 20 20 20 20 20  lError,         
8cb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 45           /* xDlE
8cc0: 72 72 6f 72 20 2a 2f 0a 20 20 20 20 74 76 66 73  rror */.    tvfs
8cd0: 44 6c 53 79 6d 2c 20 20 20 20 20 20 20 20 20 20  DlSym,          
8ce0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
8cf0: 53 79 6d 20 2a 2f 0a 20 20 20 20 74 76 66 73 44  Sym */.    tvfsD
8d00: 6c 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20  lClose,         
8d10: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 43           /* xDlC
8d20: 6c 6f 73 65 20 2a 2f 0a 23 65 6c 73 65 0a 20 20  lose */.#else.  
8d30: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
8d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d50: 2f 2a 20 78 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20  /* xDlOpen */.  
8d60: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
8d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d80: 2f 2a 20 78 44 6c 45 72 72 6f 72 20 2a 2f 0a 20  /* xDlError */. 
8d90: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
8da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8db0: 20 2f 2a 20 78 44 6c 53 79 6d 20 2a 2f 0a 20 20   /* xDlSym */.  
8dc0: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
8dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8de0: 2f 2a 20 78 44 6c 43 6c 6f 73 65 20 2a 2f 0a 23  /* xDlClose */.#
8df0: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
8e00: 4f 4d 49 54 5f 4c 4f 41 44 5f 45 58 54 45 4e 53  OMIT_LOAD_EXTENS
8e10: 49 4f 4e 20 2a 2f 0a 20 20 20 20 74 76 66 73 52  ION */.    tvfsR
8e20: 61 6e 64 6f 6d 6e 65 73 73 2c 20 20 20 20 20 20  andomness,      
8e30: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 61 6e           /* xRan
8e40: 64 6f 6d 6e 65 73 73 20 2a 2f 0a 20 20 20 20 74  domness */.    t
8e50: 76 66 73 53 6c 65 65 70 2c 20 20 20 20 20 20 20  vfsSleep,       
8e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8e70: 78 53 6c 65 65 70 20 2a 2f 0a 20 20 20 20 74 76  xSleep */.    tv
8e80: 66 73 43 75 72 72 65 6e 74 54 69 6d 65 2c 20 20  fsCurrentTime,  
8e90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8ea0: 43 75 72 72 65 6e 74 54 69 6d 65 20 2a 2f 0a 20  CurrentTime */. 
8eb0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
8ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ed0: 20 2f 2a 20 78 47 65 74 4c 61 73 74 45 72 72 6f   /* xGetLastErro
8ee0: 72 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  r */.    0,     
8ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8f00: 20 20 20 20 20 20 20 2f 2a 20 78 43 75 72 72 65         /* xCurre
8f10: 6e 74 54 69 6d 65 49 6e 74 36 34 20 2a 2f 0a 20  ntTimeInt64 */. 
8f20: 20 7d 3b 0a 0a 20 20 54 65 73 74 76 66 73 20 2a   };..  Testvfs *
8f30: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
8f40: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6f 62         /* New ob
8f50: 6a 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ject */.  sqlite
8f60: 33 5f 76 66 73 20 2a 70 56 66 73 3b 20 20 20 20  3_vfs *pVfs;    
8f70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77            /* New
8f80: 20 56 46 53 20 2a 2f 0a 20 20 63 68 61 72 20 2a   VFS */.  char *
8f90: 7a 56 66 73 3b 0a 20 20 69 6e 74 20 6e 42 79 74  zVfs;.  int nByt
8fa0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
8fb0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
8fc0: 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c   of space to all
8fd0: 6f 63 61 74 65 20 61 74 20 70 20 2a 2f 0a 0a 20  ocate at p */.. 
8fe0: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69 73   int i;.  int is
8ff0: 4e 6f 73 68 6d 20 3d 20 30 3b 20 20 20 20 20 20  Noshm = 0;      
9000: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
9010: 65 20 69 66 20 2d 6e 6f 73 68 6d 20 69 73 20 70  e if -noshm is p
9020: 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69  assed */.  int i
9030: 73 44 65 66 61 75 6c 74 20 3d 20 30 3b 20 20 20  sDefault = 0;   
9040: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
9050: 75 65 20 69 66 20 2d 64 65 66 61 75 6c 74 20 69  ue if -default i
9060: 73 20 70 61 73 73 65 64 20 2a 2f 0a 20 20 69 6e  s passed */.  in
9070: 74 20 73 7a 4f 73 46 69 6c 65 20 3d 20 30 3b 20  t szOsFile = 0; 
9080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9090: 20 56 61 6c 75 65 20 70 61 73 73 65 64 20 74 6f   Value passed to
90a0: 20 2d 73 7a 6f 73 66 69 6c 65 20 2a 2f 0a 20 20   -szosfile */.  
90b0: 69 6e 74 20 6d 78 50 61 74 68 6e 61 6d 65 20 3d  int mxPathname =
90c0: 20 2d 31 3b 20 20 20 20 20 20 20 20 20 20 20 20   -1;            
90d0: 2f 2a 20 56 61 6c 75 65 20 70 61 73 73 65 64 20  /* Value passed 
90e0: 74 6f 20 2d 6d 78 70 61 74 68 6e 61 6d 65 20 2a  to -mxpathname *
90f0: 2f 0a 20 20 69 6e 74 20 69 56 65 72 73 69 6f 6e  /.  int iVersion
9100: 20 3d 20 32 3b 20 20 20 20 20 20 20 20 20 20 20   = 2;           
9110: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 70 61 73      /* Value pas
9120: 73 65 64 20 74 6f 20 2d 69 76 65 72 73 69 6f 6e  sed to -iversion
9130: 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 3c   */..  if( objc<
9140: 32 20 7c 7c 20 30 21 3d 28 6f 62 6a 63 25 32 29  2 || 0!=(objc%2)
9150: 20 29 20 67 6f 74 6f 20 62 61 64 5f 61 72 67 73   ) goto bad_args
9160: 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6f  ;.  for(i=2; i<o
9170: 62 6a 63 3b 20 69 20 2b 3d 20 32 29 7b 0a 20 20  bjc; i += 2){.  
9180: 20 20 69 6e 74 20 6e 53 77 69 74 63 68 3b 0a 20    int nSwitch;. 
9190: 20 20 20 63 68 61 72 20 2a 7a 53 77 69 74 63 68     char *zSwitch
91a0: 3b 0a 20 20 20 20 7a 53 77 69 74 63 68 20 3d 20  ;.    zSwitch = 
91b0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f  Tcl_GetStringFro
91c0: 6d 4f 62 6a 28 6f 62 6a 76 5b 69 5d 2c 20 26 6e  mObj(objv[i], &n
91d0: 53 77 69 74 63 68 29 3b 20 0a 0a 20 20 20 20 69  Switch); ..    i
91e0: 66 28 20 6e 53 77 69 74 63 68 3e 32 20 26 26 20  f( nSwitch>2 && 
91f0: 30 3d 3d 73 74 72 6e 63 6d 70 28 22 2d 6e 6f 73  0==strncmp("-nos
9200: 68 6d 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53  hm", zSwitch, nS
9210: 77 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20  witch) ){.      
9220: 69 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65  if( Tcl_GetBoole
9230: 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  anFromObj(interp
9240: 2c 20 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73  , objv[i+1], &is
9250: 4e 6f 73 68 6d 29 20 29 7b 0a 20 20 20 20 20 20  Noshm) ){.      
9260: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
9270: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
9280: 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e  }.    else if( n
9290: 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73  Switch>2 && 0==s
92a0: 74 72 6e 63 6d 70 28 22 2d 64 65 66 61 75 6c 74  trncmp("-default
92b0: 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69  ", zSwitch, nSwi
92c0: 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66  tch) ){.      if
92d0: 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e  ( Tcl_GetBoolean
92e0: 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20  FromObj(interp, 
92f0: 6f 62 6a 76 5b 69 2b 31 5d 2c 20 26 69 73 44 65  objv[i+1], &isDe
9300: 66 61 75 6c 74 29 20 29 7b 0a 20 20 20 20 20 20  fault) ){.      
9310: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
9320: 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OR;.      }.    
9330: 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28 20 6e  }.    else if( n
9340: 53 77 69 74 63 68 3e 32 20 26 26 20 30 3d 3d 73  Switch>2 && 0==s
9350: 74 72 6e 63 6d 70 28 22 2d 73 7a 6f 73 66 69 6c  trncmp("-szosfil
9360: 65 22 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77  e", zSwitch, nSw
9370: 69 74 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69  itch) ){.      i
9380: 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f  f( Tcl_GetIntFro
9390: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
93a0: 76 5b 69 2b 31 5d 2c 20 26 73 7a 4f 73 46 69 6c  v[i+1], &szOsFil
93b0: 65 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  e) ){.        re
93c0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
93d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
93e0: 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74    else if( nSwit
93f0: 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63  ch>2 && 0==strnc
9400: 6d 70 28 22 2d 6d 78 70 61 74 68 6e 61 6d 65 22  mp("-mxpathname"
9410: 2c 20 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74  , zSwitch, nSwit
9420: 63 68 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ch) ){.      if(
9430: 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f   Tcl_GetIntFromO
9440: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
9450: 69 2b 31 5d 2c 20 26 6d 78 50 61 74 68 6e 61 6d  i+1], &mxPathnam
9460: 65 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  e) ){.        re
9470: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
9480: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
9490: 20 20 65 6c 73 65 20 69 66 28 20 6e 53 77 69 74    else if( nSwit
94a0: 63 68 3e 32 20 26 26 20 30 3d 3d 73 74 72 6e 63  ch>2 && 0==strnc
94b0: 6d 70 28 22 2d 69 76 65 72 73 69 6f 6e 22 2c 20  mp("-iversion", 
94c0: 7a 53 77 69 74 63 68 2c 20 6e 53 77 69 74 63 68  zSwitch, nSwitch
94d0: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 54  ) ){.      if( T
94e0: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
94f0: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 69 2b  (interp, objv[i+
9500: 31 5d 2c 20 26 69 56 65 72 73 69 6f 6e 29 20 29  1], &iVersion) )
9510: 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
9520: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
9530: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c    }.    }.    el
9540: 73 65 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 62  se{.      goto b
9550: 61 64 5f 61 72 67 73 3b 0a 20 20 20 20 7d 0a 20  ad_args;.    }. 
9560: 20 7d 0a 0a 20 20 69 66 28 20 73 7a 4f 73 46 69   }..  if( szOsFi
9570: 6c 65 3c 73 69 7a 65 6f 66 28 54 65 73 74 76 66  le<sizeof(Testvf
9580: 73 46 69 6c 65 29 20 29 7b 0a 20 20 20 20 73 7a  sFile) ){.    sz
9590: 4f 73 46 69 6c 65 20 3d 20 73 69 7a 65 6f 66 28  OsFile = sizeof(
95a0: 54 65 73 74 76 66 73 46 69 6c 65 29 3b 0a 20 20  TestvfsFile);.  
95b0: 7d 0a 0a 20 20 7a 56 66 73 20 3d 20 54 63 6c 5f  }..  zVfs = Tcl_
95c0: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
95d0: 5d 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69  ]);.  nByte = si
95e0: 7a 65 6f 66 28 54 65 73 74 76 66 73 29 20 2b 20  zeof(Testvfs) + 
95f0: 73 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 3b 0a  strlen(zVfs)+1;.
9600: 20 20 70 20 3d 20 28 54 65 73 74 76 66 73 20 2a    p = (Testvfs *
9610: 29 63 6b 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b  )ckalloc(nByte);
9620: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
9630: 6e 42 79 74 65 29 3b 0a 20 20 70 2d 3e 69 44 65  nByte);.  p->iDe
9640: 76 63 68 61 72 20 3d 20 2d 31 3b 0a 20 20 70 2d  vchar = -1;.  p-
9650: 3e 69 53 65 63 74 6f 72 73 69 7a 65 20 3d 20 2d  >iSectorsize = -
9660: 31 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20  1;..  /* Create 
9670: 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 63  the new object c
9680: 6f 6d 6d 61 6e 64 20 62 65 66 6f 72 65 20 71 75  ommand before qu
9690: 65 72 79 69 6e 67 20 53 51 4c 69 74 65 20 66 6f  erying SQLite fo
96a0: 72 20 61 20 64 65 66 61 75 6c 74 20 56 46 53 0a  r a default VFS.
96b0: 20 20 2a 2a 20 74 6f 20 75 73 65 20 66 6f 72 20    ** to use for 
96c0: 27 72 65 61 6c 27 20 49 4f 20 6f 70 65 72 61 74  'real' IO operat
96d0: 69 6f 6e 73 2e 20 54 68 69 73 20 69 73 20 62 65  ions. This is be
96e0: 63 61 75 73 65 20 63 72 65 61 74 69 6e 67 20 74  cause creating t
96f0: 68 65 20 6e 65 77 20 56 46 53 0a 20 20 2a 2a 20  he new VFS.  ** 
9700: 6d 61 79 20 64 65 6c 65 74 65 20 61 6e 20 65 78  may delete an ex
9710: 69 73 74 69 6e 67 20 5b 74 65 73 74 76 66 73 5d  isting [testvfs]
9720: 20 56 46 53 20 6f 66 20 74 68 65 20 73 61 6d 65   VFS of the same
9730: 20 6e 61 6d 65 2e 20 49 66 20 73 75 63 68 20 61   name. If such a
9740: 20 56 46 53 0a 20 20 2a 2a 20 69 73 20 63 75 72   VFS.  ** is cur
9750: 72 65 6e 74 6c 79 20 74 68 65 20 64 65 66 61 75  rently the defau
9760: 6c 74 2c 20 74 68 65 20 6e 65 77 20 5b 74 65 73  lt, the new [tes
9770: 74 76 66 73 5d 20 6d 61 79 20 65 6e 64 20 75 70  tvfs] may end up
9780: 20 63 61 6c 6c 69 6e 67 20 74 68 65 20 0a 20 20   calling the .  
9790: 2a 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 61 20  ** methods of a 
97a0: 64 65 6c 65 74 65 64 20 6f 62 6a 65 63 74 2e 0a  deleted object..
97b0: 20 20 2a 2f 0a 20 20 54 63 6c 5f 43 72 65 61 74    */.  Tcl_Creat
97c0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
97d0: 72 70 2c 20 7a 56 66 73 2c 20 74 65 73 74 76 66  rp, zVfs, testvf
97e0: 73 5f 6f 62 6a 5f 63 6d 64 2c 20 70 2c 20 74 65  s_obj_cmd, p, te
97f0: 73 74 76 66 73 5f 6f 62 6a 5f 64 65 6c 29 3b 0a  stvfs_obj_del);.
9800: 20 20 70 2d 3e 70 50 61 72 65 6e 74 20 3d 20 73    p->pParent = s
9810: 71 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28  qlite3_vfs_find(
9820: 30 29 3b 0a 20 20 70 2d 3e 69 6e 74 65 72 70 20  0);.  p->interp 
9830: 3d 20 69 6e 74 65 72 70 3b 0a 0a 20 20 70 2d 3e  = interp;..  p->
9840: 7a 4e 61 6d 65 20 3d 20 28 63 68 61 72 20 2a 29  zName = (char *)
9850: 26 70 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28  &p[1];.  memcpy(
9860: 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 56 66 73 2c 20  p->zName, zVfs, 
9870: 73 74 72 6c 65 6e 28 7a 56 66 73 29 2b 31 29 3b  strlen(zVfs)+1);
9880: 0a 0a 20 20 70 56 66 73 20 3d 20 28 73 71 6c 69  ..  pVfs = (sqli
9890: 74 65 33 5f 76 66 73 20 2a 29 63 6b 61 6c 6c 6f  te3_vfs *)ckallo
98a0: 63 28 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33  c(sizeof(sqlite3
98b0: 5f 76 66 73 29 29 3b 0a 20 20 6d 65 6d 63 70 79  _vfs));.  memcpy
98c0: 28 70 56 66 73 2c 20 26 74 76 66 73 5f 76 66 73  (pVfs, &tvfs_vfs
98d0: 2c 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65 33  , sizeof(sqlite3
98e0: 5f 76 66 73 29 29 3b 0a 20 20 70 56 66 73 2d 3e  _vfs));.  pVfs->
98f0: 70 41 70 70 44 61 74 61 20 3d 20 28 76 6f 69 64  pAppData = (void
9900: 20 2a 29 70 3b 0a 20 20 70 56 66 73 2d 3e 69 56   *)p;.  pVfs->iV
9910: 65 72 73 69 6f 6e 20 3d 20 69 56 65 72 73 69 6f  ersion = iVersio
9920: 6e 3b 0a 20 20 70 56 66 73 2d 3e 7a 4e 61 6d 65  n;.  pVfs->zName
9930: 20 3d 20 70 2d 3e 7a 4e 61 6d 65 3b 0a 20 20 70   = p->zName;.  p
9940: 56 66 73 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20  Vfs->mxPathname 
9950: 3d 20 70 2d 3e 70 50 61 72 65 6e 74 2d 3e 6d 78  = p->pParent->mx
9960: 50 61 74 68 6e 61 6d 65 3b 0a 20 20 69 66 28 20  Pathname;.  if( 
9970: 6d 78 50 61 74 68 6e 61 6d 65 3e 3d 30 20 26 26  mxPathname>=0 &&
9980: 20 6d 78 50 61 74 68 6e 61 6d 65 3c 70 56 66 73   mxPathname<pVfs
9990: 2d 3e 6d 78 50 61 74 68 6e 61 6d 65 20 29 7b 0a  ->mxPathname ){.
99a0: 20 20 20 20 70 56 66 73 2d 3e 6d 78 50 61 74 68      pVfs->mxPath
99b0: 6e 61 6d 65 20 3d 20 6d 78 50 61 74 68 6e 61 6d  name = mxPathnam
99c0: 65 3b 0a 20 20 7d 0a 20 20 70 56 66 73 2d 3e 73  e;.  }.  pVfs->s
99d0: 7a 4f 73 46 69 6c 65 20 3d 20 73 7a 4f 73 46 69  zOsFile = szOsFi
99e0: 6c 65 3b 0a 20 20 70 2d 3e 70 56 66 73 20 3d 20  le;.  p->pVfs = 
99f0: 70 56 66 73 3b 0a 20 20 70 2d 3e 69 73 4e 6f 73  pVfs;.  p->isNos
9a00: 68 6d 20 3d 20 69 73 4e 6f 73 68 6d 3b 0a 20 20  hm = isNoshm;.  
9a10: 70 2d 3e 6d 61 73 6b 20 3d 20 54 45 53 54 56 46  p->mask = TESTVF
9a20: 53 5f 41 4c 4c 5f 4d 41 53 4b 3b 0a 0a 20 20 73  S_ALL_MASK;..  s
9a30: 71 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73  qlite3_vfs_regis
9a40: 74 65 72 28 70 56 66 73 2c 20 69 73 44 65 66 61  ter(pVfs, isDefa
9a50: 75 6c 74 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20  ult);..  return 
9a60: 54 43 4c 5f 4f 4b 3b 0a 0a 20 62 61 64 5f 61 72  TCL_OK;.. bad_ar
9a70: 67 73 3a 0a 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  gs:.  Tcl_WrongN
9a80: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
9a90: 2c 20 6f 62 6a 76 2c 20 22 56 46 53 4e 41 4d 45  , objv, "VFSNAME
9aa0: 20 3f 2d 6e 6f 73 68 6d 20 42 4f 4f 4c 3f 20 3f   ?-noshm BOOL? ?
9ab0: 2d 64 65 66 61 75 6c 74 20 42 4f 4f 4c 3f 20 3f  -default BOOL? ?
9ac0: 2d 6d 78 70 61 74 68 6e 61 6d 65 20 49 4e 54 3f  -mxpathname INT?
9ad0: 20 3f 2d 73 7a 6f 73 66 69 6c 65 20 49 4e 54 3f   ?-szosfile INT?
9ae0: 20 3f 2d 69 76 65 72 73 69 6f 6e 20 49 4e 54 3f   ?-iversion INT?
9af0: 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  ");.  return TCL
9b00: 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 69 6e 74 20 53  _ERROR;.}..int S
9b10: 71 6c 69 74 65 74 65 73 74 76 66 73 5f 49 6e 69  qlitetestvfs_Ini
9b20: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
9b30: 74 65 72 70 29 7b 0a 20 20 54 63 6c 5f 43 72 65  terp){.  Tcl_Cre
9b40: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
9b50: 74 65 72 70 2c 20 22 74 65 73 74 76 66 73 22 2c  terp, "testvfs",
9b60: 20 74 65 73 74 76 66 73 5f 63 6d 64 2c 20 30 2c   testvfs_cmd, 0,
9b70: 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43   0);.  return TC
9b80: 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a  L_OK;.}..#endif.