/ Hex Artifact Content
Login

Artifact 3dffd0fe6c96ac7c5150485b55244e73faab5380:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 4f 63 74 6f 62  /*.** 2010 Octob
0010: 65 72 20 32 38 0a 2a 2a 0a 2a 2a 20 54 68 65 20  er 28.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
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 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20  file contains a 
0190: 56 46 53 20 22 73 68 69 6d 22 20 2d 20 61 20 6c  VFS "shim" - a l
01a0: 61 79 65 72 20 74 68 61 74 20 73 69 74 73 20 69  ayer that sits i
01b0: 6e 20 62 65 74 77 65 65 6e 20 74 68 65 0a 2a 2a  n between the.**
01c0: 20 70 61 67 65 72 20 61 6e 64 20 74 68 65 20 72   pager and the r
01d0: 65 61 6c 20 56 46 53 20 2d 20 74 68 61 74 20 62  eal VFS - that b
01e0: 72 65 61 6b 73 20 75 70 20 61 20 76 65 72 79 20  reaks up a very 
01f0: 6c 61 72 67 65 20 64 61 74 61 62 61 73 65 20 66  large database f
0200: 69 6c 65 0a 2a 2a 20 69 6e 74 6f 20 74 77 6f 20  ile.** into two 
0210: 6f 72 20 6d 6f 72 65 20 73 6d 61 6c 6c 65 72 20  or more smaller 
0220: 66 69 6c 65 73 20 6f 6e 20 64 69 73 6b 2e 20 20  files on disk.  
0230: 54 68 69 73 20 69 73 20 75 73 65 66 75 6c 2c 20  This is useful, 
0240: 66 6f 72 20 65 78 61 6d 70 6c 65 2c 0a 2a 2a 20  for example,.** 
0250: 69 6e 20 6f 72 64 65 72 20 74 6f 20 73 75 70 70  in order to supp
0260: 6f 72 74 20 6c 61 72 67 65 2c 20 6d 75 6c 74 69  ort large, multi
0270: 2d 67 69 67 61 62 79 74 65 20 64 61 74 61 62 61  -gigabyte databa
0280: 73 65 73 20 6f 6e 20 6f 6c 64 65 72 20 66 69 6c  ses on older fil
0290: 65 73 79 73 74 65 6d 73 0a 2a 2a 20 74 68 61 74  esystems.** that
02a0: 20 6c 69 6d 69 74 20 74 68 65 20 6d 61 78 69 6d   limit the maxim
02b0: 75 6d 20 66 69 6c 65 20 73 69 7a 65 20 74 6f 20  um file size to 
02c0: 32 20 47 69 42 2e 0a 2a 2a 0a 2a 2a 20 55 53 41  2 GiB..**.** USA
02d0: 47 45 3a 0a 2a 2a 0a 2a 2a 20 43 6f 6d 70 69 6c  GE:.**.** Compil
02e0: 65 20 74 68 69 73 20 73 6f 75 72 63 65 20 66 69  e this source fi
02f0: 6c 65 20 61 6e 64 20 6c 69 6e 6b 20 69 74 20 77  le and link it w
0300: 69 74 68 20 79 6f 75 72 20 61 70 70 6c 69 63 61  ith your applica
0310: 74 69 6f 6e 2e 20 20 54 68 65 6e 0a 2a 2a 20 61  tion.  Then.** a
0320: 74 20 73 74 61 72 74 2d 74 69 6d 65 2c 20 69 6e  t start-time, in
0330: 76 6f 6b 65 20 74 68 65 20 66 6f 6c 6c 6f 77 69  voke the followi
0340: 6e 67 20 70 72 6f 63 65 64 75 72 65 3a 0a 2a 2a  ng procedure:.**
0350: 0a 2a 2a 20 20 20 69 6e 74 20 73 71 6c 69 74 65  .**   int sqlite
0360: 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 69 6e 69 74  3_multiplex_init
0370: 69 61 6c 69 7a 65 28 0a 2a 2a 20 20 20 20 20 20  ialize(.**      
0380: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f 72 69  const char *zOri
0390: 67 56 66 73 4e 61 6d 65 2c 20 20 20 20 2f 2f 20  gVfsName,    // 
03a0: 54 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 72  The underlying r
03b0: 65 61 6c 20 56 46 53 0a 2a 2a 20 20 20 20 20 20  eal VFS.**      
03c0: 69 6e 74 20 6d 61 6b 65 44 65 66 61 75 6c 74 20  int makeDefault 
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2f 20               // 
03e0: 54 72 75 65 20 74 6f 20 6d 61 6b 65 20 6d 75 6c  True to make mul
03f0: 74 69 70 6c 65 78 20 74 68 65 20 64 65 66 61 75  tiplex the defau
0400: 6c 74 20 56 46 53 0a 2a 2a 20 20 20 29 3b 0a 2a  lt VFS.**   );.*
0410: 2a 0a 2a 2a 20 54 68 65 20 70 72 6f 63 65 64 75  *.** The procedu
0420: 72 65 20 63 61 6c 6c 20 61 62 6f 76 65 20 77 69  re call above wi
0430: 6c 6c 20 63 72 65 61 74 65 20 61 6e 64 20 72 65  ll create and re
0440: 67 69 73 74 65 72 20 61 20 6e 65 77 20 56 46 53  gister a new VFS
0450: 20 73 68 69 6d 20 6e 61 6d 65 64 0a 2a 2a 20 22   shim named.** "
0460: 6d 75 6c 74 69 70 6c 65 78 22 2e 20 20 54 68 65  multiplex".  The
0470: 20 6d 75 6c 74 69 70 6c 65 78 20 56 46 53 20 77   multiplex VFS w
0480: 69 6c 6c 20 75 73 65 20 74 68 65 20 56 46 53 20  ill use the VFS 
0490: 6e 61 6d 65 64 20 62 79 20 7a 4f 72 69 67 56 66  named by zOrigVf
04a0: 73 4e 61 6d 65 20 74 6f 0a 2a 2a 20 64 6f 20 74  sName to.** do t
04b0: 68 65 20 61 63 74 75 61 6c 20 64 69 73 6b 20 49  he actual disk I
04c0: 2f 4f 2e 20 20 28 54 68 65 20 7a 4f 72 69 67 56  /O.  (The zOrigV
04d0: 66 73 4e 61 6d 65 20 70 61 72 61 6d 65 74 65 72  fsName parameter
04e0: 20 6d 61 79 20 62 65 20 4e 55 4c 4c 2c 20 69 6e   may be NULL, in
04f0: 20 0a 2a 2a 20 77 68 69 63 68 20 63 61 73 65 20   .** which case 
0500: 74 68 65 20 64 65 66 61 75 6c 74 20 56 46 53 20  the default VFS 
0510: 61 74 20 74 68 65 20 6d 6f 6d 65 6e 74 20 73 71  at the moment sq
0520: 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f  lite3_multiplex_
0530: 69 6e 69 74 69 61 6c 69 7a 65 28 29 0a 2a 2a 20  initialize().** 
0540: 69 73 20 63 61 6c 6c 65 64 20 77 69 6c 6c 20 62  is called will b
0550: 65 20 75 73 65 64 20 61 73 20 74 68 65 20 75 6e  e used as the un
0560: 64 65 72 6c 79 69 6e 67 20 72 65 61 6c 20 56 46  derlying real VF
0570: 53 2e 29 20 20 0a 2a 2a 0a 2a 2a 20 49 66 20 74  S.)  .**.** If t
0580: 68 65 20 6d 61 6b 65 44 65 66 61 75 6c 74 20 70  he makeDefault p
0590: 61 72 61 6d 65 74 65 72 20 69 73 20 54 52 55 45  arameter is TRUE
05a0: 20 74 68 65 6e 20 6d 75 6c 74 69 70 6c 65 78 20   then multiplex 
05b0: 62 65 63 6f 6d 65 73 20 74 68 65 20 6e 65 77 0a  becomes the new.
05c0: 2a 2a 20 64 65 66 61 75 6c 74 20 56 46 53 2e 20  ** default VFS. 
05d0: 20 4f 74 68 65 72 77 69 73 65 2c 20 79 6f 75 20   Otherwise, you 
05e0: 63 61 6e 20 75 73 65 20 74 68 65 20 6d 75 6c 74  can use the mult
05f0: 69 70 6c 65 78 20 56 46 53 20 62 79 20 73 70 65  iplex VFS by spe
0600: 63 69 66 79 69 6e 67 0a 2a 2a 20 22 6d 75 6c 74  cifying.** "mult
0610: 69 70 6c 65 78 22 20 61 73 20 74 68 65 20 34 74  iplex" as the 4t
0620: 68 20 70 61 72 61 6d 65 74 65 72 20 74 6f 20 73  h parameter to s
0630: 71 6c 69 74 65 33 5f 6f 70 65 6e 5f 76 32 28 29  qlite3_open_v2()
0640: 20 6f 72 20 62 79 20 65 6d 70 6c 6f 79 69 6e 67   or by employing
0650: 0a 2a 2a 20 55 52 49 20 66 69 6c 65 6e 61 6d 65  .** URI filename
0660: 73 20 61 6e 64 20 61 64 64 69 6e 67 20 22 76 66  s and adding "vf
0670: 73 3d 6d 75 6c 74 69 70 6c 65 78 22 20 61 73 20  s=multiplex" as 
0680: 61 20 70 61 72 61 6d 65 74 65 72 20 74 6f 20 74  a parameter to t
0690: 68 65 20 66 69 6c 65 6e 61 6d 65 0a 2a 2a 20 55  he filename.** U
06a0: 52 49 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6d 75  RI..**.** The mu
06b0: 6c 74 69 70 6c 65 78 20 56 46 53 20 61 6c 6c 6f  ltiplex VFS allo
06c0: 77 73 20 64 61 74 61 62 61 73 65 73 20 75 70 20  ws databases up 
06d0: 74 6f 20 33 32 20 47 69 42 20 69 6e 20 73 69 7a  to 32 GiB in siz
06e0: 65 2e 20 20 42 75 74 20 69 74 20 73 70 6c 69 74  e.  But it split
06f0: 73 0a 2a 2a 20 74 68 65 20 66 69 6c 65 73 20 75  s.** the files u
0700: 70 20 69 6e 74 6f 20 73 6d 61 6c 6c 65 72 20 70  p into smaller p
0710: 69 65 63 65 73 2c 20 73 6f 20 74 68 61 74 20 74  ieces, so that t
0720: 68 65 79 20 77 69 6c 6c 20 77 6f 72 6b 20 65 76  hey will work ev
0730: 65 6e 20 6f 6e 20 0a 2a 2a 20 66 69 6c 65 73 79  en on .** filesy
0740: 73 74 65 6d 73 20 74 68 61 74 20 64 6f 20 6e 6f  stems that do no
0750: 74 20 73 75 70 70 6f 72 74 20 6c 61 72 67 65 20  t support large 
0760: 66 69 6c 65 73 2e 20 20 54 68 65 20 64 65 66 61  files.  The defa
0770: 75 6c 74 20 63 68 75 6e 6b 20 73 69 7a 65 0a 2a  ult chunk size.*
0780: 2a 20 69 73 20 32 31 34 37 34 31 38 31 31 32 20  * is 2147418112 
0790: 62 79 74 65 73 20 28 77 68 69 63 68 20 69 73 20  bytes (which is 
07a0: 36 34 4b 69 42 20 6c 65 73 73 20 74 68 61 6e 20  64KiB less than 
07b0: 32 47 69 42 29 20 62 75 74 20 74 68 69 73 20 63  2GiB) but this c
07c0: 61 6e 20 62 65 0a 2a 2a 20 63 68 61 6e 67 65 64  an be.** changed
07d0: 20 61 74 20 63 6f 6d 70 69 6c 65 2d 74 69 6d 65   at compile-time
07e0: 20 62 79 20 64 65 66 69 6e 69 6e 67 20 74 68 65   by defining the
07f0: 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45   SQLITE_MULTIPLE
0800: 58 5f 43 48 55 4e 4b 5f 53 49 5a 45 0a 2a 2a 20  X_CHUNK_SIZE.** 
0810: 6d 61 63 72 6f 2e 20 20 55 73 65 20 74 68 65 20  macro.  Use the 
0820: 22 63 68 75 6e 6b 73 69 7a 65 3d 4e 4e 4e 4e 22  "chunksize=NNNN"
0830: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
0840: 20 77 69 74 68 20 61 20 55 52 49 20 66 69 6c 65   with a URI file
0850: 6e 61 6d 65 0a 2a 2a 20 69 6e 20 6f 72 64 65 72  name.** in order
0860: 20 74 6f 20 73 65 6c 65 63 74 20 61 6e 20 61 6c   to select an al
0870: 74 65 72 6e 61 74 69 76 65 20 63 68 75 6e 6b 20  ternative chunk 
0880: 73 69 7a 65 20 66 6f 72 20 69 6e 64 69 76 69 64  size for individ
0890: 75 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 0a  ual connections.
08a0: 2a 2a 20 61 74 20 72 75 6e 2d 74 69 6d 65 2e 0a  ** at run-time..
08b0: 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c  */.#include "sql
08c0: 69 74 65 33 2e 68 22 0a 23 69 6e 63 6c 75 64 65  ite3.h".#include
08d0: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
08e0: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
08f0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0900: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 22 74 65  .h>.#include "te
0910: 73 74 5f 6d 75 6c 74 69 70 6c 65 78 2e 68 22 0a  st_multiplex.h".
0920: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
0930: 43 4f 52 45 0a 20 20 23 64 65 66 69 6e 65 20 53  CORE.  #define S
0940: 51 4c 49 54 45 5f 43 4f 52 45 20 31 20 20 2f 2a  QLITE_CORE 1  /*
0950: 20 44 69 73 61 62 6c 65 20 74 68 65 20 41 50 49   Disable the API
0960: 20 72 65 64 65 66 69 6e 69 74 69 6f 6e 20 69 6e   redefinition in
0970: 20 73 71 6c 69 74 65 33 65 78 74 2e 68 20 2a 2f   sqlite3ext.h */
0980: 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65  .#endif.#include
0990: 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22 0a   "sqlite3ext.h".
09a0: 0a 2f 2a 20 0a 2a 2a 20 54 68 65 73 65 20 73 68  ./* .** These sh
09b0: 6f 75 6c 64 20 62 65 20 64 65 66 69 6e 65 64 20  ould be defined 
09c0: 74 6f 20 62 65 20 74 68 65 20 73 61 6d 65 20 61  to be the same a
09d0: 73 20 74 68 65 20 76 61 6c 75 65 73 20 69 6e 20  s the values in 
09e0: 0a 2a 2a 20 73 71 6c 69 74 65 49 6e 74 2e 68 2e  .** sqliteInt.h.
09f0: 20 20 54 68 65 79 20 61 72 65 20 64 65 66 69 6e    They are defin
0a00: 65 64 20 73 65 70 65 72 61 74 65 6c 79 20 68 65  ed seperately he
0a10: 72 65 20 73 6f 20 74 68 61 74 0a 2a 2a 20 74 68  re so that.** th
0a20: 65 20 6d 75 6c 74 69 70 6c 65 78 20 56 46 53 20  e multiplex VFS 
0a30: 73 68 69 6d 20 63 61 6e 20 62 65 20 62 75 69 6c  shim can be buil
0a40: 74 20 61 73 20 61 20 6c 6f 61 64 61 62 6c 65 20  t as a loadable 
0a50: 0a 2a 2a 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 23  .** module..*/.#
0a60: 64 65 66 69 6e 65 20 55 4e 55 53 45 44 5f 50 41  define UNUSED_PA
0a70: 52 41 4d 45 54 45 52 28 78 29 20 28 76 6f 69 64  RAMETER(x) (void
0a80: 29 28 78 29 0a 23 64 65 66 69 6e 65 20 4d 41 58  )(x).#define MAX
0a90: 5f 50 41 47 45 5f 53 49 5a 45 20 20 20 20 20 20  _PAGE_SIZE      
0aa0: 20 30 78 31 30 30 30 30 0a 23 64 65 66 69 6e 65   0x10000.#define
0ab0: 20 44 45 46 41 55 4c 54 5f 53 45 43 54 4f 52 5f   DEFAULT_SECTOR_
0ac0: 53 49 5a 45 20 30 78 31 30 30 30 0a 0a 2f 2a 0a  SIZE 0x1000../*.
0ad0: 2a 2a 20 46 6f 72 20 61 20 62 75 69 6c 64 20 77  ** For a build w
0ae0: 69 74 68 6f 75 74 20 6d 75 74 65 78 65 73 2c 20  ithout mutexes, 
0af0: 6e 6f 2d 6f 70 20 74 68 65 20 6d 75 74 65 78 20  no-op the mutex 
0b00: 63 61 6c 6c 73 2e 0a 2a 2f 0a 23 69 66 20 64 65  calls..*/.#if de
0b10: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 48 52  fined(SQLITE_THR
0b20: 45 41 44 53 41 46 45 29 20 26 26 20 53 51 4c 49  EADSAFE) && SQLI
0b30: 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30  TE_THREADSAFE==0
0b40: 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33  .#define sqlite3
0b50: 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 58 29 20  _mutex_alloc(X) 
0b60: 20 20 20 28 28 73 71 6c 69 74 65 33 5f 6d 75 74     ((sqlite3_mut
0b70: 65 78 2a 29 38 29 0a 23 64 65 66 69 6e 65 20 73  ex*)8).#define s
0b80: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 66 72 65  qlite3_mutex_fre
0b90: 65 28 58 29 0a 23 64 65 66 69 6e 65 20 73 71 6c  e(X).#define sql
0ba0: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
0bb0: 28 58 29 0a 23 64 65 66 69 6e 65 20 73 71 6c 69  (X).#define sqli
0bc0: 74 65 33 5f 6d 75 74 65 78 5f 74 72 79 28 58 29  te3_mutex_try(X)
0bd0: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 4b 0a        SQLITE_OK.
0be0: 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f  #define sqlite3_
0bf0: 6d 75 74 65 78 5f 6c 65 61 76 65 28 58 29 0a 23  mutex_leave(X).#
0c00: 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f 6d  define sqlite3_m
0c10: 75 74 65 78 5f 68 65 6c 64 28 58 29 20 20 20 20  utex_held(X)    
0c20: 20 28 28 76 6f 69 64 29 28 58 29 2c 31 29 0a 23   ((void)(X),1).#
0c30: 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f 6d  define sqlite3_m
0c40: 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 58 29 20  utex_notheld(X) 
0c50: 20 28 28 76 6f 69 64 29 28 58 29 2c 31 29 0a 23   ((void)(X),1).#
0c60: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
0c70: 54 48 52 45 41 44 53 41 46 45 3d 3d 30 20 2a 2f  THREADSAFE==0 */
0c80: 0a 0a 2f 2a 20 4d 61 78 69 6d 75 6d 20 63 68 75  ../* Maximum chu
0c90: 6e 6b 20 6e 75 6d 62 65 72 20 2a 2f 0a 23 64 65  nk number */.#de
0ca0: 66 69 6e 65 20 4d 58 5f 43 48 55 4e 4b 5f 4e 55  fine MX_CHUNK_NU
0cb0: 4d 42 45 52 20 32 39 39 0a 0a 2f 2a 20 46 69 72  MBER 299../* Fir
0cc0: 73 74 20 63 68 75 6e 6b 20 66 6f 72 20 72 6f 6c  st chunk for rol
0cd0: 6c 62 61 63 6b 20 6a 6f 75 72 6e 61 6c 20 66 69  lback journal fi
0ce0: 6c 65 73 20 2a 2f 0a 23 64 65 66 69 6e 65 20 53  les */.#define S
0cf0: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
0d00: 4a 4f 55 52 4e 41 4c 5f 38 5f 33 5f 4f 46 46 53  JOURNAL_8_3_OFFS
0d10: 45 54 20 34 30 30 0a 23 64 65 66 69 6e 65 20 53  ET 400.#define S
0d20: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
0d30: 57 41 4c 5f 38 5f 33 5f 4f 46 46 53 45 54 20 37  WAL_8_3_OFFSET 7
0d40: 30 30 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  00.../**********
0d50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 53  ************** S
0d60: 68 69 6d 20 44 65 66 69 6e 69 74 69 6f 6e 73 20  him Definitions 
0d70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0d80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
0d90: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
0da0: 4d 55 4c 54 49 50 4c 45 58 5f 56 46 53 5f 4e 41  MULTIPLEX_VFS_NA
0db0: 4d 45 0a 23 20 64 65 66 69 6e 65 20 53 51 4c 49  ME.# define SQLI
0dc0: 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f 56 46 53  TE_MULTIPLEX_VFS
0dd0: 5f 4e 41 4d 45 20 22 6d 75 6c 74 69 70 6c 65 78  _NAME "multiplex
0de0: 22 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 54 68 69  ".#endif../* Thi
0df0: 73 20 69 73 20 74 68 65 20 6c 69 6d 69 74 20 6f  s is the limit o
0e00: 6e 20 74 68 65 20 63 68 75 6e 6b 20 73 69 7a 65  n the chunk size
0e10: 2e 20 20 49 74 20 6d 61 79 20 62 65 20 63 68 61  .  It may be cha
0e20: 6e 67 65 64 20 62 79 20 63 61 6c 6c 69 6e 67 0a  nged by calling.
0e30: 2a 2a 20 74 68 65 20 78 46 69 6c 65 43 6f 6e 74  ** the xFileCont
0e40: 72 6f 6c 28 29 20 69 6e 74 65 72 66 61 63 65 2e  rol() interface.
0e50: 20 20 49 74 20 77 69 6c 6c 20 62 65 20 72 6f 75    It will be rou
0e60: 6e 64 65 64 20 75 70 20 74 6f 20 61 20 0a 2a 2a  nded up to a .**
0e70: 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 4d 41 58   multiple of MAX
0e80: 5f 50 41 47 45 5f 53 49 5a 45 2e 20 20 57 65 20  _PAGE_SIZE.  We 
0e90: 64 65 66 61 75 6c 74 20 69 74 20 68 65 72 65 20  default it here 
0ea0: 74 6f 20 32 47 69 42 20 6c 65 73 73 20 36 34 4b  to 2GiB less 64K
0eb0: 69 42 2e 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 53  iB..*/.#ifndef S
0ec0: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
0ed0: 43 48 55 4e 4b 5f 53 49 5a 45 0a 23 20 64 65 66  CHUNK_SIZE.# def
0ee0: 69 6e 65 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49  ine SQLITE_MULTI
0ef0: 50 4c 45 58 5f 43 48 55 4e 4b 5f 53 49 5a 45 20  PLEX_CHUNK_SIZE 
0f00: 32 31 34 37 34 31 38 31 31 32 0a 23 65 6e 64 69  2147418112.#endi
0f10: 66 0a 0a 2f 2a 20 54 68 69 73 20 75 73 65 64 20  f../* This used 
0f20: 74 6f 20 62 65 20 74 68 65 20 64 65 66 61 75 6c  to be the defaul
0f30: 74 20 6c 69 6d 69 74 20 6f 6e 20 6e 75 6d 62 65  t limit on numbe
0f40: 72 20 6f 66 20 63 68 75 6e 6b 73 2c 20 62 75 74  r of chunks, but
0f50: 0a 2a 2a 20 69 74 20 69 73 20 6e 6f 20 6c 6f 6e  .** it is no lon
0f60: 67 65 72 20 65 6e 66 6f 72 63 65 64 2e 20 54 68  ger enforced. Th
0f70: 65 72 65 20 69 73 20 63 75 72 72 65 6e 74 6c 79  ere is currently
0f80: 20 6e 6f 20 6c 69 6d 69 74 20 74 6f 20 74 68 65   no limit to the
0f90: 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 63 68  .** number of ch
0fa0: 75 6e 6b 73 2e 0a 2a 2a 0a 2a 2a 20 4d 61 79 20  unks..**.** May 
0fb0: 62 65 20 63 68 61 6e 67 65 64 20 62 79 20 63 61  be changed by ca
0fc0: 6c 6c 69 6e 67 20 74 68 65 20 78 46 69 6c 65 43  lling the xFileC
0fd0: 6f 6e 74 72 6f 6c 28 29 20 69 6e 74 65 72 66 61  ontrol() interfa
0fe0: 63 65 2e 0a 2a 2f 0a 23 69 66 6e 64 65 66 20 53  ce..*/.#ifndef S
0ff0: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
1000: 4d 41 58 5f 43 48 55 4e 4b 53 0a 23 20 64 65 66  MAX_CHUNKS.# def
1010: 69 6e 65 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49  ine SQLITE_MULTI
1020: 50 4c 45 58 5f 4d 41 58 5f 43 48 55 4e 4b 53 20  PLEX_MAX_CHUNKS 
1030: 31 32 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a  12.#endif../****
1040: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1050: 2a 2a 2a 2a 20 4f 62 6a 65 63 74 20 44 65 66 69  **** Object Defi
1060: 6e 69 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nitions ********
1070: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1080: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 46 6f 72 77  ******/../* Forw
1090: 61 72 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 20  ard declaration 
10a0: 6f 66 20 61 6c 6c 20 6f 62 6a 65 63 74 20 74 79  of all object ty
10b0: 70 65 73 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  pes */.typedef s
10c0: 74 72 75 63 74 20 6d 75 6c 74 69 70 6c 65 78 47  truct multiplexG
10d0: 72 6f 75 70 20 6d 75 6c 74 69 70 6c 65 78 47 72  roup multiplexGr
10e0: 6f 75 70 3b 0a 74 79 70 65 64 65 66 20 73 74 72  oup;.typedef str
10f0: 75 63 74 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e  uct multiplexCon
1100: 6e 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 3b  n multiplexConn;
1110: 0a 0a 2f 2a 0a 2a 2a 20 41 20 22 6d 75 6c 74 69  ../*.** A "multi
1120: 70 6c 65 78 20 67 72 6f 75 70 22 20 69 73 20 61  plex group" is a
1130: 20 63 6f 6c 6c 65 63 74 69 6f 6e 20 6f 66 20 66   collection of f
1140: 69 6c 65 73 20 74 68 61 74 20 63 6f 6c 6c 65 63  iles that collec
1150: 74 69 76 65 6c 79 0a 2a 2a 20 6d 61 6b 65 75 70  tively.** makeup
1160: 20 61 20 73 69 6e 67 6c 65 20 53 51 4c 69 74 65   a single SQLite
1170: 20 44 42 20 66 69 6c 65 2e 20 20 54 68 69 73 20   DB file.  This 
1180: 61 6c 6c 6f 77 73 20 74 68 65 20 73 69 7a 65 20  allows the size 
1190: 6f 66 20 74 68 65 20 44 42 0a 2a 2a 20 74 6f 20  of the DB.** to 
11a0: 65 78 63 65 65 64 20 74 68 65 20 6c 69 6d 69 74  exceed the limit
11b0: 73 20 69 6d 70 6f 73 65 64 20 62 79 20 74 68 65  s imposed by the
11c0: 20 66 69 6c 65 20 73 79 73 74 65 6d 2e 0a 2a 2a   file system..**
11d0: 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 61 6e 20  .** There is an 
11e0: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20  instance of the 
11f0: 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74  following object
1200: 20 66 6f 72 20 65 61 63 68 20 64 65 66 69 6e 65   for each define
1210: 64 20 6d 75 6c 74 69 70 6c 65 78 0a 2a 2a 20 67  d multiplex.** g
1220: 72 6f 75 70 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  roup..*/.struct 
1230: 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 7b  multiplexGroup {
1240: 0a 20 20 73 74 72 75 63 74 20 6d 75 6c 74 69 70  .  struct multip
1250: 6c 65 78 52 65 61 6c 20 7b 20 20 20 20 20 20 20  lexReal {       
1260: 20 20 20 20 2f 2a 20 46 6f 72 20 65 61 63 68 20      /* For each 
1270: 63 68 75 6e 6b 20 2a 2f 0a 20 20 20 20 73 71 6c  chunk */.    sql
1280: 69 74 65 33 5f 66 69 6c 65 20 2a 70 3b 20 20 20  ite3_file *p;   
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12a0: 2a 20 48 61 6e 64 6c 65 20 66 6f 72 20 74 68 65  * Handle for the
12b0: 20 63 68 75 6e 6b 20 2a 2f 0a 20 20 20 20 63 68   chunk */.    ch
12c0: 61 72 20 2a 7a 3b 20 20 20 20 20 20 20 20 20 20  ar *z;          
12d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e0: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 69 73 20  /* Name of this 
12f0: 63 68 75 6e 6b 20 2a 2f 0a 20 20 7d 20 2a 61 52  chunk */.  } *aR
1300: 65 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  eal;            
1310: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6c              /* l
1320: 69 73 74 20 6f 66 20 61 6c 6c 20 63 68 75 6e 6b  ist of all chunk
1330: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 61 6c  s */.  int nReal
1340: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1350: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1360: 72 20 6f 66 20 63 68 75 6e 6b 73 20 2a 2f 0a 20  r of chunks */. 
1370: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20   char *zName;   
1380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1390: 20 20 2f 2a 20 42 61 73 65 20 66 69 6c 65 6e 61    /* Base filena
13a0: 6d 65 20 6f 66 20 74 68 69 73 20 67 72 6f 75 70  me of this group
13b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 61 6d 65 3b   */.  int nName;
13c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13d0: 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68         /* Length
13e0: 20 6f 66 20 62 61 73 65 20 66 69 6c 65 6e 61 6d   of base filenam
13f0: 65 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73  e */.  int flags
1400: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1410: 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
1420: 20 75 73 65 64 20 66 6f 72 20 6f 72 69 67 69 6e   used for origin
1430: 61 6c 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a 20 20  al opening */.  
1440: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 7a 43  unsigned int szC
1450: 68 75 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20  hunk;           
1460: 20 2f 2a 20 43 68 75 6e 6b 20 73 69 7a 65 20 75   /* Chunk size u
1470: 73 65 64 20 66 6f 72 20 74 68 69 73 20 67 72 6f  sed for this gro
1480: 75 70 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  up */.  unsigned
1490: 20 63 68 61 72 20 62 45 6e 61 62 6c 65 64 3b 20   char bEnabled; 
14a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 52 55 45           /* TRUE
14b0: 20 74 6f 20 75 73 65 20 4d 75 6c 74 69 70 6c 65   to use Multiple
14c0: 78 20 56 46 53 20 66 6f 72 20 74 68 69 73 20 66  x VFS for this f
14d0: 69 6c 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ile */.  unsigne
14e0: 64 20 63 68 61 72 20 62 54 72 75 6e 63 61 74 65  d char bTruncate
14f0: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 54 52 55  ;         /* TRU
1500: 45 20 74 6f 20 65 6e 61 62 6c 65 20 74 72 75 6e  E to enable trun
1510: 63 61 74 69 6f 6e 20 6f 66 20 64 61 74 61 62 61  cation of databa
1520: 73 65 73 20 2a 2f 0a 20 20 6d 75 6c 74 69 70 6c  ses */.  multipl
1530: 65 78 47 72 6f 75 70 20 2a 70 4e 65 78 74 2c 20  exGroup *pNext, 
1540: 2a 70 50 72 65 76 3b 20 20 20 2f 2a 20 44 6f 75  *pPrev;   /* Dou
1550: 62 6c 79 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20  bly linked list 
1560: 6f 66 20 61 6c 6c 20 67 72 6f 75 70 20 6f 62 6a  of all group obj
1570: 65 63 74 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ects */.};../*.*
1580: 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  * An instance of
1590: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   the following o
15a0: 62 6a 65 63 74 20 72 65 70 72 65 73 65 6e 74 73  bject represents
15b0: 20 65 61 63 68 20 6f 70 65 6e 20 63 6f 6e 6e 65   each open conne
15c0: 63 74 69 6f 6e 0a 2a 2a 20 74 6f 20 61 20 66 69  ction.** to a fi
15d0: 6c 65 20 74 68 61 74 20 69 73 20 6d 75 6c 74 69  le that is multi
15e0: 70 6c 65 78 27 65 64 2e 20 20 54 68 69 73 20 6f  plex'ed.  This o
15f0: 62 6a 65 63 74 20 69 73 20 61 20 0a 2a 2a 20 73  bject is a .** s
1600: 75 62 63 6c 61 73 73 20 6f 66 20 73 71 6c 69 74  ubclass of sqlit
1610: 65 33 5f 66 69 6c 65 2e 20 20 54 68 65 20 73 71  e3_file.  The sq
1620: 6c 69 74 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63  lite3_file objec
1630: 74 20 66 6f 72 20 74 68 65 20 75 6e 64 65 72 6c  t for the underl
1640: 79 69 6e 67 0a 2a 2a 20 56 46 53 20 69 73 20 61  ying.** VFS is a
1650: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 69 73 20  ppended to this 
1660: 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74  structure..*/.st
1670: 72 75 63 74 20 6d 75 6c 74 69 70 6c 65 78 43 6f  ruct multiplexCo
1680: 6e 6e 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  nn {.  sqlite3_f
1690: 69 6c 65 20 62 61 73 65 3b 20 20 20 20 20 20 20  ile base;       
16a0: 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63         /* Base c
16b0: 6c 61 73 73 20 2d 20 6d 75 73 74 20 62 65 20 66  lass - must be f
16c0: 69 72 73 74 20 2a 2f 0a 20 20 6d 75 6c 74 69 70  irst */.  multip
16d0: 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  lexGroup *pGroup
16e0: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65  ;         /* The
16f0: 20 75 6e 64 65 72 6c 79 69 6e 67 20 67 72 6f 75   underlying grou
1700: 70 20 6f 66 20 66 69 6c 65 73 20 2a 2f 0a 7d 3b  p of files */.};
1710: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
1720: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47 6c 6f  ************ Glo
1730: 62 61 6c 20 56 61 72 69 61 62 6c 65 73 20 2a 2a  bal Variables **
1740: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1750: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1760: 2f 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 67 6c 6f 62  /./*.** All glob
1770: 61 6c 20 76 61 72 69 61 62 6c 65 73 20 75 73 65  al variables use
1780: 64 20 62 79 20 74 68 69 73 20 66 69 6c 65 20 61  d by this file a
1790: 72 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 77 69  re containing wi
17a0: 74 68 69 6e 20 74 68 65 20 66 6f 6c 6c 6f 77 69  thin the followi
17b0: 6e 67 0a 2a 2a 20 67 4d 75 6c 74 69 70 6c 65 78  ng.** gMultiplex
17c0: 20 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73   structure..*/.s
17d0: 74 61 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20  tatic struct {. 
17e0: 20 2f 2a 20 54 68 65 20 70 4f 72 69 67 56 66 73   /* The pOrigVfs
17f0: 20 69 73 20 74 68 65 20 72 65 61 6c 2c 20 6f 72   is the real, or
1800: 69 67 69 6e 61 6c 20 75 6e 64 65 72 6c 79 69 6e  iginal underlyin
1810: 67 20 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61  g VFS implementa
1820: 74 69 6f 6e 2e 0a 20 20 2a 2a 20 4d 6f 73 74 20  tion..  ** Most 
1830: 6f 70 65 72 61 74 69 6f 6e 73 20 70 61 73 73 2d  operations pass-
1840: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 72  through to the r
1850: 65 61 6c 20 56 46 53 2e 20 20 54 68 69 73 20 76  eal VFS.  This v
1860: 61 6c 75 65 20 69 73 20 72 65 61 64 2d 6f 6e 6c  alue is read-onl
1870: 79 0a 20 20 2a 2a 20 64 75 72 69 6e 67 20 6f 70  y.  ** during op
1880: 65 72 61 74 69 6f 6e 2e 20 20 49 74 20 69 73 20  eration.  It is 
1890: 6f 6e 6c 79 20 6d 6f 64 69 66 69 65 64 20 61 74  only modified at
18a0: 20 73 74 61 72 74 2d 74 69 6d 65 20 61 6e 64 20   start-time and 
18b0: 74 68 75 73 20 64 6f 65 73 20 6e 6f 74 0a 20 20  thus does not.  
18c0: 2a 2a 20 72 65 71 75 69 72 65 20 61 20 6d 75 74  ** require a mut
18d0: 65 78 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74  ex..  */.  sqlit
18e0: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
18f0: 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 73 54 68 69  ;..  /* The sThi
1900: 73 56 66 73 20 69 73 20 74 68 65 20 56 46 53 20  sVfs is the VFS 
1910: 73 74 72 75 63 74 75 72 65 20 75 73 65 64 20 62  structure used b
1920: 79 20 74 68 69 73 20 73 68 69 6d 2e 20 20 49 74  y this shim.  It
1930: 20 69 73 20 69 6e 69 74 69 61 6c 69 7a 65 64 0a   is initialized.
1940: 20 20 2a 2a 20 61 74 20 73 74 61 72 74 2d 74 69    ** at start-ti
1950: 6d 65 20 61 6e 64 20 74 68 75 73 20 64 6f 65 73  me and thus does
1960: 20 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20 6d   not require a m
1970: 75 74 65 78 0a 20 20 2a 2f 0a 20 20 73 71 6c 69  utex.  */.  sqli
1980: 74 65 33 5f 76 66 73 20 73 54 68 69 73 56 66 73  te3_vfs sThisVfs
1990: 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 73 49 6f 4d  ;..  /* The sIoM
19a0: 65 74 68 6f 64 73 20 64 65 66 69 6e 65 73 20 74  ethods defines t
19b0: 68 65 20 6d 65 74 68 6f 64 73 20 75 73 65 64 20  he methods used 
19c0: 62 79 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  by sqlite3_file 
19d0: 6f 62 6a 65 63 74 73 20 0a 20 20 2a 2a 20 61 73  objects .  ** as
19e0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
19f0: 69 73 20 73 68 69 6d 2e 20 20 49 74 20 69 73 20  is shim.  It is 
1a00: 69 6e 69 74 69 61 6c 69 7a 65 64 20 61 74 20 73  initialized at s
1a10: 74 61 72 74 2d 74 69 6d 65 20 61 6e 64 20 64 6f  tart-time and do
1a20: 65 73 0a 20 20 2a 2a 20 6e 6f 74 20 72 65 71 75  es.  ** not requ
1a30: 69 72 65 20 61 20 6d 75 74 65 78 2e 0a 20 20 2a  ire a mutex..  *
1a40: 2a 0a 20 20 2a 2a 20 57 68 65 6e 20 74 68 65 20  *.  ** When the 
1a50: 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20 69  underlying VFS i
1a60: 73 20 63 61 6c 6c 65 64 20 74 6f 20 6f 70 65 6e  s called to open
1a70: 20 61 20 66 69 6c 65 2c 20 69 74 20 6d 69 67 68   a file, it migh
1a80: 74 20 72 65 74 75 72 6e 20 0a 20 20 2a 2a 20 65  t return .  ** e
1a90: 69 74 68 65 72 20 61 20 76 65 72 73 69 6f 6e 20  ither a version 
1aa0: 31 20 6f 72 20 61 20 76 65 72 73 69 6f 6e 20 32  1 or a version 2
1ab0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 6f 62   sqlite3_file ob
1ac0: 6a 65 63 74 2e 20 20 54 68 69 73 20 73 68 69 6d  ject.  This shim
1ad0: 0a 20 20 2a 2a 20 68 61 73 20 74 6f 20 63 72 65  .  ** has to cre
1ae0: 61 74 65 20 61 20 77 72 61 70 70 65 72 20 73 71  ate a wrapper sq
1af0: 6c 69 74 65 33 5f 66 69 6c 65 20 6f 66 20 74 68  lite3_file of th
1b00: 65 20 73 61 6d 65 20 76 65 72 73 69 6f 6e 2e 20  e same version. 
1b10: 20 48 65 6e 63 65 0a 20 20 2a 2a 20 74 68 65 72   Hence.  ** ther
1b20: 65 20 61 72 65 20 74 77 6f 20 49 2f 4f 20 6d 65  e are two I/O me
1b30: 74 68 6f 64 20 73 74 72 75 63 74 75 72 65 73 2c  thod structures,
1b40: 20 6f 6e 65 20 66 6f 72 20 76 65 72 73 69 6f 6e   one for version
1b50: 20 31 20 61 6e 64 20 74 68 65 20 6f 74 68 65 72   1 and the other
1b60: 0a 20 20 2a 2a 20 66 6f 72 20 76 65 72 73 69 6f  .  ** for versio
1b70: 6e 20 32 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69  n 2..  */.  sqli
1b80: 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 73  te3_io_methods s
1b90: 49 6f 4d 65 74 68 6f 64 73 56 31 3b 0a 20 20 73  IoMethodsV1;.  s
1ba0: 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64  qlite3_io_method
1bb0: 73 20 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b 0a  s sIoMethodsV2;.
1bc0: 0a 20 20 2f 2a 20 54 72 75 65 20 77 68 65 6e 20  .  /* True when 
1bd0: 74 68 69 73 20 73 68 69 6d 20 68 61 73 20 62 65  this shim has be
1be0: 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65 64 2e 0a  en initialized..
1bf0: 20 20 2a 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69    */.  int isIni
1c00: 74 69 61 6c 69 7a 65 64 3b 0a 0a 20 20 2f 2a 20  tialized;..  /* 
1c10: 46 6f 72 20 72 75 6e 2d 74 69 6d 65 20 61 63 63  For run-time acc
1c20: 65 73 73 20 61 6e 79 20 6f 66 20 74 68 65 20 6f  ess any of the o
1c30: 74 68 65 72 20 67 6c 6f 62 61 6c 20 64 61 74 61  ther global data
1c40: 20 73 74 72 75 63 74 75 72 65 73 20 69 6e 20 74   structures in t
1c50: 68 69 73 0a 20 20 2a 2a 20 73 68 69 6d 2c 20 74  his.  ** shim, t
1c60: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6d 75 74  he following mut
1c70: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 2e  ex must be held.
1c80: 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  .  */.  sqlite3_
1c90: 6d 75 74 65 78 20 2a 70 4d 75 74 65 78 3b 0a 0a  mutex *pMutex;..
1ca0: 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 6d 75 6c    /* List of mul
1cb0: 74 69 70 6c 65 78 47 72 6f 75 70 20 6f 62 6a 65  tiplexGroup obje
1cc0: 63 74 73 2e 0a 20 20 2a 2f 0a 20 20 6d 75 6c 74  cts..  */.  mult
1cd0: 69 70 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f  iplexGroup *pGro
1ce0: 75 70 73 3b 0a 7d 20 67 4d 75 6c 74 69 70 6c 65  ups;.} gMultiple
1cf0: 78 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  x;../***********
1d00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 55  ************** U
1d10: 74 69 6c 69 74 79 20 52 6f 75 74 69 6e 65 73 20  tility Routines 
1d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1d30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1d40: 2a 2f 0a 2f 2a 0a 2a 2a 20 41 63 71 75 69 72 65  */./*.** Acquire
1d50: 20 61 6e 64 20 72 65 6c 65 61 73 65 20 74 68 65   and release the
1d60: 20 6d 75 74 65 78 20 75 73 65 64 20 74 6f 20 73   mutex used to s
1d70: 65 72 69 61 6c 69 7a 65 20 61 63 63 65 73 73 20  erialize access 
1d80: 74 6f 20 74 68 65 0a 2a 2a 20 6c 69 73 74 20 6f  to the.** list o
1d90: 66 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70  f multiplexGroup
1da0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
1db0: 64 20 6d 75 6c 74 69 70 6c 65 78 45 6e 74 65 72  d multiplexEnter
1dc0: 28 76 6f 69 64 29 7b 20 73 71 6c 69 74 65 33 5f  (void){ sqlite3_
1dd0: 6d 75 74 65 78 5f 65 6e 74 65 72 28 67 4d 75 6c  mutex_enter(gMul
1de0: 74 69 70 6c 65 78 2e 70 4d 75 74 65 78 29 3b 20  tiplex.pMutex); 
1df0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75  }.static void mu
1e00: 6c 74 69 70 6c 65 78 4c 65 61 76 65 28 76 6f 69  ltiplexLeave(voi
1e10: 64 29 7b 20 73 71 6c 69 74 65 33 5f 6d 75 74 65  d){ sqlite3_mute
1e20: 78 5f 6c 65 61 76 65 28 67 4d 75 6c 74 69 70 6c  x_leave(gMultipl
1e30: 65 78 2e 70 4d 75 74 65 78 29 3b 20 7d 0a 0a 2f  ex.pMutex); }../
1e40: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 73  *.** Compute a s
1e50: 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 74 68 61  tring length tha
1e60: 74 20 69 73 20 6c 69 6d 69 74 65 64 20 74 6f 20  t is limited to 
1e70: 77 68 61 74 20 63 61 6e 20 62 65 20 73 74 6f 72  what can be stor
1e80: 65 64 20 69 6e 0a 2a 2a 20 6c 6f 77 65 72 20 33  ed in.** lower 3
1e90: 30 20 62 69 74 73 20 6f 66 20 61 20 33 32 2d 62  0 bits of a 32-b
1ea0: 69 74 20 73 69 67 6e 65 64 20 69 6e 74 65 67 65  it signed intege
1eb0: 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  r..**.** The val
1ec0: 75 65 20 72 65 74 75 72 6e 65 64 20 77 69 6c 6c  ue returned will
1ed0: 20 6e 65 76 65 72 20 62 65 20 6e 65 67 61 74 69   never be negati
1ee0: 76 65 2e 20 20 4e 6f 72 20 77 69 6c 6c 20 69 74  ve.  Nor will it
1ef0: 20 65 76 65 72 20 62 65 20 67 72 65 61 74 65 72   ever be greater
1f00: 0a 2a 2a 20 74 68 61 6e 20 74 68 65 20 61 63 74  .** than the act
1f10: 75 61 6c 20 6c 65 6e 67 74 68 20 6f 66 20 74 68  ual length of th
1f20: 65 20 73 74 72 69 6e 67 2e 20 20 46 6f 72 20 76  e string.  For v
1f30: 65 72 79 20 6c 6f 6e 67 20 73 74 72 69 6e 67 73  ery long strings
1f40: 20 28 67 72 65 61 74 65 72 0a 2a 2a 20 74 68 61   (greater.** tha
1f50: 6e 20 31 47 69 42 29 20 74 68 65 20 76 61 6c 75  n 1GiB) the valu
1f60: 65 20 72 65 74 75 72 6e 65 64 20 6d 69 67 68 74  e returned might
1f70: 20 62 65 20 6c 65 73 73 20 74 68 61 6e 20 74 68   be less than th
1f80: 65 20 74 72 75 65 20 73 74 72 69 6e 67 20 6c 65  e true string le
1f90: 6e 67 74 68 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ngth..*/.static 
1fa0: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53 74 72  int multiplexStr
1fb0: 6c 65 6e 33 30 28 63 6f 6e 73 74 20 63 68 61 72  len30(const char
1fc0: 20 2a 7a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68   *z){.  const ch
1fd0: 61 72 20 2a 7a 32 20 3d 20 7a 3b 0a 20 20 69 66  ar *z2 = z;.  if
1fe0: 28 20 7a 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( z==0 ) return 
1ff0: 30 3b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 32 20  0;.  while( *z2 
2000: 29 7b 20 7a 32 2b 2b 3b 20 7d 0a 20 20 72 65 74  ){ z2++; }.  ret
2010: 75 72 6e 20 30 78 33 66 66 66 66 66 66 66 20 26  urn 0x3fffffff &
2020: 20 28 69 6e 74 29 28 7a 32 20 2d 20 7a 29 3b 0a   (int)(z2 - z);.
2030: 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74  }../*.** Generat
2040: 65 20 74 68 65 20 66 69 6c 65 2d 6e 61 6d 65 20  e the file-name 
2050: 66 6f 72 20 63 68 75 6e 6b 20 69 43 68 75 6e 6b  for chunk iChunk
2060: 20 6f 66 20 74 68 65 20 67 72 6f 75 70 20 77 69   of the group wi
2070: 74 68 20 62 61 73 65 20 6e 61 6d 65 0a 2a 2a 20  th base name.** 
2080: 7a 42 61 73 65 2e 20 54 68 65 20 66 69 6c 65 2d  zBase. The file-
2090: 6e 61 6d 65 20 69 73 20 77 72 69 74 74 65 6e 20  name is written 
20a0: 74 6f 20 62 75 66 66 65 72 20 7a 4f 75 74 20 62  to buffer zOut b
20b0: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
20c0: 20 42 75 66 66 65 72 0a 2a 2a 20 7a 4f 75 74 20   Buffer.** zOut 
20d0: 6d 75 73 74 20 62 65 20 61 6c 6c 6f 63 61 74 65  must be allocate
20e0: 64 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 20  d by the caller 
20f0: 73 6f 20 74 68 61 74 20 69 74 20 69 73 20 61 74  so that it is at
2100: 20 6c 65 61 73 74 20 28 6e 42 61 73 65 2b 35 29   least (nBase+5)
2110: 0a 2a 2a 20 62 79 74 65 73 20 69 6e 20 73 69 7a  .** bytes in siz
2120: 65 2c 20 77 68 65 72 65 20 6e 42 61 73 65 20 69  e, where nBase i
2130: 73 20 74 68 65 20 6c 65 6e 67 74 68 20 6f 66 20  s the length of 
2140: 7a 42 61 73 65 2c 20 6e 6f 74 20 69 6e 63 6c 75  zBase, not inclu
2150: 64 69 6e 67 20 74 68 65 0a 2a 2a 20 6e 75 6c 2d  ding the.** nul-
2160: 74 65 72 6d 69 6e 61 74 6f 72 2e 0a 2a 2a 0a 2a  terminator..**.*
2170: 2a 20 49 66 20 69 43 68 75 6e 6b 20 69 73 20 30  * If iChunk is 0
2180: 20 28 6f 72 20 34 30 30 20 2d 20 74 68 65 20 6e   (or 400 - the n
2190: 75 6d 62 65 72 20 66 6f 72 20 74 68 65 20 66 69  umber for the fi
21a0: 72 73 74 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65  rst journal file
21b0: 20 63 68 75 6e 6b 29 2c 0a 2a 2a 20 74 68 65 20   chunk),.** the 
21c0: 6f 75 74 70 75 74 20 69 73 20 61 20 63 6f 70 79  output is a copy
21d0: 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 73 74   of the input st
21e0: 72 69 6e 67 2e 20 4f 74 68 65 72 77 69 73 65 2c  ring. Otherwise,
21f0: 20 69 66 20 0a 2a 2a 20 53 51 4c 49 54 45 5f 45   if .** SQLITE_E
2200: 4e 41 42 4c 45 5f 38 5f 33 5f 4e 41 4d 45 53 20  NABLE_8_3_NAMES 
2210: 69 73 20 6e 6f 74 20 64 65 66 69 6e 65 64 20 6f  is not defined o
2220: 72 20 74 68 65 20 69 6e 70 75 74 20 62 75 66 66  r the input buff
2230: 65 72 20 64 6f 65 73 20 6e 6f 74 20 63 6f 6e 74  er does not cont
2240: 61 69 6e 0a 2a 2a 20 61 20 22 2e 22 20 63 68 61  ain.** a "." cha
2250: 72 61 63 74 65 72 2c 20 74 68 65 6e 20 74 68 65  racter, then the
2260: 20 6f 75 74 70 75 74 20 69 73 20 61 20 63 6f 70   output is a cop
2270: 79 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 73  y of the input s
2280: 74 72 69 6e 67 20 77 69 74 68 20 74 68 65 20 0a  tring with the .
2290: 2a 2a 20 74 68 72 65 65 2d 64 69 67 69 74 20 7a  ** three-digit z
22a0: 65 72 6f 2d 70 61 64 64 65 64 20 64 65 63 69 6d  ero-padded decim
22b0: 61 6c 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f  al representatio
22c0: 6e 20 69 66 20 69 43 68 75 6e 6b 20 61 70 70 65  n if iChunk appe
22d0: 6e 64 65 64 20 74 6f 20 69 74 2e 20 0a 2a 2a 20  nded to it. .** 
22e0: 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a  For example:.**.
22f0: 2a 2a 20 20 20 7a 42 61 73 65 3d 22 74 65 73 74  **   zBase="test
2300: 2e 64 62 22 2c 20 69 43 68 75 6e 6b 3d 34 20 20  .db", iChunk=4  
2310: 2d 3e 20 20 7a 4f 75 74 3d 22 74 65 73 74 2e 64  ->  zOut="test.d
2320: 62 30 30 34 22 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20  b004".**.** Or, 
2330: 69 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  if SQLITE_ENABLE
2340: 5f 38 5f 33 5f 4e 41 4d 45 53 20 69 73 20 64 65  _8_3_NAMES is de
2350: 66 69 6e 65 64 20 61 6e 64 20 74 68 65 20 69 6e  fined and the in
2360: 70 75 74 20 62 75 66 66 65 72 20 63 6f 6e 74 61  put buffer conta
2370: 69 6e 73 0a 2a 2a 20 61 20 22 2e 22 20 63 68 61  ins.** a "." cha
2380: 72 61 63 74 65 72 2c 20 74 68 65 6e 20 65 76 65  racter, then eve
2390: 72 79 74 68 69 6e 67 20 61 66 74 65 72 20 74 68  rything after th
23a0: 65 20 22 2e 22 20 69 73 20 72 65 70 6c 61 63 65  e "." is replace
23b0: 64 20 62 79 20 74 68 65 20 0a 2a 2a 20 74 68 72  d by the .** thr
23c0: 65 65 2d 64 69 67 69 74 20 72 65 70 72 65 73 65  ee-digit represe
23d0: 6e 74 61 74 69 6f 6e 20 6f 66 20 69 43 68 75 6e  ntation of iChun
23e0: 6b 2e 0a 2a 2a 0a 2a 2a 20 20 20 7a 42 61 73 65  k..**.**   zBase
23f0: 3d 22 74 65 73 74 2e 64 62 22 2c 20 69 43 68 75  ="test.db", iChu
2400: 6e 6b 3d 34 20 20 2d 3e 20 20 7a 4f 75 74 3d 22  nk=4  ->  zOut="
2410: 74 65 73 74 2e 30 30 34 22 0a 2a 2a 0a 2a 2a 20  test.004".**.** 
2420: 54 68 65 20 6f 75 74 70 75 74 20 62 75 66 66 65  The output buffe
2430: 72 20 73 74 72 69 6e 67 20 69 73 20 74 65 72 6d  r string is term
2440: 69 6e 61 74 65 64 20 62 79 20 32 20 30 78 30 30  inated by 2 0x00
2450: 20 62 79 74 65 73 2e 20 54 68 69 73 20 6d 61 6b   bytes. This mak
2460: 65 73 20 69 74 20 73 61 66 65 0a 2a 2a 20 74 6f  es it safe.** to
2470: 20 70 61 73 73 20 74 6f 20 73 71 6c 69 74 65 33   pass to sqlite3
2480: 5f 75 72 69 5f 70 61 72 61 6d 65 74 65 72 28 29  _uri_parameter()
2490: 20 61 6e 64 20 73 69 6d 69 6c 61 72 2e 0a 2a 2f   and similar..*/
24a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c  .static void mul
24b0: 74 69 70 6c 65 78 46 69 6c 65 6e 61 6d 65 28 0a  tiplexFilename(.
24c0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 42    const char *zB
24d0: 61 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ase,            
24e0: 20 20 2f 2a 20 46 69 6c 65 6e 61 6d 65 20 66 6f    /* Filename fo
24f0: 72 20 63 68 75 6e 6b 20 30 20 2a 2f 0a 20 20 69  r chunk 0 */.  i
2500: 6e 74 20 6e 42 61 73 65 2c 20 20 20 20 20 20 20  nt nBase,       
2510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2520: 2a 20 53 69 7a 65 20 6f 66 20 7a 42 61 73 65 20  * Size of zBase 
2530: 69 6e 20 62 79 74 65 73 20 28 77 69 74 68 6f 75  in bytes (withou
2540: 74 20 5c 30 29 20 2a 2f 0a 20 20 69 6e 74 20 66  t \0) */.  int f
2550: 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20  lags,           
2560: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
2570: 61 67 73 20 75 73 65 64 20 74 6f 20 6f 70 65 6e  ags used to open
2580: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69   file */.  int i
2590: 43 68 75 6e 6b 2c 20 20 20 20 20 20 20 20 20 20  Chunk,          
25a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
25b0: 75 6e 6b 20 74 6f 20 67 65 6e 65 72 61 74 65 20  unk to generate 
25c0: 66 69 6c 65 6e 61 6d 65 20 66 6f 72 20 2a 2f 0a  filename for */.
25d0: 20 20 63 68 61 72 20 2a 7a 4f 75 74 20 20 20 20    char *zOut    
25e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25f0: 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 77    /* Buffer to w
2600: 72 69 74 65 20 67 65 6e 65 72 61 74 65 64 20 6e  rite generated n
2610: 61 6d 65 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 69  ame to */.){.  i
2620: 6e 74 20 6e 20 3d 20 6e 42 61 73 65 3b 0a 20 20  nt n = nBase;.  
2630: 6d 65 6d 63 70 79 28 7a 4f 75 74 2c 20 7a 42 61  memcpy(zOut, zBa
2640: 73 65 2c 20 6e 2b 31 29 3b 0a 20 20 69 66 28 20  se, n+1);.  if( 
2650: 69 43 68 75 6e 6b 21 3d 30 20 26 26 20 69 43 68  iChunk!=0 && iCh
2660: 75 6e 6b 3c 3d 4d 58 5f 43 48 55 4e 4b 5f 4e 55  unk<=MX_CHUNK_NU
2670: 4d 42 45 52 20 29 7b 0a 23 69 66 64 65 66 20 53  MBER ){.#ifdef S
2680: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 38 5f 33  QLITE_ENABLE_8_3
2690: 5f 4e 41 4d 45 53 0a 20 20 20 20 69 6e 74 20 69  _NAMES.    int i
26a0: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 6e 2d 31 3b  ;.    for(i=n-1;
26b0: 20 69 3e 30 20 26 26 20 69 3e 3d 6e 2d 34 20 26   i>0 && i>=n-4 &
26c0: 26 20 7a 4f 75 74 5b 69 5d 21 3d 27 2e 27 3b 20  & zOut[i]!='.'; 
26d0: 69 2d 2d 29 7b 7d 0a 20 20 20 20 69 66 28 20 69  i--){}.    if( i
26e0: 3e 3d 6e 2d 34 20 29 20 6e 20 3d 20 69 2b 31 3b  >=n-4 ) n = i+1;
26f0: 0a 20 20 20 20 69 66 28 20 66 6c 61 67 73 20 26  .    if( flags &
2700: 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49   SQLITE_OPEN_MAI
2710: 4e 5f 4a 4f 55 52 4e 41 4c 20 29 7b 0a 20 20 20  N_JOURNAL ){.   
2720: 20 20 20 2f 2a 20 54 68 65 20 65 78 74 65 6e 73     /* The extens
2730: 69 6f 6e 73 20 6f 6e 20 6f 76 65 72 66 6c 6f 77  ions on overflow
2740: 20 66 69 6c 65 73 20 66 6f 72 20 6d 61 69 6e 20   files for main 
2750: 64 61 74 61 62 61 73 65 73 20 61 72 65 20 30 30  databases are 00
2760: 31 2c 20 30 30 32 2c 0a 20 20 20 20 20 20 2a 2a  1, 002,.      **
2770: 20 30 30 33 20 61 6e 64 20 73 6f 20 66 6f 72 74   003 and so fort
2780: 68 2e 20 20 54 6f 20 61 76 6f 69 64 20 6e 61 6d  h.  To avoid nam
2790: 65 20 63 6f 6c 6c 69 73 69 6f 6e 73 2c 20 61 64  e collisions, ad
27a0: 64 20 34 30 30 20 74 6f 20 74 68 65 20 0a 20 20  d 400 to the .  
27b0: 20 20 20 20 2a 2a 20 65 78 74 65 6e 73 69 6f 6e      ** extension
27c0: 73 20 6f 66 20 6a 6f 75 72 6e 61 6c 20 66 69 6c  s of journal fil
27d0: 65 73 20 73 6f 20 74 68 61 74 20 74 68 65 79 20  es so that they 
27e0: 61 72 65 20 34 30 31 2c 20 34 30 32 2c 20 34 30  are 401, 402, 40
27f0: 33 2c 20 2e 2e 2e 2e 0a 20 20 20 20 20 20 2a 2f  3, .....      */
2800: 0a 20 20 20 20 20 20 69 43 68 75 6e 6b 20 2b 3d  .      iChunk +=
2810: 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45   SQLITE_MULTIPLE
2820: 58 5f 4a 4f 55 52 4e 41 4c 5f 38 5f 33 5f 4f 46  X_JOURNAL_8_3_OF
2830: 46 53 45 54 3b 0a 20 20 20 20 7d 65 6c 73 65 20  FSET;.    }else 
2840: 69 66 28 20 66 6c 61 67 73 20 26 20 53 51 4c 49  if( flags & SQLI
2850: 54 45 5f 4f 50 45 4e 5f 57 41 4c 20 29 7b 0a 20  TE_OPEN_WAL ){. 
2860: 20 20 20 20 20 2f 2a 20 54 6f 20 61 76 6f 69 64       /* To avoid
2870: 20 6e 61 6d 65 20 63 6f 6c 6c 69 73 69 6f 6e 73   name collisions
2880: 2c 20 61 64 64 20 37 30 30 20 74 6f 20 74 68 65  , add 700 to the
2890: 20 0a 20 20 20 20 20 20 2a 2a 20 65 78 74 65 6e   .      ** exten
28a0: 73 69 6f 6e 73 20 6f 66 20 57 41 4c 20 66 69 6c  sions of WAL fil
28b0: 65 73 20 73 6f 20 74 68 61 74 20 74 68 65 79 20  es so that they 
28c0: 61 72 65 20 37 30 31 2c 20 37 30 32 2c 20 37 30  are 701, 702, 70
28d0: 33 2c 20 2e 2e 2e 2e 0a 20 20 20 20 20 20 2a 2f  3, .....      */
28e0: 0a 20 20 20 20 20 20 69 43 68 75 6e 6b 20 2b 3d  .      iChunk +=
28f0: 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45   SQLITE_MULTIPLE
2900: 58 5f 57 41 4c 5f 38 5f 33 5f 4f 46 46 53 45 54  X_WAL_8_3_OFFSET
2910: 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20  ;.    }.#endif. 
2920: 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
2930: 6e 74 66 28 34 2c 26 7a 4f 75 74 5b 6e 5d 2c 22  ntf(4,&zOut[n],"
2940: 25 30 33 64 22 2c 69 43 68 75 6e 6b 29 3b 0a 20  %03d",iChunk);. 
2950: 20 20 20 6e 20 2b 3d 20 33 3b 0a 20 20 7d 0a 0a     n += 3;.  }..
2960: 20 20 61 73 73 65 72 74 28 20 7a 4f 75 74 5b 6e    assert( zOut[n
2970: 5d 3d 3d 27 5c 30 27 20 29 3b 0a 20 20 7a 4f 75  ]=='\0' );.  zOu
2980: 74 5b 6e 2b 31 5d 20 3d 20 27 5c 30 27 3b 0a 7d  t[n+1] = '\0';.}
2990: 0a 0a 2f 2a 20 43 6f 6d 70 75 74 65 20 74 68 65  ../* Compute the
29a0: 20 66 69 6c 65 6e 61 6d 65 20 66 6f 72 20 74 68   filename for th
29b0: 65 20 69 43 68 75 6e 6b 2d 74 68 20 63 68 75 6e  e iChunk-th chun
29c0: 6b 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  k.*/.static int 
29d0: 6d 75 6c 74 69 70 6c 65 78 53 75 62 46 69 6c 65  multiplexSubFile
29e0: 6e 61 6d 65 28 6d 75 6c 74 69 70 6c 65 78 47 72  name(multiplexGr
29f0: 6f 75 70 20 2a 70 47 72 6f 75 70 2c 20 69 6e 74  oup *pGroup, int
2a00: 20 69 43 68 75 6e 6b 29 7b 0a 20 20 69 66 28 20   iChunk){.  if( 
2a10: 69 43 68 75 6e 6b 3e 3d 70 47 72 6f 75 70 2d 3e  iChunk>=pGroup->
2a20: 6e 52 65 61 6c 20 29 7b 0a 20 20 20 20 73 74 72  nReal ){.    str
2a30: 75 63 74 20 6d 75 6c 74 69 70 6c 65 78 52 65 61  uct multiplexRea
2a40: 6c 20 2a 70 3b 0a 20 20 20 20 70 20 3d 20 73 71  l *p;.    p = sq
2a50: 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70 47  lite3_realloc(pG
2a60: 72 6f 75 70 2d 3e 61 52 65 61 6c 2c 20 28 69 43  roup->aReal, (iC
2a70: 68 75 6e 6b 2b 31 29 2a 73 69 7a 65 6f 66 28 2a  hunk+1)*sizeof(*
2a80: 70 29 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d  p));.    if( p==
2a90: 30 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  0 ){.      retur
2aa0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2ab0: 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74      }.    memset
2ac0: 28 26 70 5b 70 47 72 6f 75 70 2d 3e 6e 52 65 61  (&p[pGroup->nRea
2ad0: 6c 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 5b  l], 0, sizeof(p[
2ae0: 30 5d 29 2a 28 69 43 68 75 6e 6b 2b 31 2d 70 47  0])*(iChunk+1-pG
2af0: 72 6f 75 70 2d 3e 6e 52 65 61 6c 29 29 3b 0a 20  roup->nReal));. 
2b00: 20 20 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c     pGroup->aReal
2b10: 20 3d 20 70 3b 0a 20 20 20 20 70 47 72 6f 75 70   = p;.    pGroup
2b20: 2d 3e 6e 52 65 61 6c 20 3d 20 69 43 68 75 6e 6b  ->nReal = iChunk
2b30: 2b 31 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 47  +1;.  }.  if( pG
2b40: 72 6f 75 70 2d 3e 7a 4e 61 6d 65 20 26 26 20 70  roup->zName && p
2b50: 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68  Group->aReal[iCh
2b60: 75 6e 6b 5d 2e 7a 3d 3d 30 20 29 7b 0a 20 20 20  unk].z==0 ){.   
2b70: 20 63 68 61 72 20 2a 7a 3b 0a 20 20 20 20 69 6e   char *z;.    in
2b80: 74 20 6e 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4e  t n = pGroup->nN
2b90: 61 6d 65 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d  ame;.    pGroup-
2ba0: 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a  >aReal[iChunk].z
2bb0: 20 3d 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d   = z = sqlite3_m
2bc0: 61 6c 6c 6f 63 28 20 6e 2b 35 20 29 3b 0a 20 20  alloc( n+5 );.  
2bd0: 20 20 69 66 28 20 7a 3d 3d 30 20 29 7b 0a 20 20    if( z==0 ){.  
2be0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
2bf0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
2c00: 20 20 20 6d 75 6c 74 69 70 6c 65 78 46 69 6c 65     multiplexFile
2c10: 6e 61 6d 65 28 70 47 72 6f 75 70 2d 3e 7a 4e 61  name(pGroup->zNa
2c20: 6d 65 2c 20 70 47 72 6f 75 70 2d 3e 6e 4e 61 6d  me, pGroup->nNam
2c30: 65 2c 20 70 47 72 6f 75 70 2d 3e 66 6c 61 67 73  e, pGroup->flags
2c40: 2c 20 69 43 68 75 6e 6b 2c 20 7a 29 3b 0a 20 20  , iChunk, z);.  
2c50: 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
2c60: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 54 72 61 6e  E_OK;.}../* Tran
2c70: 73 6c 61 74 65 20 61 6e 20 73 71 6c 69 74 65 33  slate an sqlite3
2c80: 5f 66 69 6c 65 2a 20 74 68 61 74 20 69 73 20 72  _file* that is r
2c90: 65 61 6c 6c 79 20 61 20 6d 75 6c 74 69 70 6c 65  eally a multiple
2ca0: 78 47 72 6f 75 70 2a 20 69 6e 74 6f 0a 2a 2a 20  xGroup* into.** 
2cb0: 74 68 65 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  the sqlite3_file
2cc0: 2a 20 66 6f 72 20 74 68 65 20 75 6e 64 65 72 6c  * for the underl
2cd0: 79 69 6e 67 20 6f 72 69 67 69 6e 61 6c 20 56 46  ying original VF
2ce0: 53 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 63 68 75  S..**.** For chu
2cf0: 6e 6b 20 30 2c 20 74 68 65 20 70 47 72 6f 75 70  nk 0, the pGroup
2d00: 2d 3e 66 6c 61 67 73 20 64 65 74 65 72 6d 69 6e  ->flags determin
2d10: 65 73 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f  es whether or no
2d20: 74 20 61 20 6e 65 77 20 66 69 6c 65 0a 2a 2a 20  t a new file.** 
2d30: 69 73 20 63 72 65 61 74 65 64 20 69 66 20 69 74  is created if it
2d40: 20 64 6f 65 73 20 6e 6f 74 20 61 6c 72 65 61 64   does not alread
2d50: 79 20 65 78 69 73 74 2e 20 20 46 6f 72 20 63 68  y exist.  For ch
2d60: 75 6e 6b 73 20 31 20 61 6e 64 20 68 69 67 68 65  unks 1 and highe
2d70: 72 2c 20 74 68 65 0a 2a 2a 20 66 69 6c 65 20 69  r, the.** file i
2d80: 73 20 63 72 65 61 74 65 64 20 6f 6e 6c 79 20 69  s created only i
2d90: 66 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20  f createFlag is 
2da0: 31 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  1..*/.static sql
2db0: 69 74 65 33 5f 66 69 6c 65 20 2a 6d 75 6c 74 69  ite3_file *multi
2dc0: 70 6c 65 78 53 75 62 4f 70 65 6e 28 0a 20 20 6d  plexSubOpen(.  m
2dd0: 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a 70  ultiplexGroup *p
2de0: 47 72 6f 75 70 2c 20 20 20 20 2f 2a 20 54 68 65  Group,    /* The
2df0: 20 6d 75 6c 74 69 70 6c 65 78 6f 72 20 67 72 6f   multiplexor gro
2e00: 75 70 20 2a 2f 0a 20 20 69 6e 74 20 69 43 68 75  up */.  int iChu
2e10: 6e 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  nk,             
2e20: 20 20 20 2f 2a 20 57 68 69 63 68 20 63 68 75 6e     /* Which chun
2e30: 6b 20 74 6f 20 6f 70 65 6e 2e 20 20 30 3d 3d 6f  k to open.  0==o
2e40: 72 69 67 69 6e 61 6c 20 66 69 6c 65 20 2a 2f 0a  riginal file */.
2e50: 20 20 69 6e 74 20 2a 72 63 2c 20 20 20 20 20 20    int *rc,      
2e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2e70: 52 65 73 75 6c 74 20 63 6f 64 65 20 69 6e 20 61  Result code in a
2e80: 6e 64 20 6f 75 74 20 2a 2f 0a 20 20 69 6e 74 20  nd out */.  int 
2e90: 2a 70 4f 75 74 46 6c 61 67 73 2c 20 20 20 20 20  *pOutFlags,     
2ea0: 20 20 20 20 20 20 20 2f 2a 20 4f 75 74 70 75 74         /* Output
2eb0: 20 66 6c 61 67 73 20 2a 2f 0a 20 20 69 6e 74 20   flags */.  int 
2ec0: 63 72 65 61 74 65 46 6c 61 67 20 20 20 20 20 20  createFlag      
2ed0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
2ee0: 6f 20 63 72 65 61 74 65 20 69 66 20 69 43 68 75  o create if iChu
2ef0: 6e 6b 3e 30 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  nk>0 */.){.  sql
2f00: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
2f10: 70 65 6e 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74  pen = 0;.  sqlit
2f20: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
2f30: 20 3d 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f   = gMultiplex.pO
2f40: 72 69 67 56 66 73 3b 20 20 20 20 20 20 20 20 2f  rigVfs;        /
2f50: 2a 20 52 65 61 6c 20 56 46 53 20 2a 2f 0a 0a 23  * Real VFS */..#
2f60: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
2f70: 42 4c 45 5f 38 5f 33 5f 4e 41 4d 45 53 0a 20 20  BLE_8_3_NAMES.  
2f80: 2f 2a 20 49 66 20 4a 4f 55 52 4e 41 4c 5f 38 5f  /* If JOURNAL_8_
2f90: 33 5f 4f 46 46 53 45 54 20 69 73 20 73 65 74 20  3_OFFSET is set 
2fa0: 74 6f 20 28 73 61 79 29 20 34 30 30 2c 20 74 68  to (say) 400, th
2fb0: 65 6e 20 61 6e 79 20 6f 76 65 72 66 6c 6f 77 20  en any overflow 
2fc0: 66 69 6c 65 73 20 61 72 65 20 0a 20 20 2a 2a 20  files are .  ** 
2fd0: 70 61 72 74 20 6f 66 20 61 20 64 61 74 61 62 61  part of a databa
2fe0: 73 65 20 6a 6f 75 72 6e 61 6c 20 61 72 65 20 6e  se journal are n
2ff0: 61 6d 65 64 20 64 62 2e 34 30 31 2c 20 64 62 2e  amed db.401, db.
3000: 34 30 32 2c 20 61 6e 64 20 73 6f 20 6f 6e 2e 20  402, and so on. 
3010: 41 20 0a 20 20 2a 2a 20 64 61 74 61 62 61 73 65  A .  ** database
3020: 20 6d 61 79 20 74 68 65 72 65 66 6f 72 65 20 6e   may therefore n
3030: 6f 74 20 67 72 6f 77 20 74 6f 20 6c 61 72 67 65  ot grow to large
3040: 72 20 74 68 61 6e 20 34 30 30 20 63 68 75 6e 6b  r than 400 chunk
3050: 73 2e 20 41 74 74 65 6d 70 74 69 6e 67 0a 20 20  s. Attempting.  
3060: 2a 2a 20 74 6f 20 6f 70 65 6e 20 63 68 75 6e 6b  ** to open chunk
3070: 20 34 30 31 20 69 6e 64 69 63 61 74 65 73 20 74   401 indicates t
3080: 68 65 20 64 61 74 61 62 61 73 65 20 69 73 20 66  he database is f
3090: 75 6c 6c 2e 20 2a 2f 0a 20 20 69 66 28 20 69 43  ull. */.  if( iC
30a0: 68 75 6e 6b 3e 3d 53 51 4c 49 54 45 5f 4d 55 4c  hunk>=SQLITE_MUL
30b0: 54 49 50 4c 45 58 5f 4a 4f 55 52 4e 41 4c 5f 38  TIPLEX_JOURNAL_8
30c0: 5f 33 5f 4f 46 46 53 45 54 20 29 7b 0a 20 20 20  _3_OFFSET ){.   
30d0: 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c   sqlite3_log(SQL
30e0: 49 54 45 5f 46 55 4c 4c 2c 20 22 6d 75 6c 74 69  ITE_FULL, "multi
30f0: 70 6c 65 78 65 64 20 63 68 75 6e 6b 20 6f 76 65  plexed chunk ove
3100: 72 66 6c 6f 77 3a 20 25 73 22 2c 20 70 47 72 6f  rflow: %s", pGro
3110: 75 70 2d 3e 7a 4e 61 6d 65 29 3b 0a 20 20 20 20  up->zName);.    
3120: 2a 72 63 20 3d 20 53 51 4c 49 54 45 5f 46 55 4c  *rc = SQLITE_FUL
3130: 4c 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  L;.    return 0;
3140: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2a  .  }.#endif..  *
3150: 72 63 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75  rc = multiplexSu
3160: 62 46 69 6c 65 6e 61 6d 65 28 70 47 72 6f 75 70  bFilename(pGroup
3170: 2c 20 69 43 68 75 6e 6b 29 3b 0a 20 20 69 66 28  , iChunk);.  if(
3180: 20 28 2a 72 63 29 3d 3d 53 51 4c 49 54 45 5f 4f   (*rc)==SQLITE_O
3190: 4b 20 26 26 20 28 70 53 75 62 4f 70 65 6e 20 3d  K && (pSubOpen =
31a0: 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69   pGroup->aReal[i
31b0: 43 68 75 6e 6b 5d 2e 70 29 3d 3d 30 20 29 7b 0a  Chunk].p)==0 ){.
31c0: 20 20 20 20 69 6e 74 20 66 6c 61 67 73 2c 20 62      int flags, b
31d0: 45 78 69 73 74 73 3b 0a 20 20 20 20 66 6c 61 67  Exists;.    flag
31e0: 73 20 3d 20 70 47 72 6f 75 70 2d 3e 66 6c 61 67  s = pGroup->flag
31f0: 73 3b 0a 20 20 20 20 69 66 28 20 63 72 65 61 74  s;.    if( creat
3200: 65 46 6c 61 67 20 29 7b 0a 20 20 20 20 20 20 66  eFlag ){.      f
3210: 6c 61 67 73 20 7c 3d 20 53 51 4c 49 54 45 5f 4f  lags |= SQLITE_O
3220: 50 45 4e 5f 43 52 45 41 54 45 3b 0a 20 20 20 20  PEN_CREATE;.    
3230: 7d 65 6c 73 65 20 69 66 28 20 69 43 68 75 6e 6b  }else if( iChunk
3240: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  ==0 ){.      /* 
3250: 46 61 6c 6c 20 74 68 72 6f 75 67 68 20 2a 2f 0a  Fall through */.
3260: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 47      }else if( pG
3270: 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75  roup->aReal[iChu
3280: 6e 6b 5d 2e 7a 3d 3d 30 20 29 7b 0a 20 20 20 20  nk].z==0 ){.    
3290: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20    return 0;.    
32a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 72 63  }else{.      *rc
32b0: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 41 63   = pOrigVfs->xAc
32c0: 63 65 73 73 28 70 4f 72 69 67 56 66 73 2c 20 70  cess(pOrigVfs, p
32d0: 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68  Group->aReal[iCh
32e0: 75 6e 6b 5d 2e 7a 2c 0a 20 20 20 20 20 20 20 20  unk].z,.        
32f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3300: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 41 43 43        SQLITE_ACC
3310: 45 53 53 5f 45 58 49 53 54 53 2c 20 26 62 45 78  ESS_EXISTS, &bEx
3320: 69 73 74 73 29 3b 0a 20 20 20 20 20 69 66 28 20  ists);.     if( 
3330: 2a 72 63 20 7c 7c 20 21 62 45 78 69 73 74 73 20  *rc || !bExists 
3340: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 2a  ){.        if( *
3350: 72 63 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  rc ){.          
3360: 73 71 6c 69 74 65 33 5f 6c 6f 67 28 2a 72 63 2c  sqlite3_log(*rc,
3370: 20 22 6d 75 6c 74 69 70 6c 65 78 6f 72 2e 78 41   "multiplexor.xA
3380: 63 63 65 73 73 20 66 61 69 6c 75 72 65 20 6f 6e  ccess failure on
3390: 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20   %s",.          
33a0: 20 20 20 20 20 20 20 20 20 20 20 20 70 47 72 6f              pGro
33b0: 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b  up->aReal[iChunk
33c0: 5d 2e 7a 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ].z);.        }.
33d0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 30          return 0
33e0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
33f0: 66 6c 61 67 73 20 26 3d 20 7e 53 51 4c 49 54 45  flags &= ~SQLITE
3400: 5f 4f 50 45 4e 5f 43 52 45 41 54 45 3b 0a 20 20  _OPEN_CREATE;.  
3410: 20 20 7d 0a 20 20 20 20 70 53 75 62 4f 70 65 6e    }.    pSubOpen
3420: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
3430: 63 28 20 70 4f 72 69 67 56 66 73 2d 3e 73 7a 4f  c( pOrigVfs->szO
3440: 73 46 69 6c 65 20 29 3b 0a 20 20 20 20 69 66 28  sFile );.    if(
3450: 20 70 53 75 62 4f 70 65 6e 3d 3d 30 20 29 7b 0a   pSubOpen==0 ){.
3460: 20 20 20 20 20 20 2a 72 63 20 3d 20 53 51 4c 49        *rc = SQLI
3470: 54 45 5f 49 4f 45 52 52 5f 4e 4f 4d 45 4d 3b 0a  TE_IOERR_NOMEM;.
3480: 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
3490: 20 20 20 20 7d 0a 20 20 20 20 70 47 72 6f 75 70      }.    pGroup
34a0: 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e  ->aReal[iChunk].
34b0: 70 20 3d 20 70 53 75 62 4f 70 65 6e 3b 0a 20 20  p = pSubOpen;.  
34c0: 20 20 2a 72 63 20 3d 20 70 4f 72 69 67 56 66 73    *rc = pOrigVfs
34d0: 2d 3e 78 4f 70 65 6e 28 70 4f 72 69 67 56 66 73  ->xOpen(pOrigVfs
34e0: 2c 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b  , pGroup->aReal[
34f0: 69 43 68 75 6e 6b 5d 2e 7a 2c 20 70 53 75 62 4f  iChunk].z, pSubO
3500: 70 65 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20  pen,.           
3510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 66                 f
3520: 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29  lags, pOutFlags)
3530: 3b 0a 20 20 20 20 69 66 28 20 28 2a 72 63 29 21  ;.    if( (*rc)!
3540: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3550: 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28      sqlite3_log(
3560: 2a 72 63 2c 20 22 6d 75 6c 74 69 70 6c 65 78 6f  *rc, "multiplexo
3570: 72 2e 78 4f 70 65 6e 20 66 61 69 6c 75 72 65 20  r.xOpen failure 
3580: 6f 6e 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20  on %s",.        
3590: 20 20 20 20 20 20 20 20 20 20 70 47 72 6f 75 70            pGroup
35a0: 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e  ->aReal[iChunk].
35b0: 7a 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  z);.      sqlite
35c0: 33 5f 66 72 65 65 28 70 53 75 62 4f 70 65 6e 29  3_free(pSubOpen)
35d0: 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  ;.      pGroup->
35e0: 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 70 20  aReal[iChunk].p 
35f0: 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72  = 0;.      retur
3600: 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  n 0;.    }.  }. 
3610: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
3620: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
3630: 6e 20 74 68 65 20 73 69 7a 65 2c 20 69 6e 20 62  n the size, in b
3640: 79 74 65 73 2c 20 6f 66 20 63 68 75 6e 6b 20 6e  ytes, of chunk n
3650: 75 6d 62 65 72 20 69 43 68 75 6e 6b 2e 20 20 49  umber iChunk.  I
3660: 66 20 74 68 61 74 20 63 68 75 6e 6b 0a 2a 2a 20  f that chunk.** 
3670: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 2c 20  does not exist, 
3680: 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e 20 20  then return 0.  
3690: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f  This function do
36a0: 65 73 20 6e 6f 74 20 64 69 73 74 69 6e 67 69 73  es not distingis
36b0: 68 20 62 65 74 77 65 65 6e 0a 2a 2a 20 6e 6f 6e  h between.** non
36c0: 2d 65 78 69 73 74 61 6e 74 20 66 69 6c 65 73 20  -existant files 
36d0: 61 6e 64 20 7a 65 72 6f 2d 6c 65 6e 67 74 68 20  and zero-length 
36e0: 66 69 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  files..*/.static
36f0: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6d   sqlite3_int64 m
3700: 75 6c 74 69 70 6c 65 78 53 75 62 53 69 7a 65 28  ultiplexSubSize(
3710: 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75  .  multiplexGrou
3720: 70 20 2a 70 47 72 6f 75 70 2c 20 20 20 20 2f 2a  p *pGroup,    /*
3730: 20 54 68 65 20 6d 75 6c 74 69 70 6c 65 78 6f 72   The multiplexor
3740: 20 67 72 6f 75 70 20 2a 2f 0a 20 20 69 6e 74 20   group */.  int 
3750: 69 43 68 75 6e 6b 2c 20 20 20 20 20 20 20 20 20  iChunk,         
3760: 20 20 20 20 20 20 20 2f 2a 20 57 68 69 63 68 20         /* Which 
3770: 63 68 75 6e 6b 20 74 6f 20 6f 70 65 6e 2e 20 20  chunk to open.  
3780: 30 3d 3d 6f 72 69 67 69 6e 61 6c 20 66 69 6c 65  0==original file
3790: 20 2a 2f 0a 20 20 69 6e 74 20 2a 72 63 20 20 20   */.  int *rc   
37a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37b0: 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f 64 65 20   /* Result code 
37c0: 69 6e 20 61 6e 64 20 6f 75 74 20 2a 2f 0a 29 7b  in and out */.){
37d0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
37e0: 2a 70 53 75 62 3b 0a 20 20 73 71 6c 69 74 65 33  *pSub;.  sqlite3
37f0: 5f 69 6e 74 36 34 20 73 7a 20 3d 20 30 3b 0a 0a  _int64 sz = 0;..
3800: 20 20 69 66 28 20 2a 72 63 20 29 20 72 65 74 75    if( *rc ) retu
3810: 72 6e 20 30 3b 0a 20 20 70 53 75 62 20 3d 20 6d  rn 0;.  pSub = m
3820: 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28  ultiplexSubOpen(
3830: 70 47 72 6f 75 70 2c 20 69 43 68 75 6e 6b 2c 20  pGroup, iChunk, 
3840: 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20  rc, NULL, 0);.  
3850: 69 66 28 20 70 53 75 62 3d 3d 30 20 29 20 72 65  if( pSub==0 ) re
3860: 74 75 72 6e 20 30 3b 0a 20 20 2a 72 63 20 3d 20  turn 0;.  *rc = 
3870: 70 53 75 62 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  pSub->pMethods->
3880: 78 46 69 6c 65 53 69 7a 65 28 70 53 75 62 2c 20  xFileSize(pSub, 
3890: 26 73 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  &sz);.  return s
38a0: 7a 3b 0a 7d 20 20 20 20 0a 0a 2f 2a 0a 2a 2a 20  z;.}    ../*.** 
38b0: 54 68 69 73 20 69 73 20 74 68 65 20 69 6d 70 6c  This is the impl
38c0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
38d0: 65 20 6d 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74  e multiplex_cont
38e0: 72 6f 6c 28 29 20 53 51 4c 20 66 75 6e 63 74 69  rol() SQL functi
38f0: 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  on..*/.static vo
3900: 69 64 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 74  id multiplexCont
3910: 72 6f 6c 46 75 6e 63 28 0a 20 20 73 71 6c 69 74  rolFunc(.  sqlit
3920: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74  e3_context *cont
3930: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  ext,.  int argc,
3940: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
3950: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74   **argv.){.  int
3960: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3970: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d  .  sqlite3 *db =
3980: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
3990: 5f 64 62 5f 68 61 6e 64 6c 65 28 63 6f 6e 74 65  _db_handle(conte
39a0: 78 74 29 3b 0a 20 20 69 6e 74 20 6f 70 3b 0a 20  xt);.  int op;. 
39b0: 20 69 6e 74 20 69 56 61 6c 3b 0a 0a 20 20 69 66   int iVal;..  if
39c0: 28 20 21 64 62 20 7c 7c 20 61 72 67 63 21 3d 32  ( !db || argc!=2
39d0: 20 29 7b 20 0a 20 20 20 20 72 63 20 3d 20 53 51   ){ .    rc = SQ
39e0: 4c 49 54 45 5f 45 52 52 4f 52 3b 20 0a 20 20 7d  LITE_ERROR; .  }
39f0: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 65 78 74  else{.    /* ext
3a00: 72 61 63 74 20 70 61 72 61 6d 73 20 2a 2f 0a 20  ract params */. 
3a10: 20 20 20 6f 70 20 3d 20 73 71 6c 69 74 65 33 5f     op = sqlite3_
3a20: 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 30  value_int(argv[0
3a30: 5d 29 3b 0a 20 20 20 20 69 56 61 6c 20 3d 20 73  ]);.    iVal = s
3a40: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74  qlite3_value_int
3a50: 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 20 20 2f  (argv[1]);.    /
3a60: 2a 20 6d 61 70 20 66 75 6e 63 74 69 6f 6e 20 6f  * map function o
3a70: 70 20 74 6f 20 66 69 6c 65 5f 63 6f 6e 74 72 6f  p to file_contro
3a80: 6c 20 6f 70 20 2a 2f 0a 20 20 20 20 73 77 69 74  l op */.    swit
3a90: 63 68 28 20 6f 70 20 29 7b 0a 20 20 20 20 20 20  ch( op ){.      
3aa0: 63 61 73 65 20 31 3a 20 0a 20 20 20 20 20 20 20  case 1: .       
3ab0: 20 6f 70 20 3d 20 4d 55 4c 54 49 50 4c 45 58 5f   op = MULTIPLEX_
3ac0: 43 54 52 4c 5f 45 4e 41 42 4c 45 3b 20 0a 20 20  CTRL_ENABLE; .  
3ad0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
3ae0: 20 20 20 63 61 73 65 20 32 3a 20 0a 20 20 20 20     case 2: .    
3af0: 20 20 20 20 6f 70 20 3d 20 4d 55 4c 54 49 50 4c      op = MULTIPL
3b00: 45 58 5f 43 54 52 4c 5f 53 45 54 5f 43 48 55 4e  EX_CTRL_SET_CHUN
3b10: 4b 5f 53 49 5a 45 3b 20 0a 20 20 20 20 20 20 20  K_SIZE; .       
3b20: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61   break;.      ca
3b30: 73 65 20 33 3a 20 0a 20 20 20 20 20 20 20 20 6f  se 3: .        o
3b40: 70 20 3d 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54  p = MULTIPLEX_CT
3b50: 52 4c 5f 53 45 54 5f 4d 41 58 5f 43 48 55 4e 4b  RL_SET_MAX_CHUNK
3b60: 53 3b 20 0a 20 20 20 20 20 20 20 20 62 72 65 61  S; .        brea
3b70: 6b 3b 0a 20 20 20 20 20 20 64 65 66 61 75 6c 74  k;.      default
3b80: 3a 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  :.        rc = S
3b90: 51 4c 49 54 45 5f 4e 4f 54 46 4f 55 4e 44 3b 0a  QLITE_NOTFOUND;.
3ba0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
3bb0: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72     }.  }.  if( r
3bc0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
3bd0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3be0: 5f 66 69 6c 65 5f 63 6f 6e 74 72 6f 6c 28 64 62  _file_control(db
3bf0: 2c 20 30 2c 20 6f 70 2c 20 26 69 56 61 6c 29 3b  , 0, op, &iVal);
3c00: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 72  .  }.  sqlite3_r
3c10: 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65  esult_error_code
3c20: 28 63 6f 6e 74 65 78 74 2c 20 72 63 29 3b 0a 7d  (context, rc);.}
3c30: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ../*.** This is 
3c40: 74 68 65 20 65 6e 74 72 79 20 70 6f 69 6e 74 20  the entry point 
3c50: 74 6f 20 72 65 67 69 73 74 65 72 20 74 68 65 20  to register the 
3c60: 61 75 74 6f 2d 65 78 74 65 6e 73 69 6f 6e 20 66  auto-extension f
3c70: 6f 72 20 74 68 65 20 0a 2a 2a 20 6d 75 6c 74 69  or the .** multi
3c80: 70 6c 65 78 5f 63 6f 6e 74 72 6f 6c 28 29 20 66  plex_control() f
3c90: 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  unction..*/.stat
3ca0: 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78  ic int multiplex
3cb0: 46 75 6e 63 49 6e 69 74 28 0a 20 20 73 71 6c 69  FuncInit(.  sqli
3cc0: 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72  te3 *db, .  char
3cd0: 20 2a 2a 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20   **pzErrMsg, .  
3ce0: 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 61 70  const sqlite3_ap
3cf0: 69 5f 72 6f 75 74 69 6e 65 73 20 2a 70 41 70 69  i_routines *pApi
3d00: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  .){.  int rc;.  
3d10: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65  rc = sqlite3_cre
3d20: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c  ate_function(db,
3d30: 20 22 6d 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74   "multiplex_cont
3d40: 72 6f 6c 22 2c 20 32 2c 20 53 51 4c 49 54 45 5f  rol", 2, SQLITE_
3d50: 41 4e 59 2c 20 0a 20 20 20 20 20 20 30 2c 20 6d  ANY, .      0, m
3d60: 75 6c 74 69 70 6c 65 78 43 6f 6e 74 72 6f 6c 46  ultiplexControlF
3d70: 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 72 65  unc, 0, 0);.  re
3d80: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
3d90: 2a 20 43 6c 6f 73 65 20 61 20 73 69 6e 67 6c 65  * Close a single
3da0: 20 73 75 62 2d 66 69 6c 65 20 69 6e 20 74 68 65   sub-file in the
3db0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 67 72 6f 75   connection grou
3dc0: 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  p..*/.static voi
3dd0: 64 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 43 6c  d multiplexSubCl
3de0: 6f 73 65 28 0a 20 20 6d 75 6c 74 69 70 6c 65 78  ose(.  multiplex
3df0: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 2c 0a 20  Group *pGroup,. 
3e00: 20 69 6e 74 20 69 43 68 75 6e 6b 2c 0a 20 20 73   int iChunk,.  s
3e10: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69  qlite3_vfs *pOri
3e20: 67 56 66 73 0a 29 7b 0a 20 20 73 71 6c 69 74 65  gVfs.){.  sqlite
3e30: 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e  3_file *pSubOpen
3e40: 20 3d 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c   = pGroup->aReal
3e50: 5b 69 43 68 75 6e 6b 5d 2e 70 3b 0a 20 20 69 66  [iChunk].p;.  if
3e60: 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20  ( pSubOpen ){.  
3e70: 20 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74    pSubOpen->pMet
3e80: 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 53 75  hods->xClose(pSu
3e90: 62 4f 70 65 6e 29 3b 0a 20 20 20 20 69 66 28 20  bOpen);.    if( 
3ea0: 70 4f 72 69 67 56 66 73 20 26 26 20 70 47 72 6f  pOrigVfs && pGro
3eb0: 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b  up->aReal[iChunk
3ec0: 5d 2e 7a 20 29 7b 0a 20 20 20 20 20 20 70 4f 72  ].z ){.      pOr
3ed0: 69 67 56 66 73 2d 3e 78 44 65 6c 65 74 65 28 70  igVfs->xDelete(p
3ee0: 4f 72 69 67 56 66 73 2c 20 70 47 72 6f 75 70 2d  OrigVfs, pGroup-
3ef0: 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a  >aReal[iChunk].z
3f00: 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  , 0);.    }.    
3f10: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 47 72  sqlite3_free(pGr
3f20: 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e  oup->aReal[iChun
3f30: 6b 5d 2e 70 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  k].p);.  }.  sql
3f40: 69 74 65 33 5f 66 72 65 65 28 70 47 72 6f 75 70  ite3_free(pGroup
3f50: 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e  ->aReal[iChunk].
3f60: 7a 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 47  z);.  memset(&pG
3f70: 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75  roup->aReal[iChu
3f80: 6e 6b 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70  nk], 0, sizeof(p
3f90: 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68  Group->aReal[iCh
3fa0: 75 6e 6b 5d 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  unk]));.}../*.**
3fb0: 20 44 65 61 6c 6c 6f 63 61 74 65 20 6d 65 6d 6f   Deallocate memo
3fc0: 72 79 20 68 65 6c 64 20 62 79 20 61 20 6d 75 6c  ry held by a mul
3fd0: 74 69 70 6c 65 78 47 72 6f 75 70 0a 2a 2f 0a 73  tiplexGroup.*/.s
3fe0: 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c 74 69  tatic void multi
3ff0: 70 6c 65 78 46 72 65 65 43 6f 6d 70 6f 6e 65 6e  plexFreeComponen
4000: 74 73 28 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75  ts(multiplexGrou
4010: 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20 69 6e  p *pGroup){.  in
4020: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
4030: 69 3c 70 47 72 6f 75 70 2d 3e 6e 52 65 61 6c 3b  i<pGroup->nReal;
4040: 20 69 2b 2b 29 7b 20 6d 75 6c 74 69 70 6c 65 78   i++){ multiplex
4050: 53 75 62 43 6c 6f 73 65 28 70 47 72 6f 75 70 2c  SubClose(pGroup,
4060: 20 69 2c 20 30 29 3b 20 7d 0a 20 20 73 71 6c 69   i, 0); }.  sqli
4070: 74 65 33 5f 66 72 65 65 28 70 47 72 6f 75 70 2d  te3_free(pGroup-
4080: 3e 61 52 65 61 6c 29 3b 0a 20 20 70 47 72 6f 75  >aReal);.  pGrou
4090: 70 2d 3e 61 52 65 61 6c 20 3d 20 30 3b 0a 20 20  p->aReal = 0;.  
40a0: 70 47 72 6f 75 70 2d 3e 6e 52 65 61 6c 20 3d 20  pGroup->nReal = 
40b0: 30 3b 0a 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  0;.}.../********
40c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
40d0: 2a 20 56 46 53 20 4d 65 74 68 6f 64 20 57 72 61  * VFS Method Wra
40e0: 70 70 65 72 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ppers **********
40f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4100: 2a 2a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ***/../*.** This
4110: 20 69 73 20 74 68 65 20 78 4f 70 65 6e 20 6d 65   is the xOpen me
4120: 74 68 6f 64 20 75 73 65 64 20 66 6f 72 20 74 68  thod used for th
4130: 65 20 22 6d 75 6c 74 69 70 6c 65 78 22 20 56 46  e "multiplex" VF
4140: 53 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 73 74 20 6f 66  S..**.** Most of
4150: 20 74 68 65 20 77 6f 72 6b 20 69 73 20 64 6f 6e   the work is don
4160: 65 20 62 79 20 74 68 65 20 75 6e 64 65 72 6c 79  e by the underly
4170: 69 6e 67 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  ing original VFS
4180: 2e 20 20 54 68 69 73 20 6d 65 74 68 6f 64 0a 2a  .  This method.*
4190: 2a 20 73 69 6d 70 6c 79 20 6c 69 6e 6b 73 20 74  * simply links t
41a0: 68 65 20 6e 65 77 20 66 69 6c 65 20 69 6e 74 6f  he new file into
41b0: 20 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65   the appropriate
41c0: 20 6d 75 6c 74 69 70 6c 65 78 20 67 72 6f 75 70   multiplex group
41d0: 20 69 66 20 69 74 20 69 73 20 61 0a 2a 2a 20 66   if it is a.** f
41e0: 69 6c 65 20 74 68 61 74 20 6e 65 65 64 73 20 74  ile that needs t
41f0: 6f 20 62 65 20 74 72 61 63 6b 65 64 2e 0a 2a 2f  o be tracked..*/
4200: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
4210: 69 70 6c 65 78 4f 70 65 6e 28 0a 20 20 73 71 6c  iplexOpen(.  sql
4220: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
4230: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6d          /* The m
4240: 75 6c 74 69 70 6c 65 78 20 56 46 53 20 2a 2f 0a  ultiplex VFS */.
4250: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
4260: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  ame,         /* 
4270: 4e 61 6d 65 20 6f 66 20 66 69 6c 65 20 74 6f 20  Name of file to 
4280: 62 65 20 6f 70 65 6e 65 64 20 2a 2f 0a 20 20 73  be opened */.  s
4290: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
42a0: 6e 6e 2c 20 20 20 20 20 20 20 2f 2a 20 46 69 6c  nn,       /* Fil
42b0: 6c 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 64  l in this file d
42c0: 65 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20 20 69  escriptor */.  i
42d0: 6e 74 20 66 6c 61 67 73 2c 20 20 20 20 20 20 20  nt flags,       
42e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
42f0: 67 73 20 74 6f 20 63 6f 6e 74 72 6f 6c 20 74 68  gs to control th
4300: 65 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a 20 20 69  e opening */.  i
4310: 6e 74 20 2a 70 4f 75 74 46 6c 61 67 73 20 20 20  nt *pOutFlags   
4320: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
4330: 67 73 20 73 68 6f 77 69 6e 67 20 72 65 73 75 6c  gs showing resul
4340: 74 73 20 6f 66 20 6f 70 65 6e 69 6e 67 20 2a 2f  ts of opening */
4350: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
4360: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
4370: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
4380: 73 75 6c 74 20 63 6f 64 65 20 2a 2f 0a 20 20 6d  sult code */.  m
4390: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 4d  ultiplexConn *pM
43a0: 75 6c 74 69 70 6c 65 78 4f 70 65 6e 3b 20 20 20  ultiplexOpen;   
43b0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 6d      /* The new m
43c0: 75 6c 74 69 70 6c 65 78 20 66 69 6c 65 20 64 65  ultiplex file de
43d0: 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20 20 6d 75  scriptor */.  mu
43e0: 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a 70 47  ltiplexGroup *pG
43f0: 72 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20 20  roup;           
4400: 20 20 20 2f 2a 20 43 6f 72 72 65 73 70 6f 6e 64     /* Correspond
4410: 69 6e 67 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f  ing multiplexGro
4420: 75 70 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73  up object */.  s
4430: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
4440: 62 4f 70 65 6e 20 3d 20 30 3b 20 20 20 20 20 20  bOpen = 0;      
4450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4460: 20 52 65 61 6c 20 66 69 6c 65 20 64 65 73 63 72   Real file descr
4470: 69 70 74 6f 72 20 2a 2f 0a 20 20 73 71 6c 69 74  iptor */.  sqlit
4480: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
4490: 20 3d 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f   = gMultiplex.pO
44a0: 72 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61  rigVfs;   /* Rea
44b0: 6c 20 56 46 53 20 2a 2f 0a 20 20 69 6e 74 20 6e  l VFS */.  int n
44c0: 4e 61 6d 65 3b 0a 20 20 69 6e 74 20 73 7a 3b 0a  Name;.  int sz;.
44d0: 20 20 63 68 61 72 20 2a 7a 54 6f 46 72 65 65 20    char *zToFree 
44e0: 3d 20 30 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50  = 0;..  UNUSED_P
44f0: 41 52 41 4d 45 54 45 52 28 70 56 66 73 29 3b 0a  ARAMETER(pVfs);.
4500: 20 20 6d 65 6d 73 65 74 28 70 43 6f 6e 6e 2c 20    memset(pConn, 
4510: 30 2c 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c  0, pVfs->szOsFil
4520: 65 29 3b 0a 20 20 61 73 73 65 72 74 28 20 7a 4e  e);.  assert( zN
4530: 61 6d 65 20 7c 7c 20 28 66 6c 61 67 73 20 26 20  ame || (flags & 
4540: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45  SQLITE_OPEN_DELE
4550: 54 45 4f 4e 43 4c 4f 53 45 29 20 29 3b 0a 0a 20  TEONCLOSE) );.. 
4560: 20 2f 2a 20 57 65 20 6e 65 65 64 20 74 6f 20 63   /* We need to c
4570: 72 65 61 74 65 20 61 20 67 72 6f 75 70 20 73 74  reate a group st
4580: 72 75 63 74 75 72 65 20 61 6e 64 20 6d 61 6e 61  ructure and mana
4590: 67 65 0a 20 20 2a 2a 20 61 63 63 65 73 73 20 74  ge.  ** access t
45a0: 6f 20 74 68 69 73 20 67 72 6f 75 70 20 6f 66 20  o this group of 
45b0: 66 69 6c 65 73 2e 0a 20 20 2a 2f 0a 20 20 6d 75  files..  */.  mu
45c0: 6c 74 69 70 6c 65 78 45 6e 74 65 72 28 29 3b 0a  ltiplexEnter();.
45d0: 20 20 70 4d 75 6c 74 69 70 6c 65 78 4f 70 65 6e    pMultiplexOpen
45e0: 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e   = (multiplexCon
45f0: 6e 2a 29 70 43 6f 6e 6e 3b 0a 0a 20 20 69 66 28  n*)pConn;..  if(
4600: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4610: 7b 0a 20 20 20 20 2f 2a 20 61 6c 6c 6f 63 61 74  {.    /* allocat
4620: 65 20 73 70 61 63 65 20 66 6f 72 20 67 72 6f 75  e space for grou
4630: 70 20 2a 2f 0a 20 20 20 20 6e 4e 61 6d 65 20 3d  p */.    nName =
4640: 20 7a 4e 61 6d 65 20 3f 20 6d 75 6c 74 69 70 6c   zName ? multipl
4650: 65 78 53 74 72 6c 65 6e 33 30 28 7a 4e 61 6d 65  exStrlen30(zName
4660: 29 20 3a 20 30 3b 0a 20 20 20 20 73 7a 20 3d 20  ) : 0;.    sz = 
4670: 73 69 7a 65 6f 66 28 6d 75 6c 74 69 70 6c 65 78  sizeof(multiplex
4680: 47 72 6f 75 70 29 20 20 20 20 20 20 20 20 20 20  Group)          
4690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46a0: 20 20 20 2f 2a 20 6d 75 6c 74 69 70 6c 65 78 47     /* multiplexG
46b0: 72 6f 75 70 20 2a 2f 0a 20 20 20 20 20 20 20 2b  roup */.       +
46c0: 20 6e 4e 61 6d 65 20 2b 20 31 3b 20 20 20 20 20   nName + 1;     
46d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46f0: 20 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f 0a      /* zName */.
4700: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 73 71 6c      pGroup = sql
4710: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 7a 20  ite3_malloc( sz 
4720: 29 3b 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75  );.    if( pGrou
4730: 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63  p==0 ){.      rc
4740: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
4750: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
4760: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4770: 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  ){.    const cha
4780: 72 20 2a 7a 55 72 69 20 3d 20 28 66 6c 61 67 73  r *zUri = (flags
4790: 20 26 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 55   & SQLITE_OPEN_U
47a0: 52 49 29 20 3f 20 7a 4e 61 6d 65 20 3a 20 30 3b  RI) ? zName : 0;
47b0: 0a 20 20 20 20 2f 2a 20 61 73 73 69 67 6e 20 70  .    /* assign p
47c0: 6f 69 6e 74 65 72 73 20 74 6f 20 65 78 74 72 61  ointers to extra
47d0: 20 73 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64   space allocated
47e0: 20 2a 2f 0a 20 20 20 20 6d 65 6d 73 65 74 28 70   */.    memset(p
47f0: 47 72 6f 75 70 2c 20 30 2c 20 73 7a 29 3b 0a 20  Group, 0, sz);. 
4800: 20 20 20 70 4d 75 6c 74 69 70 6c 65 78 4f 70 65     pMultiplexOpe
4810: 6e 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f  n->pGroup = pGro
4820: 75 70 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  up;.    pGroup->
4830: 62 45 6e 61 62 6c 65 64 20 3d 20 2d 31 3b 0a 20  bEnabled = -1;. 
4840: 20 20 20 70 47 72 6f 75 70 2d 3e 62 54 72 75 6e     pGroup->bTrun
4850: 63 61 74 65 20 3d 20 73 71 6c 69 74 65 33 5f 75  cate = sqlite3_u
4860: 72 69 5f 62 6f 6f 6c 65 61 6e 28 7a 55 72 69 2c  ri_boolean(zUri,
4870: 20 22 74 72 75 6e 63 61 74 65 22 2c 20 0a 20 20   "truncate", .  
4880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
48a0: 20 28 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45   (flags & SQLITE
48b0: 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 29 3d 3d  _OPEN_MAIN_DB)==
48c0: 30 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  0);.    pGroup->
48d0: 73 7a 43 68 75 6e 6b 20 3d 20 28 69 6e 74 29 73  szChunk = (int)s
48e0: 71 6c 69 74 65 33 5f 75 72 69 5f 69 6e 74 36 34  qlite3_uri_int64
48f0: 28 7a 55 72 69 2c 20 22 63 68 75 6e 6b 73 69 7a  (zUri, "chunksiz
4900: 65 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  e",.            
4910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4920: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
4930: 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f 43 48 55  TE_MULTIPLEX_CHU
4940: 4e 4b 5f 53 49 5a 45 29 3b 0a 20 20 20 20 70 47  NK_SIZE);.    pG
4950: 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 3d 20  roup->szChunk = 
4960: 28 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b  (pGroup->szChunk
4970: 2b 30 78 66 66 66 66 29 26 7e 30 78 66 66 66 66  +0xffff)&~0xffff
4980: 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20  ;.    if( zName 
4990: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 70  ){.      char *p
49a0: 20 3d 20 28 63 68 61 72 20 2a 29 26 70 47 72 6f   = (char *)&pGro
49b0: 75 70 5b 31 5d 3b 0a 20 20 20 20 20 20 70 47 72  up[1];.      pGr
49c0: 6f 75 70 2d 3e 7a 4e 61 6d 65 20 3d 20 70 3b 0a  oup->zName = p;.
49d0: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 47 72        memcpy(pGr
49e0: 6f 75 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d  oup->zName, zNam
49f0: 65 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20 20  e, nName+1);.   
4a00: 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4e 61 6d 65     pGroup->nName
4a10: 20 3d 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 7d 0a   = nName;.    }.
4a20: 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e      if( pGroup->
4a30: 62 45 6e 61 62 6c 65 64 20 29 7b 0a 20 20 20 20  bEnabled ){.    
4a40: 20 20 2f 2a 20 4d 61 6b 65 20 73 75 72 65 20 74    /* Make sure t
4a50: 68 61 74 20 74 68 65 20 63 68 75 6e 6b 73 69 7a  hat the chunksiz
4a60: 65 20 69 73 20 73 75 63 68 20 74 68 61 74 20 74  e is such that t
4a70: 68 65 20 70 65 6e 64 69 6e 67 20 62 79 74 65 20  he pending byte 
4a80: 64 6f 65 73 20 6e 6f 74 0a 20 20 20 20 20 20 2a  does not.      *
4a90: 2a 20 66 61 6c 6c 73 20 61 74 20 74 68 65 20 65  * falls at the e
4aa0: 6e 64 20 6f 66 20 61 20 63 68 75 6e 6b 2e 20 20  nd of a chunk.  
4ab0: 41 20 72 65 67 69 6f 6e 20 6f 66 20 75 70 20 74  A region of up t
4ac0: 6f 20 36 34 4b 20 66 6f 6c 6c 6f 77 69 6e 67 0a  o 64K following.
4ad0: 20 20 20 20 20 20 2a 2a 20 74 68 65 20 70 65 6e        ** the pen
4ae0: 64 69 6e 67 20 62 79 74 65 20 69 73 20 6e 65 76  ding byte is nev
4af0: 65 72 20 77 72 69 74 74 65 6e 2c 20 73 6f 20 69  er written, so i
4b00: 66 20 74 68 65 20 70 65 6e 64 69 6e 67 20 62 79  f the pending by
4b10: 74 65 20 6f 63 63 75 72 73 0a 20 20 20 20 20 20  te occurs.      
4b20: 2a 2a 20 6e 65 61 72 20 74 68 65 20 65 6e 64 20  ** near the end 
4b30: 6f 66 20 61 20 63 68 75 6e 6b 2c 20 74 68 61 74  of a chunk, that
4b40: 20 63 68 75 6e 6b 20 77 69 6c 6c 20 62 65 20 74   chunk will be t
4b50: 6f 6f 20 73 6d 61 6c 6c 2e 20 2a 2f 0a 23 69 66  oo small. */.#if
4b60: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
4b70: 5f 57 53 44 0a 20 20 20 20 20 20 65 78 74 65 72  _WSD.      exter
4b80: 6e 20 69 6e 74 20 73 71 6c 69 74 65 33 50 65 6e  n int sqlite3Pen
4b90: 64 69 6e 67 42 79 74 65 3b 0a 23 65 6c 73 65 0a  dingByte;.#else.
4ba0: 20 20 20 20 20 20 69 6e 74 20 73 71 6c 69 74 65        int sqlite
4bb0: 33 50 65 6e 64 69 6e 67 42 79 74 65 20 3d 20 30  3PendingByte = 0
4bc0: 78 34 30 30 30 30 30 30 30 3b 0a 23 65 6e 64 69  x40000000;.#endi
4bd0: 66 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 28  f.      while( (
4be0: 73 71 6c 69 74 65 33 50 65 6e 64 69 6e 67 42 79  sqlite3PendingBy
4bf0: 74 65 20 25 20 70 47 72 6f 75 70 2d 3e 73 7a 43  te % pGroup->szC
4c00: 68 75 6e 6b 29 3e 3d 28 70 47 72 6f 75 70 2d 3e  hunk)>=(pGroup->
4c10: 73 7a 43 68 75 6e 6b 2d 36 35 35 33 36 29 20 29  szChunk-65536) )
4c20: 7b 0a 20 20 20 20 20 20 20 20 70 47 72 6f 75 70  {.        pGroup
4c30: 2d 3e 73 7a 43 68 75 6e 6b 20 2b 3d 20 36 35 35  ->szChunk += 655
4c40: 33 36 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  36;.      }.    
4c50: 7d 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 66 6c  }.    pGroup->fl
4c60: 61 67 73 20 3d 20 66 6c 61 67 73 3b 0a 20 20 20  ags = flags;.   
4c70: 20 72 63 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53   rc = multiplexS
4c80: 75 62 46 69 6c 65 6e 61 6d 65 28 70 47 72 6f 75  ubFilename(pGrou
4c90: 70 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20 72  p, 1);.    if( r
4ca0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
4cb0: 20 20 20 20 20 20 70 53 75 62 4f 70 65 6e 20 3d        pSubOpen =
4cc0: 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65   multiplexSubOpe
4cd0: 6e 28 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63  n(pGroup, 0, &rc
4ce0: 2c 20 70 4f 75 74 46 6c 61 67 73 2c 20 30 29 3b  , pOutFlags, 0);
4cf0: 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62 4f  .      if( pSubO
4d00: 70 65 6e 3d 3d 30 20 26 26 20 72 63 3d 3d 53 51  pen==0 && rc==SQ
4d10: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 53  LITE_OK ) rc = S
4d20: 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 3b 0a  QLITE_CANTOPEN;.
4d30: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
4d40: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
4d50: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74       sqlite3_int
4d60: 36 34 20 73 7a 3b 0a 0a 20 20 20 20 20 20 72 63  64 sz;..      rc
4d70: 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65   = pSubOpen->pMe
4d80: 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69 7a 65  thods->xFileSize
4d90: 28 70 53 75 62 4f 70 65 6e 2c 20 26 73 7a 29 3b  (pSubOpen, &sz);
4da0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
4db0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 7a 4e 61 6d  QLITE_OK && zNam
4dc0: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  e ){.        int
4dd0: 20 62 45 78 69 73 74 73 3b 0a 20 20 20 20 20 20   bExists;.      
4de0: 20 20 69 66 28 20 73 7a 3d 3d 30 20 29 7b 0a 20    if( sz==0 ){. 
4df0: 20 20 20 20 20 20 20 20 20 69 66 28 20 66 6c 61           if( fla
4e00: 67 73 20 26 20 53 51 4c 49 54 45 5f 4f 50 45 4e  gs & SQLITE_OPEN
4e10: 5f 4d 41 49 4e 5f 4a 4f 55 52 4e 41 4c 20 29 7b  _MAIN_JOURNAL ){
4e20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  .            /* 
4e30: 49 66 20 6f 70 65 6e 69 6e 67 20 61 20 6d 61 69  If opening a mai
4e40: 6e 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20 61  n journal file a
4e50: 6e 64 20 74 68 65 20 66 69 72 73 74 20 63 68 75  nd the first chu
4e60: 6e 6b 20 69 73 20 7a 65 72 6f 0a 20 20 20 20 20  nk is zero.     
4e70: 20 20 20 20 20 20 20 2a 2a 20 62 79 74 65 73 20         ** bytes 
4e80: 69 6e 20 73 69 7a 65 2c 20 64 65 6c 65 74 65 20  in size, delete 
4e90: 61 6e 79 20 73 75 62 73 65 71 75 65 6e 74 20 63  any subsequent c
4ea0: 68 75 6e 6b 73 20 66 72 6f 6d 20 74 68 65 20 0a  hunks from the .
4eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20 66              ** f
4ec0: 69 6c 65 2d 73 79 73 74 65 6d 2e 20 2a 2f 0a 20  ile-system. */. 
4ed0: 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 69             int i
4ee0: 43 68 75 6e 6b 20 3d 20 31 3b 0a 20 20 20 20 20  Chunk = 1;.     
4ef0: 20 20 20 20 20 20 20 64 6f 20 7b 0a 20 20 20 20         do {.    
4f00: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 70            rc = p
4f10: 4f 72 69 67 56 66 73 2d 3e 78 41 63 63 65 73 73  OrigVfs->xAccess
4f20: 28 70 4f 72 69 67 56 66 73 2c 20 0a 20 20 20 20  (pOrigVfs, .    
4f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 47                pG
4f40: 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75  roup->aReal[iChu
4f50: 6e 6b 5d 2e 7a 2c 20 53 51 4c 49 54 45 5f 41 43  nk].z, SQLITE_AC
4f60: 43 45 53 53 5f 45 58 49 53 54 53 2c 20 26 62 45  CESS_EXISTS, &bE
4f70: 78 69 73 74 73 0a 20 20 20 20 20 20 20 20 20 20  xists.          
4f80: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20      );.         
4f90: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
4fa0: 49 54 45 5f 4f 4b 20 26 26 20 62 45 78 69 73 74  ITE_OK && bExist
4fb0: 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  s ){.           
4fc0: 20 20 20 20 20 72 63 20 3d 20 70 4f 72 69 67 56       rc = pOrigV
4fd0: 66 73 2d 3e 78 44 65 6c 65 74 65 28 70 4f 72 69  fs->xDelete(pOri
4fe0: 67 56 66 73 2c 20 70 47 72 6f 75 70 2d 3e 61 52  gVfs, pGroup->aR
4ff0: 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 2c 20 30  eal[iChunk].z, 0
5000: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
5010: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
5020: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
5030: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 6d            rc = m
5040: 75 6c 74 69 70 6c 65 78 53 75 62 46 69 6c 65 6e  ultiplexSubFilen
5050: 61 6d 65 28 70 47 72 6f 75 70 2c 20 2b 2b 69 43  ame(pGroup, ++iC
5060: 68 75 6e 6b 29 3b 0a 20 20 20 20 20 20 20 20 20  hunk);.         
5070: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5080: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
5090: 20 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63 3d       }while( rc=
50a0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45  =SQLITE_OK && bE
50b0: 78 69 73 74 73 20 29 3b 0a 20 20 20 20 20 20 20  xists );.       
50c0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 65 6c     }.        }el
50d0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a  se{.          /*
50e0: 20 49 66 20 74 68 65 20 66 69 72 73 74 20 6f 76   If the first ov
50f0: 65 72 66 6c 6f 77 20 66 69 6c 65 20 65 78 69 73  erflow file exis
5100: 74 73 20 61 6e 64 20 69 66 20 74 68 65 20 73 69  ts and if the si
5110: 7a 65 20 6f 66 20 74 68 65 20 6d 61 69 6e 20 66  ze of the main f
5120: 69 6c 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  ile.          **
5130: 20 69 73 20 64 69 66 66 65 72 65 6e 74 20 66 72   is different fr
5140: 6f 6d 20 74 68 65 20 63 68 75 6e 6b 20 73 69 7a  om the chunk siz
5150: 65 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 74 68  e, that means th
5160: 65 20 63 68 75 6e 6b 20 73 69 7a 65 20 69 73 20  e chunk size is 
5170: 73 65 74 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  set.          **
5180: 20 73 65 74 20 69 6e 63 6f 72 72 65 63 74 6c 79   set incorrectly
5190: 2e 20 20 53 6f 20 66 69 78 20 69 74 2e 0a 20 20  .  So fix it..  
51a0: 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20          **.     
51b0: 20 20 20 20 20 2a 2a 20 4f 72 2c 20 69 66 20 74       ** Or, if t
51c0: 68 65 20 66 69 72 73 74 20 6f 76 65 72 66 6c 6f  he first overflo
51d0: 77 20 66 69 6c 65 20 64 6f 65 73 20 6e 6f 74 20  w file does not 
51e0: 65 78 69 73 74 20 61 6e 64 20 74 68 65 20 6d 61  exist and the ma
51f0: 69 6e 20 66 69 6c 65 20 69 73 0a 20 20 20 20 20  in file is.     
5200: 20 20 20 20 20 2a 2a 20 6c 61 72 67 65 72 20 74       ** larger t
5210: 68 61 6e 20 74 68 65 20 63 68 75 6e 6b 20 73 69  han the chunk si
5220: 7a 65 2c 20 74 68 61 74 20 6d 65 61 6e 73 20 74  ze, that means t
5230: 68 65 20 63 68 75 6e 6b 20 73 69 7a 65 20 69 73  he chunk size is
5240: 20 74 6f 6f 20 73 6d 61 6c 6c 2e 0a 20 20 20 20   too small..    
5250: 20 20 20 20 20 20 2a 2a 20 42 75 74 20 77 65 20        ** But we 
5260: 68 61 76 65 20 6e 6f 20 77 61 79 20 6f 66 20 64  have no way of d
5270: 65 74 65 72 6d 69 6e 69 6e 67 20 74 68 65 20 69  etermining the i
5280: 6e 74 65 6e 64 65 64 20 63 68 75 6e 6b 20 73 69  ntended chunk si
5290: 7a 65 2c 20 73 6f 20 0a 20 20 20 20 20 20 20 20  ze, so .        
52a0: 20 20 2a 2a 20 6a 75 73 74 20 64 69 73 61 62 6c    ** just disabl
52b0: 65 20 74 68 65 20 6d 75 6c 74 69 70 6c 65 78 6f  e the multiplexo
52c0: 72 20 61 6c 6c 20 74 6f 67 65 74 68 72 65 2e 0a  r all togethre..
52d0: 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20            */.   
52e0: 20 20 20 20 20 20 20 72 63 20 3d 20 70 4f 72 69         rc = pOri
52f0: 67 56 66 73 2d 3e 78 41 63 63 65 73 73 28 70 4f  gVfs->xAccess(pO
5300: 72 69 67 56 66 73 2c 20 70 47 72 6f 75 70 2d 3e  rigVfs, pGroup->
5310: 61 52 65 61 6c 5b 31 5d 2e 7a 2c 0a 20 20 20 20  aReal[1].z,.    
5320: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
5330: 5f 41 43 43 45 53 53 5f 45 58 49 53 54 53 2c 20  _ACCESS_EXISTS, 
5340: 26 62 45 78 69 73 74 73 29 3b 0a 20 20 20 20 20  &bExists);.     
5350: 20 20 20 20 20 62 45 78 69 73 74 73 20 3d 20 6d       bExists = m
5360: 75 6c 74 69 70 6c 65 78 53 75 62 53 69 7a 65 28  ultiplexSubSize(
5370: 70 47 72 6f 75 70 2c 20 31 2c 20 26 72 63 29 3e  pGroup, 1, &rc)>
5380: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  0;.          if(
5390: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
53a0: 26 20 62 45 78 69 73 74 73 20 20 26 26 20 73 7a  & bExists  && sz
53b0: 3d 3d 28 73 7a 26 30 78 66 66 66 66 30 30 30 30  ==(sz&0xffff0000
53c0: 29 20 26 26 20 73 7a 3e 30 0a 20 20 20 20 20 20  ) && sz>0.      
53d0: 20 20 20 20 20 20 20 20 26 26 20 73 7a 21 3d 70          && sz!=p
53e0: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 29  Group->szChunk )
53f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 47  {.            pG
5400: 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 3d 20  roup->szChunk = 
5410: 28 69 6e 74 29 73 7a 3b 0a 20 20 20 20 20 20 20  (int)sz;.       
5420: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d     }else if( rc=
5430: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 21 62  =SQLITE_OK && !b
5440: 45 78 69 73 74 73 20 26 26 20 73 7a 3e 70 47 72  Exists && sz>pGr
5450: 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 29 7b 0a  oup->szChunk ){.
5460: 20 20 20 20 20 20 20 20 20 20 20 20 70 47 72 6f              pGro
5470: 75 70 2d 3e 62 45 6e 61 62 6c 65 64 20 3d 20 30  up->bEnabled = 0
5480: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
5490: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
54a0: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
54b0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
54c0: 20 20 20 20 20 20 69 66 28 20 70 53 75 62 4f 70        if( pSubOp
54d0: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 69 56  en->pMethods->iV
54e0: 65 72 73 69 6f 6e 3d 3d 31 20 29 7b 0a 20 20 20  ersion==1 ){.   
54f0: 20 20 20 20 20 70 4d 75 6c 74 69 70 6c 65 78 4f       pMultiplexO
5500: 70 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f  pen->base.pMetho
5510: 64 73 20 3d 20 26 67 4d 75 6c 74 69 70 6c 65 78  ds = &gMultiplex
5520: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 3b 0a 20  .sIoMethodsV1;. 
5530: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
5540: 20 20 20 20 70 4d 75 6c 74 69 70 6c 65 78 4f 70      pMultiplexOp
5550: 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f 64  en->base.pMethod
5560: 73 20 3d 20 26 67 4d 75 6c 74 69 70 6c 65 78 2e  s = &gMultiplex.
5570: 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b 0a 20 20  sIoMethodsV2;.  
5580: 20 20 20 20 7d 0a 20 20 20 20 20 20 2f 2a 20 70      }.      /* p
5590: 6c 61 63 65 20 74 68 69 73 20 67 72 6f 75 70 20  lace this group 
55a0: 61 74 20 74 68 65 20 68 65 61 64 20 6f 66 20 6f  at the head of o
55b0: 75 72 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20 20  ur list */.     
55c0: 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 20 3d   pGroup->pNext =
55d0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 47 72 6f   gMultiplex.pGro
55e0: 75 70 73 3b 0a 20 20 20 20 20 20 69 66 28 20 67  ups;.      if( g
55f0: 4d 75 6c 74 69 70 6c 65 78 2e 70 47 72 6f 75 70  Multiplex.pGroup
5600: 73 20 29 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70  s ) gMultiplex.p
5610: 47 72 6f 75 70 73 2d 3e 70 50 72 65 76 20 3d 20  Groups->pPrev = 
5620: 70 47 72 6f 75 70 3b 0a 20 20 20 20 20 20 67 4d  pGroup;.      gM
5630: 75 6c 74 69 70 6c 65 78 2e 70 47 72 6f 75 70 73  ultiplex.pGroups
5640: 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20 20 20 7d   = pGroup;.    }
5650: 65 6c 73 65 7b 0a 20 20 20 20 20 20 6d 75 6c 74  else{.      mult
5660: 69 70 6c 65 78 46 72 65 65 43 6f 6d 70 6f 6e 65  iplexFreeCompone
5670: 6e 74 73 28 70 47 72 6f 75 70 29 3b 0a 20 20 20  nts(pGroup);.   
5680: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
5690: 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 7d 0a 20  pGroup);.    }. 
56a0: 20 7d 0a 20 20 6d 75 6c 74 69 70 6c 65 78 4c 65   }.  multiplexLe
56b0: 61 76 65 28 29 3b 0a 20 20 73 71 6c 69 74 65 33  ave();.  sqlite3
56c0: 5f 66 72 65 65 28 7a 54 6f 46 72 65 65 29 3b 0a  _free(zToFree);.
56d0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
56e0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
56f0: 65 20 78 44 65 6c 65 74 65 20 6d 65 74 68 6f 64  e xDelete method
5700: 20 75 73 65 64 20 66 6f 72 20 74 68 65 20 22 6d   used for the "m
5710: 75 6c 74 69 70 6c 65 78 22 20 56 46 53 2e 0a 2a  ultiplex" VFS..*
5720: 2a 20 49 74 20 61 74 74 65 6d 70 74 73 20 74 6f  * It attempts to
5730: 20 64 65 6c 65 74 65 20 74 68 65 20 66 69 6c 65   delete the file
5740: 6e 61 6d 65 20 73 70 65 63 69 66 69 65 64 2e 0a  name specified..
5750: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75  */.static int mu
5760: 6c 74 69 70 6c 65 78 44 65 6c 65 74 65 28 0a 20  ltiplexDelete(. 
5770: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
5780: 66 73 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 54  fs,         /* T
5790: 68 65 20 6d 75 6c 74 69 70 6c 65 78 20 56 46 53  he multiplex VFS
57a0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
57b0: 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20   *zName,        
57c0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c 65   /* Name of file
57d0: 20 74 6f 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20   to delete */.  
57e0: 69 6e 74 20 73 79 6e 63 44 69 72 0a 29 7b 0a 20  int syncDir.){. 
57f0: 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74   int rc;.  sqlit
5800: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
5810: 20 3d 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f   = gMultiplex.pO
5820: 72 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61  rigVfs;   /* Rea
5830: 6c 20 56 46 53 20 2a 2f 0a 20 20 72 63 20 3d 20  l VFS */.  rc = 
5840: 70 4f 72 69 67 56 66 73 2d 3e 78 44 65 6c 65 74  pOrigVfs->xDelet
5850: 65 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61 6d  e(pOrigVfs, zNam
5860: 65 2c 20 73 79 6e 63 44 69 72 29 3b 0a 20 20 69  e, syncDir);.  i
5870: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
5880: 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 74 68   ){.    /* If th
5890: 65 20 6d 61 69 6e 20 63 68 75 6e 6b 20 77 61 73  e main chunk was
58a0: 20 64 65 6c 65 74 65 64 20 73 75 63 63 65 73 73   deleted success
58b0: 66 75 6c 6c 79 2c 20 61 6c 73 6f 20 64 65 6c 65  fully, also dele
58c0: 74 65 20 61 6e 79 20 73 75 62 73 65 71 75 65 6e  te any subsequen
58d0: 74 0a 20 20 20 20 2a 2a 20 63 68 75 6e 6b 73 20  t.    ** chunks 
58e0: 2d 20 73 74 61 72 74 69 6e 67 20 77 69 74 68 20  - starting with 
58f0: 74 68 65 20 6c 61 73 74 20 28 68 69 67 68 65 73  the last (highes
5900: 74 20 6e 75 6d 62 65 72 65 64 29 2e 20 0a 20 20  t numbered). .  
5910: 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 4e 61    */.    int nNa
5920: 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d  me = strlen(zNam
5930: 65 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 3b  e);.    char *z;
5940: 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33  .    z = sqlite3
5950: 5f 6d 61 6c 6c 6f 63 28 6e 4e 61 6d 65 20 2b 20  _malloc(nName + 
5960: 35 29 3b 0a 20 20 20 20 69 66 28 20 7a 3d 3d 30  5);.    if( z==0
5970: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
5980: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 4e 4f 4d 45  QLITE_IOERR_NOME
5990: 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  M;.    }else{.  
59a0: 20 20 20 20 69 6e 74 20 69 43 68 75 6e 6b 20 3d      int iChunk =
59b0: 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 62 45   0;.      int bE
59c0: 78 69 73 74 73 3b 0a 20 20 20 20 20 20 64 6f 7b  xists;.      do{
59d0: 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 70 6c  .        multipl
59e0: 65 78 46 69 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65  exFilename(zName
59f0: 2c 20 6e 4e 61 6d 65 2c 20 53 51 4c 49 54 45 5f  , nName, SQLITE_
5a00: 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e 41  OPEN_MAIN_JOURNA
5a10: 4c 2c 20 2b 2b 69 43 68 75 6e 6b 2c 20 7a 29 3b  L, ++iChunk, z);
5a20: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 4f  .        rc = pO
5a30: 72 69 67 56 66 73 2d 3e 78 41 63 63 65 73 73 28  rigVfs->xAccess(
5a40: 70 4f 72 69 67 56 66 73 2c 20 7a 2c 20 53 51 4c  pOrigVfs, z, SQL
5a50: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
5a60: 53 2c 20 26 62 45 78 69 73 74 73 29 3b 0a 20 20  S, &bExists);.  
5a70: 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d      }while( rc==
5a80: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 78  SQLITE_OK && bEx
5a90: 69 73 74 73 20 29 3b 0a 20 20 20 20 20 20 77 68  ists );.      wh
5aa0: 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
5ab0: 4f 4b 20 26 26 20 69 43 68 75 6e 6b 3e 31 20 29  OK && iChunk>1 )
5ac0: 7b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 70  {.        multip
5ad0: 6c 65 78 46 69 6c 65 6e 61 6d 65 28 7a 4e 61 6d  lexFilename(zNam
5ae0: 65 2c 20 6e 4e 61 6d 65 2c 20 53 51 4c 49 54 45  e, nName, SQLITE
5af0: 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e  _OPEN_MAIN_JOURN
5b00: 41 4c 2c 20 2d 2d 69 43 68 75 6e 6b 2c 20 7a 29  AL, --iChunk, z)
5b10: 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70  ;.        rc = p
5b20: 4f 72 69 67 56 66 73 2d 3e 78 44 65 6c 65 74 65  OrigVfs->xDelete
5b30: 28 70 4f 72 69 67 56 66 73 2c 20 7a 2c 20 73 79  (pOrigVfs, z, sy
5b40: 6e 63 44 69 72 29 3b 0a 20 20 20 20 20 20 7d 0a  ncDir);.      }.
5b50: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
5b60: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
5b70: 20 20 20 69 43 68 75 6e 6b 20 3d 20 30 3b 0a 20     iChunk = 0;. 
5b80: 20 20 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20         do{.     
5b90: 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78 46 69       multiplexFi
5ba0: 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e  lename(zName, nN
5bb0: 61 6d 65 2c 20 53 51 4c 49 54 45 5f 4f 50 45 4e  ame, SQLITE_OPEN
5bc0: 5f 57 41 4c 2c 20 2b 2b 69 43 68 75 6e 6b 2c 20  _WAL, ++iChunk, 
5bd0: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  z);.          rc
5be0: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 41 63   = pOrigVfs->xAc
5bf0: 63 65 73 73 28 70 4f 72 69 67 56 66 73 2c 20 7a  cess(pOrigVfs, z
5c00: 2c 20 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f  , SQLITE_ACCESS_
5c10: 45 58 49 53 54 53 2c 20 26 62 45 78 69 73 74 73  EXISTS, &bExists
5c20: 29 3b 0a 20 20 20 20 20 20 20 20 7d 77 68 69 6c  );.        }whil
5c30: 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
5c40: 20 26 26 20 62 45 78 69 73 74 73 20 29 3b 0a 20   && bExists );. 
5c50: 20 20 20 20 20 20 20 77 68 69 6c 65 28 20 72 63         while( rc
5c60: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
5c70: 43 68 75 6e 6b 3e 31 20 29 7b 0a 20 20 20 20 20  Chunk>1 ){.     
5c80: 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78 46 69       multiplexFi
5c90: 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e  lename(zName, nN
5ca0: 61 6d 65 2c 20 53 51 4c 49 54 45 5f 4f 50 45 4e  ame, SQLITE_OPEN
5cb0: 5f 57 41 4c 2c 20 2d 2d 69 43 68 75 6e 6b 2c 20  _WAL, --iChunk, 
5cc0: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  z);.          rc
5cd0: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 44 65   = pOrigVfs->xDe
5ce0: 6c 65 74 65 28 70 4f 72 69 67 56 66 73 2c 20 7a  lete(pOrigVfs, z
5cf0: 2c 20 73 79 6e 63 44 69 72 29 3b 0a 20 20 20 20  , syncDir);.    
5d00: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
5d10: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
5d20: 66 72 65 65 28 7a 29 3b 0a 20 20 7d 0a 20 20 72  free(z);.  }.  r
5d30: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
5d40: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
5d50: 78 41 63 63 65 73 73 28 73 71 6c 69 74 65 33 5f  xAccess(sqlite3_
5d60: 76 66 73 20 2a 61 2c 20 63 6f 6e 73 74 20 63 68  vfs *a, const ch
5d70: 61 72 20 2a 62 2c 20 69 6e 74 20 63 2c 20 69 6e  ar *b, int c, in
5d80: 74 20 2a 64 29 7b 0a 20 20 72 65 74 75 72 6e 20  t *d){.  return 
5d90: 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67  gMultiplex.pOrig
5da0: 56 66 73 2d 3e 78 41 63 63 65 73 73 28 67 4d 75  Vfs->xAccess(gMu
5db0: 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73  ltiplex.pOrigVfs
5dc0: 2c 20 62 2c 20 63 2c 20 64 29 3b 0a 7d 0a 73 74  , b, c, d);.}.st
5dd0: 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c  atic int multipl
5de0: 65 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 73  exFullPathname(s
5df0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 61 2c 20 63  qlite3_vfs *a, c
5e00: 6f 6e 73 74 20 63 68 61 72 20 2a 62 2c 20 69 6e  onst char *b, in
5e10: 74 20 63 2c 20 63 68 61 72 20 2a 64 29 7b 0a 20  t c, char *d){. 
5e20: 20 72 65 74 75 72 6e 20 67 4d 75 6c 74 69 70 6c   return gMultipl
5e30: 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78 46 75  ex.pOrigVfs->xFu
5e40: 6c 6c 50 61 74 68 6e 61 6d 65 28 67 4d 75 6c 74  llPathname(gMult
5e50: 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2c 20  iplex.pOrigVfs, 
5e60: 62 2c 20 63 2c 20 64 29 3b 0a 7d 0a 73 74 61 74  b, c, d);.}.stat
5e70: 69 63 20 76 6f 69 64 20 2a 6d 75 6c 74 69 70 6c  ic void *multipl
5e80: 65 78 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33  exDlOpen(sqlite3
5e90: 5f 76 66 73 20 2a 61 2c 20 63 6f 6e 73 74 20 63  _vfs *a, const c
5ea0: 68 61 72 20 2a 62 29 7b 0a 20 20 72 65 74 75 72  har *b){.  retur
5eb0: 6e 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72  n gMultiplex.pOr
5ec0: 69 67 56 66 73 2d 3e 78 44 6c 4f 70 65 6e 28 67  igVfs->xDlOpen(g
5ed0: 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56  Multiplex.pOrigV
5ee0: 66 73 2c 20 62 29 3b 0a 7d 0a 73 74 61 74 69 63  fs, b);.}.static
5ef0: 20 76 6f 69 64 20 6d 75 6c 74 69 70 6c 65 78 44   void multiplexD
5f00: 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76  lError(sqlite3_v
5f10: 66 73 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68  fs *a, int b, ch
5f20: 61 72 20 2a 63 29 7b 0a 20 20 67 4d 75 6c 74 69  ar *c){.  gMulti
5f30: 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78  plex.pOrigVfs->x
5f40: 44 6c 45 72 72 6f 72 28 67 4d 75 6c 74 69 70 6c  DlError(gMultipl
5f50: 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 2c 20  ex.pOrigVfs, b, 
5f60: 63 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  c);.}.static voi
5f70: 64 20 28 2a 6d 75 6c 74 69 70 6c 65 78 44 6c 53  d (*multiplexDlS
5f80: 79 6d 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  ym(sqlite3_vfs *
5f90: 61 2c 20 76 6f 69 64 20 2a 62 2c 20 63 6f 6e 73  a, void *b, cons
5fa0: 74 20 63 68 61 72 20 2a 63 29 29 28 76 6f 69 64  t char *c))(void
5fb0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 4d 75 6c  ){.  return gMul
5fc0: 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d  tiplex.pOrigVfs-
5fd0: 3e 78 44 6c 53 79 6d 28 67 4d 75 6c 74 69 70 6c  >xDlSym(gMultipl
5fe0: 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 2c 20  ex.pOrigVfs, b, 
5ff0: 63 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  c);.}.static voi
6000: 64 20 6d 75 6c 74 69 70 6c 65 78 44 6c 43 6c 6f  d multiplexDlClo
6010: 73 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  se(sqlite3_vfs *
6020: 61 2c 20 76 6f 69 64 20 2a 62 29 7b 0a 20 20 67  a, void *b){.  g
6030: 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56  Multiplex.pOrigV
6040: 66 73 2d 3e 78 44 6c 43 6c 6f 73 65 28 67 4d 75  fs->xDlClose(gMu
6050: 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73  ltiplex.pOrigVfs
6060: 2c 20 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  , b);.}.static i
6070: 6e 74 20 6d 75 6c 74 69 70 6c 65 78 52 61 6e 64  nt multiplexRand
6080: 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f 76  omness(sqlite3_v
6090: 66 73 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68  fs *a, int b, ch
60a0: 61 72 20 2a 63 29 7b 0a 20 20 72 65 74 75 72 6e  ar *c){.  return
60b0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69   gMultiplex.pOri
60c0: 67 56 66 73 2d 3e 78 52 61 6e 64 6f 6d 6e 65 73  gVfs->xRandomnes
60d0: 73 28 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72  s(gMultiplex.pOr
60e0: 69 67 56 66 73 2c 20 62 2c 20 63 29 3b 0a 7d 0a  igVfs, b, c);.}.
60f0: 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69  static int multi
6100: 70 6c 65 78 53 6c 65 65 70 28 73 71 6c 69 74 65  plexSleep(sqlite
6110: 33 5f 76 66 73 20 2a 61 2c 20 69 6e 74 20 62 29  3_vfs *a, int b)
6120: 7b 0a 20 20 72 65 74 75 72 6e 20 67 4d 75 6c 74  {.  return gMult
6130: 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e  iplex.pOrigVfs->
6140: 78 53 6c 65 65 70 28 67 4d 75 6c 74 69 70 6c 65  xSleep(gMultiple
6150: 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 29 3b 0a  x.pOrigVfs, b);.
6160: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c  }.static int mul
6170: 74 69 70 6c 65 78 43 75 72 72 65 6e 74 54 69 6d  tiplexCurrentTim
6180: 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 61  e(sqlite3_vfs *a
6190: 2c 20 64 6f 75 62 6c 65 20 2a 62 29 7b 0a 20 20  , double *b){.  
61a0: 72 65 74 75 72 6e 20 67 4d 75 6c 74 69 70 6c 65  return gMultiple
61b0: 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78 43 75 72  x.pOrigVfs->xCur
61c0: 72 65 6e 74 54 69 6d 65 28 67 4d 75 6c 74 69 70  rentTime(gMultip
61d0: 6c 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 29  lex.pOrigVfs, b)
61e0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 6d  ;.}.static int m
61f0: 75 6c 74 69 70 6c 65 78 47 65 74 4c 61 73 74 45  ultiplexGetLastE
6200: 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66 73  rror(sqlite3_vfs
6210: 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68 61 72   *a, int b, char
6220: 20 2a 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 67   *c){.  return g
6230: 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56  Multiplex.pOrigV
6240: 66 73 2d 3e 78 47 65 74 4c 61 73 74 45 72 72 6f  fs->xGetLastErro
6250: 72 28 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72  r(gMultiplex.pOr
6260: 69 67 56 66 73 2c 20 62 2c 20 63 29 3b 0a 7d 0a  igVfs, b, c);.}.
6270: 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69  static int multi
6280: 70 6c 65 78 43 75 72 72 65 6e 74 54 69 6d 65 49  plexCurrentTimeI
6290: 6e 74 36 34 28 73 71 6c 69 74 65 33 5f 76 66 73  nt64(sqlite3_vfs
62a0: 20 2a 61 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74   *a, sqlite3_int
62b0: 36 34 20 2a 62 29 7b 0a 20 20 72 65 74 75 72 6e  64 *b){.  return
62c0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69   gMultiplex.pOri
62d0: 67 56 66 73 2d 3e 78 43 75 72 72 65 6e 74 54 69  gVfs->xCurrentTi
62e0: 6d 65 49 6e 74 36 34 28 67 4d 75 6c 74 69 70 6c  meInt64(gMultipl
62f0: 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 29 3b  ex.pOrigVfs, b);
6300: 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .}../***********
6310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 49 2f  ************* I/
6320: 4f 20 4d 65 74 68 6f 64 20 57 72 61 70 70 65 72  O Method Wrapper
6330: 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s **************
6340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6350: 2a 2f 0a 0a 2f 2a 20 78 43 6c 6f 73 65 20 72 65  */../* xClose re
6360: 71 75 65 73 74 73 20 67 65 74 20 70 61 73 73 65  quests get passe
6370: 64 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65  d through to the
6380: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 0a 2a   original VFS..*
6390: 2a 20 57 65 20 6c 6f 6f 70 20 6f 76 65 72 20 61  * We loop over a
63a0: 6c 6c 20 6f 70 65 6e 20 63 68 75 6e 6b 20 68 61  ll open chunk ha
63b0: 6e 64 6c 65 73 20 61 6e 64 20 63 6c 6f 73 65 20  ndles and close 
63c0: 74 68 65 6d 2e 0a 2a 2a 20 54 68 65 20 67 72 6f  them..** The gro
63d0: 75 70 20 73 74 72 75 63 74 75 72 65 20 66 6f 72  up structure for
63e0: 20 74 68 69 73 20 66 69 6c 65 20 69 73 20 75 6e   this file is un
63f0: 6c 69 6e 6b 65 64 20 66 72 6f 6d 20 0a 2a 2a 20  linked from .** 
6400: 6f 75 72 20 6c 69 73 74 20 6f 66 20 67 72 6f 75  our list of grou
6410: 70 73 20 61 6e 64 20 66 72 65 65 64 2e 0a 2a 2f  ps and freed..*/
6420: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
6430: 69 70 6c 65 78 43 6c 6f 73 65 28 73 71 6c 69 74  iplexClose(sqlit
6440: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b  e3_file *pConn){
6450: 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e  .  multiplexConn
6460: 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78   *p = (multiplex
6470: 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 6d  Conn*)pConn;.  m
6480: 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a 70  ultiplexGroup *p
6490: 47 72 6f 75 70 20 3d 20 70 2d 3e 70 47 72 6f 75  Group = p->pGrou
64a0: 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  p;.  int rc = SQ
64b0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 6d 75 6c 74 69  LITE_OK;.  multi
64c0: 70 6c 65 78 45 6e 74 65 72 28 29 3b 0a 20 20 6d  plexEnter();.  m
64d0: 75 6c 74 69 70 6c 65 78 46 72 65 65 43 6f 6d 70  ultiplexFreeComp
64e0: 6f 6e 65 6e 74 73 28 70 47 72 6f 75 70 29 3b 0a  onents(pGroup);.
64f0: 20 20 2f 2a 20 72 65 6d 6f 76 65 20 66 72 6f 6d    /* remove from
6500: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 2a 2f 0a   linked list */.
6510: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 4e    if( pGroup->pN
6520: 65 78 74 20 29 20 70 47 72 6f 75 70 2d 3e 70 4e  ext ) pGroup->pN
6530: 65 78 74 2d 3e 70 50 72 65 76 20 3d 20 70 47 72  ext->pPrev = pGr
6540: 6f 75 70 2d 3e 70 50 72 65 76 3b 0a 20 20 69 66  oup->pPrev;.  if
6550: 28 20 70 47 72 6f 75 70 2d 3e 70 50 72 65 76 20  ( pGroup->pPrev 
6560: 29 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  ){.    pGroup->p
6570: 50 72 65 76 2d 3e 70 4e 65 78 74 20 3d 20 70 47  Prev->pNext = pG
6580: 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d  roup->pNext;.  }
6590: 65 6c 73 65 7b 0a 20 20 20 20 67 4d 75 6c 74 69  else{.    gMulti
65a0: 70 6c 65 78 2e 70 47 72 6f 75 70 73 20 3d 20 70  plex.pGroups = p
65b0: 47 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20  Group->pNext;.  
65c0: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  }.  sqlite3_free
65d0: 28 70 47 72 6f 75 70 29 3b 0a 20 20 6d 75 6c 74  (pGroup);.  mult
65e0: 69 70 6c 65 78 4c 65 61 76 65 28 29 3b 0a 20 20  iplexLeave();.  
65f0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6600: 20 50 61 73 73 20 78 52 65 61 64 20 72 65 71 75   Pass xRead requ
6610: 65 73 74 73 20 74 68 72 75 20 74 6f 20 74 68 65  ests thru to the
6620: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 61 66   original VFS af
6630: 74 65 72 0a 2a 2a 20 64 65 74 65 72 6d 69 6e 69  ter.** determini
6640: 6e 67 20 74 68 65 20 63 6f 72 72 65 63 74 20 63  ng the correct c
6650: 68 75 6e 6b 20 74 6f 20 6f 70 65 72 61 74 65 20  hunk to operate 
6660: 6f 6e 2e 0a 2a 2a 20 42 72 65 61 6b 20 75 70 20  on..** Break up 
6670: 72 65 61 64 73 20 61 63 72 6f 73 73 20 63 68 75  reads across chu
6680: 6e 6b 20 62 6f 75 6e 64 61 72 69 65 73 2e 0a 2a  nk boundaries..*
6690: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c  /.static int mul
66a0: 74 69 70 6c 65 78 52 65 61 64 28 0a 20 20 73 71  tiplexRead(.  sq
66b0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e  lite3_file *pCon
66c0: 6e 2c 0a 20 20 76 6f 69 64 20 2a 70 42 75 66 2c  n,.  void *pBuf,
66d0: 0a 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20 20 73  .  int iAmt,.  s
66e0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
66f0: 73 74 0a 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65  st.){.  multiple
6700: 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74  xConn *p = (mult
6710: 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e  iplexConn*)pConn
6720: 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f  ;.  multiplexGro
6730: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e  up *pGroup = p->
6740: 70 47 72 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63  pGroup;.  int rc
6750: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
6760: 6d 75 6c 74 69 70 6c 65 78 45 6e 74 65 72 28 29  multiplexEnter()
6770: 3b 0a 20 20 69 66 28 20 21 70 47 72 6f 75 70 2d  ;.  if( !pGroup-
6780: 3e 62 45 6e 61 62 6c 65 64 20 29 7b 0a 20 20 20  >bEnabled ){.   
6790: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
67a0: 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70  SubOpen = multip
67b0: 6c 65 78 53 75 62 4f 70 65 6e 28 70 47 72 6f 75  lexSubOpen(pGrou
67c0: 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c  p, 0, &rc, NULL,
67d0: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 70 53 75   0);.    if( pSu
67e0: 62 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20  bOpen==0 ){.    
67f0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f    rc = SQLITE_IO
6800: 45 52 52 5f 52 45 41 44 3b 0a 20 20 20 20 7d 65  ERR_READ;.    }e
6810: 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  lse{.      rc = 
6820: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
6830: 64 73 2d 3e 78 52 65 61 64 28 70 53 75 62 4f 70  ds->xRead(pSubOp
6840: 65 6e 2c 20 70 42 75 66 2c 20 69 41 6d 74 2c 20  en, pBuf, iAmt, 
6850: 69 4f 66 73 74 29 3b 0a 20 20 20 20 7d 0a 20 20  iOfst);.    }.  
6860: 7d 65 6c 73 65 7b 0a 20 20 20 20 77 68 69 6c 65  }else{.    while
6870: 28 20 69 41 6d 74 20 3e 20 30 20 29 7b 0a 20 20  ( iAmt > 0 ){.  
6880: 20 20 20 20 69 6e 74 20 69 20 3d 20 28 69 6e 74      int i = (int
6890: 29 28 69 4f 66 73 74 20 2f 20 70 47 72 6f 75 70  )(iOfst / pGroup
68a0: 2d 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20 20 20 20  ->szChunk);.    
68b0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
68c0: 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69  pSubOpen = multi
68d0: 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 47 72 6f  plexSubOpen(pGro
68e0: 75 70 2c 20 69 2c 20 26 72 63 2c 20 4e 55 4c 4c  up, i, &rc, NULL
68f0: 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 1);.      if( 
6900: 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20  pSubOpen ){.    
6910: 20 20 20 20 69 6e 74 20 65 78 74 72 61 20 3d 20      int extra = 
6920: 28 28 69 6e 74 29 28 69 4f 66 73 74 20 25 20 70  ((int)(iOfst % p
6930: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 20  Group->szChunk) 
6940: 2b 20 69 41 6d 74 29 20 2d 20 70 47 72 6f 75 70  + iAmt) - pGroup
6950: 2d 3e 73 7a 43 68 75 6e 6b 3b 0a 20 20 20 20 20  ->szChunk;.     
6960: 20 20 20 69 66 28 20 65 78 74 72 61 3c 30 20 29     if( extra<0 )
6970: 20 65 78 74 72 61 20 3d 20 30 3b 0a 20 20 20 20   extra = 0;.    
6980: 20 20 20 20 69 41 6d 74 20 2d 3d 20 65 78 74 72      iAmt -= extr
6990: 61 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  a;.        rc = 
69a0: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
69b0: 64 73 2d 3e 78 52 65 61 64 28 70 53 75 62 4f 70  ds->xRead(pSubOp
69c0: 65 6e 2c 20 70 42 75 66 2c 20 69 41 6d 74 2c 0a  en, pBuf, iAmt,.
69d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69f0: 20 20 20 20 20 20 20 69 4f 66 73 74 20 25 20 70         iOfst % p
6a00: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 3b  Group->szChunk);
6a10: 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21  .        if( rc!
6a20: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65  =SQLITE_OK ) bre
6a30: 61 6b 3b 0a 20 20 20 20 20 20 20 20 70 42 75 66  ak;.        pBuf
6a40: 20 3d 20 28 63 68 61 72 20 2a 29 70 42 75 66 20   = (char *)pBuf 
6a50: 2b 20 69 41 6d 74 3b 0a 20 20 20 20 20 20 20 20  + iAmt;.        
6a60: 69 4f 66 73 74 20 2b 3d 20 69 41 6d 74 3b 0a 20  iOfst += iAmt;. 
6a70: 20 20 20 20 20 20 20 69 41 6d 74 20 3d 20 65 78         iAmt = ex
6a80: 74 72 61 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  tra;.      }else
6a90: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
6aa0: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 52 45 41 44  QLITE_IOERR_READ
6ab0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
6ac0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
6ad0: 20 7d 0a 20 20 6d 75 6c 74 69 70 6c 65 78 4c 65   }.  multiplexLe
6ae0: 61 76 65 28 29 3b 0a 20 20 72 65 74 75 72 6e 20  ave();.  return 
6af0: 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78  rc;.}../* Pass x
6b00: 57 72 69 74 65 20 72 65 71 75 65 73 74 73 20 74  Write requests t
6b10: 68 72 75 20 74 6f 20 74 68 65 20 6f 72 69 67 69  hru to the origi
6b20: 6e 61 6c 20 56 46 53 20 61 66 74 65 72 0a 2a 2a  nal VFS after.**
6b30: 20 64 65 74 65 72 6d 69 6e 69 6e 67 20 74 68 65   determining the
6b40: 20 63 6f 72 72 65 63 74 20 63 68 75 6e 6b 20 74   correct chunk t
6b50: 6f 20 6f 70 65 72 61 74 65 20 6f 6e 2e 0a 2a 2a  o operate on..**
6b60: 20 42 72 65 61 6b 20 75 70 20 77 72 69 74 65 73   Break up writes
6b70: 20 61 63 72 6f 73 73 20 63 68 75 6e 6b 20 62 6f   across chunk bo
6b80: 75 6e 64 61 72 69 65 73 2e 0a 2a 2f 0a 73 74 61  undaries..*/.sta
6b90: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
6ba0: 78 57 72 69 74 65 28 0a 20 20 73 71 6c 69 74 65  xWrite(.  sqlite
6bb0: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 0a 20  3_file *pConn,. 
6bc0: 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 42 75   const void *pBu
6bd0: 66 2c 0a 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20  f,.  int iAmt,. 
6be0: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
6bf0: 4f 66 73 74 0a 29 7b 0a 20 20 6d 75 6c 74 69 70  Ofst.){.  multip
6c00: 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75  lexConn *p = (mu
6c10: 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f  ltiplexConn*)pCo
6c20: 6e 6e 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47  nn;.  multiplexG
6c30: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
6c40: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 69 6e 74 20  ->pGroup;.  int 
6c50: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
6c60: 20 20 6d 75 6c 74 69 70 6c 65 78 45 6e 74 65 72    multiplexEnter
6c70: 28 29 3b 0a 20 20 69 66 28 20 21 70 47 72 6f 75  ();.  if( !pGrou
6c80: 70 2d 3e 62 45 6e 61 62 6c 65 64 20 29 7b 0a 20  p->bEnabled ){. 
6c90: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20     sqlite3_file 
6ca0: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74  *pSubOpen = mult
6cb0: 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 47 72  iplexSubOpen(pGr
6cc0: 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c  oup, 0, &rc, NUL
6cd0: 4c 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 70  L, 0);.    if( p
6ce0: 53 75 62 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20 20  SubOpen==0 ){.  
6cf0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
6d00: 49 4f 45 52 52 5f 57 52 49 54 45 3b 0a 20 20 20  IOERR_WRITE;.   
6d10: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
6d20: 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65   = pSubOpen->pMe
6d30: 74 68 6f 64 73 2d 3e 78 57 72 69 74 65 28 70 53  thods->xWrite(pS
6d40: 75 62 4f 70 65 6e 2c 20 70 42 75 66 2c 20 69 41  ubOpen, pBuf, iA
6d50: 6d 74 2c 20 69 4f 66 73 74 29 3b 0a 20 20 20 20  mt, iOfst);.    
6d60: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 77  }.  }else{.    w
6d70: 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  hile( rc==SQLITE
6d80: 5f 4f 4b 20 26 26 20 69 41 6d 74 3e 30 20 29 7b  _OK && iAmt>0 ){
6d90: 0a 20 20 20 20 20 20 69 6e 74 20 69 20 3d 20 28  .      int i = (
6da0: 69 6e 74 29 28 69 4f 66 73 74 20 2f 20 70 47 72  int)(iOfst / pGr
6db0: 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20  oup->szChunk);. 
6dc0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c       sqlite3_fil
6dd0: 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75  e *pSubOpen = mu
6de0: 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70  ltiplexSubOpen(p
6df0: 47 72 6f 75 70 2c 20 69 2c 20 26 72 63 2c 20 4e  Group, i, &rc, N
6e00: 55 4c 4c 2c 20 31 29 3b 0a 20 20 20 20 20 20 69  ULL, 1);.      i
6e10: 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20  f( pSubOpen ){. 
6e20: 20 20 20 20 20 20 20 69 6e 74 20 65 78 74 72 61         int extra
6e30: 20 3d 20 28 28 69 6e 74 29 28 69 4f 66 73 74 20   = ((int)(iOfst 
6e40: 25 20 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e  % pGroup->szChun
6e50: 6b 29 20 2b 20 69 41 6d 74 29 20 2d 0a 20 20 20  k) + iAmt) -.   
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e70: 20 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b   pGroup->szChunk
6e80: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 78  ;.        if( ex
6e90: 74 72 61 3c 30 20 29 20 65 78 74 72 61 20 3d 20  tra<0 ) extra = 
6ea0: 30 3b 0a 20 20 20 20 20 20 20 20 69 41 6d 74 20  0;.        iAmt 
6eb0: 2d 3d 20 65 78 74 72 61 3b 0a 20 20 20 20 20 20  -= extra;.      
6ec0: 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d    rc = pSubOpen-
6ed0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57 72 69 74  >pMethods->xWrit
6ee0: 65 28 70 53 75 62 4f 70 65 6e 2c 20 70 42 75 66  e(pSubOpen, pBuf
6ef0: 2c 20 69 41 6d 74 2c 0a 20 20 20 20 20 20 20 20  , iAmt,.        
6f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f20: 69 4f 66 73 74 20 25 20 70 47 72 6f 75 70 2d 3e  iOfst % pGroup->
6f30: 73 7a 43 68 75 6e 6b 29 3b 0a 20 20 20 20 20 20  szChunk);.      
6f40: 20 20 70 42 75 66 20 3d 20 28 63 68 61 72 20 2a    pBuf = (char *
6f50: 29 70 42 75 66 20 2b 20 69 41 6d 74 3b 0a 20 20  )pBuf + iAmt;.  
6f60: 20 20 20 20 20 20 69 4f 66 73 74 20 2b 3d 20 69        iOfst += i
6f70: 41 6d 74 3b 0a 20 20 20 20 20 20 20 20 69 41 6d  Amt;.        iAm
6f80: 74 20 3d 20 65 78 74 72 61 3b 0a 20 20 20 20 20  t = extra;.     
6f90: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 6d   }.    }.  }.  m
6fa0: 75 6c 74 69 70 6c 65 78 4c 65 61 76 65 28 29 3b  ultiplexLeave();
6fb0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6fc0: 0a 2f 2a 20 50 61 73 73 20 78 54 72 75 6e 63 61  ./* Pass xTrunca
6fd0: 74 65 20 72 65 71 75 65 73 74 73 20 74 68 72 75  te requests thru
6fe0: 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c   to the original
6ff0: 20 56 46 53 20 61 66 74 65 72 0a 2a 2a 20 64 65   VFS after.** de
7000: 74 65 72 6d 69 6e 69 6e 67 20 74 68 65 20 63 6f  termining the co
7010: 72 72 65 63 74 20 63 68 75 6e 6b 20 74 6f 20 6f  rrect chunk to o
7020: 70 65 72 61 74 65 20 6f 6e 2e 20 20 44 65 6c 65  perate on.  Dele
7030: 74 65 20 61 6e 79 0a 2a 2a 20 63 68 75 6e 6b 73  te any.** chunks
7040: 20 61 62 6f 76 65 20 74 68 65 20 74 72 75 6e 63   above the trunc
7050: 61 74 65 20 6d 61 72 6b 2e 0a 2a 2f 0a 73 74 61  ate mark..*/.sta
7060: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
7070: 78 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  xTruncate(sqlite
7080: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 73  3_file *pConn, s
7090: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 69 7a  qlite3_int64 siz
70a0: 65 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43  e){.  multiplexC
70b0: 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70  onn *p = (multip
70c0: 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a  lexConn*)pConn;.
70d0: 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70    multiplexGroup
70e0: 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e 70 47   *pGroup = p->pG
70f0: 72 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d  roup;.  int rc =
7100: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 6d 75   SQLITE_OK;.  mu
7110: 6c 74 69 70 6c 65 78 45 6e 74 65 72 28 29 3b 0a  ltiplexEnter();.
7120: 20 20 69 66 28 20 21 70 47 72 6f 75 70 2d 3e 62    if( !pGroup->b
7130: 45 6e 61 62 6c 65 64 20 29 7b 0a 20 20 20 20 73  Enabled ){.    s
7140: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
7150: 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65  bOpen = multiple
7160: 78 53 75 62 4f 70 65 6e 28 70 47 72 6f 75 70 2c  xSubOpen(pGroup,
7170: 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30   0, &rc, NULL, 0
7180: 29 3b 0a 20 20 20 20 69 66 28 20 70 53 75 62 4f  );.    if( pSubO
7190: 70 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  pen==0 ){.      
71a0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52  rc = SQLITE_IOER
71b0: 52 5f 54 52 55 4e 43 41 54 45 3b 0a 20 20 20 20  R_TRUNCATE;.    
71c0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
71d0: 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74  = pSubOpen->pMet
71e0: 68 6f 64 73 2d 3e 78 54 72 75 6e 63 61 74 65 28  hods->xTruncate(
71f0: 70 53 75 62 4f 70 65 6e 2c 20 73 69 7a 65 29 3b  pSubOpen, size);
7200: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
7210: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 69      int i;.    i
7220: 6e 74 20 69 42 61 73 65 47 72 6f 75 70 20 3d 20  nt iBaseGroup = 
7230: 28 69 6e 74 29 28 73 69 7a 65 20 2f 20 70 47 72  (int)(size / pGr
7240: 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20  oup->szChunk);. 
7250: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20     sqlite3_file 
7260: 2a 70 53 75 62 4f 70 65 6e 3b 0a 20 20 20 20 73  *pSubOpen;.    s
7270: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69  qlite3_vfs *pOri
7280: 67 56 66 73 20 3d 20 67 4d 75 6c 74 69 70 6c 65  gVfs = gMultiple
7290: 78 2e 70 4f 72 69 67 56 66 73 3b 20 20 20 2f 2a  x.pOrigVfs;   /*
72a0: 20 52 65 61 6c 20 56 46 53 20 2a 2f 0a 20 20 20   Real VFS */.   
72b0: 20 2f 2a 20 64 65 6c 65 74 65 20 74 68 65 20 63   /* delete the c
72c0: 68 75 6e 6b 73 20 61 62 6f 76 65 20 74 68 65 20  hunks above the 
72d0: 74 72 75 6e 63 61 74 65 20 6c 69 6d 69 74 20 2a  truncate limit *
72e0: 2f 0a 20 20 20 20 66 6f 72 28 69 20 3d 20 70 47  /.    for(i = pG
72f0: 72 6f 75 70 2d 3e 6e 52 65 61 6c 2d 31 3b 20 69  roup->nReal-1; i
7300: 3e 69 42 61 73 65 47 72 6f 75 70 20 26 26 20 72  >iBaseGroup && r
7310: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2d  c==SQLITE_OK; i-
7320: 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 47  -){.      if( pG
7330: 72 6f 75 70 2d 3e 62 54 72 75 6e 63 61 74 65 20  roup->bTruncate 
7340: 29 7b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69  ){.        multi
7350: 70 6c 65 78 53 75 62 43 6c 6f 73 65 28 70 47 72  plexSubClose(pGr
7360: 6f 75 70 2c 20 69 2c 20 70 4f 72 69 67 56 66 73  oup, i, pOrigVfs
7370: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
7380: 20 20 20 20 20 20 20 20 70 53 75 62 4f 70 65 6e          pSubOpen
7390: 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f   = multiplexSubO
73a0: 70 65 6e 28 70 47 72 6f 75 70 2c 20 69 2c 20 26  pen(pGroup, i, &
73b0: 72 63 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 20  rc, 0, 0);.     
73c0: 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20     if( pSubOpen 
73d0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
73e0: 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74  = pSubOpen->pMet
73f0: 68 6f 64 73 2d 3e 78 54 72 75 6e 63 61 74 65 28  hods->xTruncate(
7400: 70 53 75 62 4f 70 65 6e 2c 20 30 29 3b 0a 20 20  pSubOpen, 0);.  
7410: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
7420: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
7430: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7440: 20 20 20 20 20 70 53 75 62 4f 70 65 6e 20 3d 20       pSubOpen = 
7450: 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e  multiplexSubOpen
7460: 28 70 47 72 6f 75 70 2c 20 69 42 61 73 65 47 72  (pGroup, iBaseGr
7470: 6f 75 70 2c 20 26 72 63 2c 20 30 2c 20 30 29 3b  oup, &rc, 0, 0);
7480: 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62 4f  .      if( pSubO
7490: 70 65 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 72  pen ){.        r
74a0: 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  c = pSubOpen->pM
74b0: 65 74 68 6f 64 73 2d 3e 78 54 72 75 6e 63 61 74  ethods->xTruncat
74c0: 65 28 70 53 75 62 4f 70 65 6e 2c 20 73 69 7a 65  e(pSubOpen, size
74d0: 20 25 20 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75   % pGroup->szChu
74e0: 6e 6b 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  nk);.      }.   
74f0: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 20 29 20   }.    if( rc ) 
7500: 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52  rc = SQLITE_IOER
7510: 52 5f 54 52 55 4e 43 41 54 45 3b 0a 20 20 7d 0a  R_TRUNCATE;.  }.
7520: 20 20 6d 75 6c 74 69 70 6c 65 78 4c 65 61 76 65    multiplexLeave
7530: 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ();.  return rc;
7540: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 79 6e  .}../* Pass xSyn
7550: 63 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75  c requests throu
7560: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
7570: 61 6c 20 56 46 53 20 77 69 74 68 6f 75 74 20 63  al VFS without c
7580: 68 61 6e 67 65 0a 2a 2f 0a 73 74 61 74 69 63 20  hange.*/.static 
7590: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53 79 6e  int multiplexSyn
75a0: 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  c(sqlite3_file *
75b0: 70 43 6f 6e 6e 2c 20 69 6e 74 20 66 6c 61 67 73  pConn, int flags
75c0: 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f  ){.  multiplexCo
75d0: 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c  nn *p = (multipl
75e0: 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  exConn*)pConn;. 
75f0: 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20   multiplexGroup 
7600: 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e 70 47 72  *pGroup = p->pGr
7610: 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  oup;.  int rc = 
7620: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
7630: 20 69 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 45   i;.  multiplexE
7640: 6e 74 65 72 28 29 3b 0a 20 20 66 6f 72 28 69 3d  nter();.  for(i=
7650: 30 3b 20 69 3c 70 47 72 6f 75 70 2d 3e 6e 52 65  0; i<pGroup->nRe
7660: 61 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71  al; i++){.    sq
7670: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
7680: 4f 70 65 6e 20 3d 20 70 47 72 6f 75 70 2d 3e 61  Open = pGroup->a
7690: 52 65 61 6c 5b 69 5d 2e 70 3b 0a 20 20 20 20 69  Real[i].p;.    i
76a0: 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20  f( pSubOpen ){. 
76b0: 20 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20 70       int rc2 = p
76c0: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
76d0: 73 2d 3e 78 53 79 6e 63 28 70 53 75 62 4f 70 65  s->xSync(pSubOpe
76e0: 6e 2c 20 66 6c 61 67 73 29 3b 0a 20 20 20 20 20  n, flags);.     
76f0: 20 69 66 28 20 72 63 32 21 3d 53 51 4c 49 54 45   if( rc2!=SQLITE
7700: 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
7710: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 6d 75 6c 74      }.  }.  mult
7720: 69 70 6c 65 78 4c 65 61 76 65 28 29 3b 0a 20 20  iplexLeave();.  
7730: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
7740: 20 50 61 73 73 20 78 46 69 6c 65 53 69 7a 65 20   Pass xFileSize 
7750: 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68  requests through
7760: 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c   to the original
7770: 20 56 46 53 2e 0a 2a 2a 20 41 67 67 72 65 67 61   VFS..** Aggrega
7780: 74 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20 61  te the size of a
7790: 6c 6c 20 74 68 65 20 63 68 75 6e 6b 73 20 62 65  ll the chunks be
77a0: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
77b0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75  */.static int mu
77c0: 6c 74 69 70 6c 65 78 46 69 6c 65 53 69 7a 65 28  ltiplexFileSize(
77d0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
77e0: 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  onn, sqlite3_int
77f0: 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20 6d 75  64 *pSize){.  mu
7800: 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d  ltiplexConn *p =
7810: 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a   (multiplexConn*
7820: 29 70 43 6f 6e 6e 3b 0a 20 20 6d 75 6c 74 69 70  )pConn;.  multip
7830: 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  lexGroup *pGroup
7840: 20 3d 20 70 2d 3e 70 47 72 6f 75 70 3b 0a 20 20   = p->pGroup;.  
7850: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7860: 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 6d  OK;.  int i;.  m
7870: 75 6c 74 69 70 6c 65 78 45 6e 74 65 72 28 29 3b  ultiplexEnter();
7880: 0a 20 20 69 66 28 20 21 70 47 72 6f 75 70 2d 3e  .  if( !pGroup->
7890: 62 45 6e 61 62 6c 65 64 20 29 7b 0a 20 20 20 20  bEnabled ){.    
78a0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53  sqlite3_file *pS
78b0: 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c  ubOpen = multipl
78c0: 65 78 53 75 62 4f 70 65 6e 28 70 47 72 6f 75 70  exSubOpen(pGroup
78d0: 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20  , 0, &rc, NULL, 
78e0: 30 29 3b 0a 20 20 20 20 69 66 28 20 70 53 75 62  0);.    if( pSub
78f0: 4f 70 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Open==0 ){.     
7900: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45   rc = SQLITE_IOE
7910: 52 52 5f 46 53 54 41 54 3b 0a 20 20 20 20 7d 65  RR_FSTAT;.    }e
7920: 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  lse{.      rc = 
7930: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
7940: 64 73 2d 3e 78 46 69 6c 65 53 69 7a 65 28 70 53  ds->xFileSize(pS
7950: 75 62 4f 70 65 6e 2c 20 70 53 69 7a 65 29 3b 0a  ubOpen, pSize);.
7960: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
7970: 20 20 20 2a 70 53 69 7a 65 20 3d 20 30 3b 0a 20     *pSize = 0;. 
7980: 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d     for(i=0; rc==
7990: 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b  SQLITE_OK; i++){
79a0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69  .      sqlite3_i
79b0: 6e 74 36 34 20 73 7a 20 3d 20 6d 75 6c 74 69 70  nt64 sz = multip
79c0: 6c 65 78 53 75 62 53 69 7a 65 28 70 47 72 6f 75  lexSubSize(pGrou
79d0: 70 2c 20 69 2c 20 26 72 63 29 3b 0a 20 20 20 20  p, i, &rc);.    
79e0: 20 20 69 66 28 20 73 7a 3d 3d 30 20 29 20 62 72    if( sz==0 ) br
79f0: 65 61 6b 3b 0a 20 20 20 20 20 20 2a 70 53 69 7a  eak;.      *pSiz
7a00: 65 20 3d 20 69 2a 28 73 71 6c 69 74 65 33 5f 69  e = i*(sqlite3_i
7a10: 6e 74 36 34 29 70 47 72 6f 75 70 2d 3e 73 7a 43  nt64)pGroup->szC
7a20: 68 75 6e 6b 20 2b 20 73 7a 3b 0a 20 20 20 20 7d  hunk + sz;.    }
7a30: 0a 20 20 7d 0a 20 20 6d 75 6c 74 69 70 6c 65 78  .  }.  multiplex
7a40: 4c 65 61 76 65 28 29 3b 0a 20 20 72 65 74 75 72  Leave();.  retur
7a50: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  n rc;.}../* Pass
7a60: 20 78 4c 6f 63 6b 20 72 65 71 75 65 73 74 73 20   xLock requests 
7a70: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f  through to the o
7a80: 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68  riginal VFS unch
7a90: 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  anged..*/.static
7aa0: 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 4c 6f   int multiplexLo
7ab0: 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ck(sqlite3_file 
7ac0: 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 6c 6f 63 6b  *pConn, int lock
7ad0: 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f  ){.  multiplexCo
7ae0: 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c  nn *p = (multipl
7af0: 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  exConn*)pConn;. 
7b00: 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74   int rc;.  sqlit
7b10: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
7b20: 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62  n = multiplexSub
7b30: 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75 70 2c 20  Open(p->pGroup, 
7b40: 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29  0, &rc, NULL, 0)
7b50: 3b 0a 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e  ;.  if( pSubOpen
7b60: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
7b70: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
7b80: 73 2d 3e 78 4c 6f 63 6b 28 70 53 75 62 4f 70 65  s->xLock(pSubOpe
7b90: 6e 2c 20 6c 6f 63 6b 29 3b 0a 20 20 7d 0a 20 20  n, lock);.  }.  
7ba0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 42 55  return SQLITE_BU
7bb0: 53 59 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78  SY;.}../* Pass x
7bc0: 55 6e 6c 6f 63 6b 20 72 65 71 75 65 73 74 73 20  Unlock requests 
7bd0: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f  through to the o
7be0: 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68  riginal VFS unch
7bf0: 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  anged..*/.static
7c00: 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 55 6e   int multiplexUn
7c10: 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c  lock(sqlite3_fil
7c20: 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 6c 6f  e *pConn, int lo
7c30: 63 6b 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78  ck){.  multiplex
7c40: 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69  Conn *p = (multi
7c50: 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b  plexConn*)pConn;
7c60: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c  .  int rc;.  sql
7c70: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
7c80: 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  pen = multiplexS
7c90: 75 62 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75 70  ubOpen(p->pGroup
7ca0: 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20  , 0, &rc, NULL, 
7cb0: 30 29 3b 0a 20 20 69 66 28 20 70 53 75 62 4f 70  0);.  if( pSubOp
7cc0: 65 6e 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  en ){.    return
7cd0: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
7ce0: 6f 64 73 2d 3e 78 55 6e 6c 6f 63 6b 28 70 53 75  ods->xUnlock(pSu
7cf0: 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29 3b 0a 20 20  bOpen, lock);.  
7d00: 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
7d10: 45 5f 49 4f 45 52 52 5f 55 4e 4c 4f 43 4b 3b 0a  E_IOERR_UNLOCK;.
7d20: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 43 68 65 63  }../* Pass xChec
7d30: 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 20 72 65  kReservedLock re
7d40: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
7d50: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
7d60: 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f  FS unchanged..*/
7d70: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
7d80: 69 70 6c 65 78 43 68 65 63 6b 52 65 73 65 72 76  iplexCheckReserv
7d90: 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66  edLock(sqlite3_f
7da0: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20  ile *pConn, int 
7db0: 2a 70 52 65 73 4f 75 74 29 7b 0a 20 20 6d 75 6c  *pResOut){.  mul
7dc0: 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20  tiplexConn *p = 
7dd0: 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29  (multiplexConn*)
7de0: 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63 3b  pConn;.  int rc;
7df0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
7e00: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74  *pSubOpen = mult
7e10: 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d 3e  iplexSubOpen(p->
7e20: 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20  pGroup, 0, &rc, 
7e30: 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20  NULL, 0);.  if( 
7e40: 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20  pSubOpen ){.    
7e50: 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d  return pSubOpen-
7e60: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 68 65 63  >pMethods->xChec
7e70: 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 70 53  kReservedLock(pS
7e80: 75 62 4f 70 65 6e 2c 20 70 52 65 73 4f 75 74 29  ubOpen, pResOut)
7e90: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
7ea0: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 43 48 45 43  QLITE_IOERR_CHEC
7eb0: 4b 52 45 53 45 52 56 45 44 4c 4f 43 4b 3b 0a 7d  KRESERVEDLOCK;.}
7ec0: 0a 0a 2f 2a 20 50 61 73 73 20 78 46 69 6c 65 43  ../* Pass xFileC
7ed0: 6f 6e 74 72 6f 6c 20 72 65 71 75 65 73 74 73 20  ontrol requests 
7ee0: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f  through to the o
7ef0: 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68  riginal VFS unch
7f00: 61 6e 67 65 64 2c 0a 2a 2a 20 65 78 63 65 70 74  anged,.** except
7f10: 20 66 6f 72 20 61 6e 79 20 4d 55 4c 54 49 50 4c   for any MULTIPL
7f20: 45 58 5f 43 54 52 4c 5f 2a 20 72 65 71 75 65 73  EX_CTRL_* reques
7f30: 74 73 20 68 65 72 65 2e 0a 2a 2f 0a 73 74 61 74  ts here..*/.stat
7f40: 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78  ic int multiplex
7f50: 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c 69  FileControl(sqli
7f60: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
7f70: 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70   int op, void *p
7f80: 41 72 67 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65  Arg){.  multiple
7f90: 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74  xConn *p = (mult
7fa0: 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e  iplexConn*)pConn
7fb0: 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f  ;.  multiplexGro
7fc0: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e  up *pGroup = p->
7fd0: 70 47 72 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63  pGroup;.  int rc
7fe0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
7ff0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
8000: 2a 70 53 75 62 4f 70 65 6e 3b 0a 0a 20 20 69 66  *pSubOpen;..  if
8010: 28 20 21 67 4d 75 6c 74 69 70 6c 65 78 2e 69 73  ( !gMultiplex.is
8020: 49 6e 69 74 69 61 6c 69 7a 65 64 20 29 20 72 65  Initialized ) re
8030: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55  turn SQLITE_MISU
8040: 53 45 3b 0a 20 20 73 77 69 74 63 68 28 20 6f 70  SE;.  switch( op
8050: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 4d 55 4c   ){.    case MUL
8060: 54 49 50 4c 45 58 5f 43 54 52 4c 5f 45 4e 41 42  TIPLEX_CTRL_ENAB
8070: 4c 45 3a 0a 20 20 20 20 20 20 69 66 28 20 70 41  LE:.      if( pA
8080: 72 67 20 29 20 7b 0a 20 20 20 20 20 20 20 20 69  rg ) {.        i
8090: 6e 74 20 62 45 6e 61 62 6c 65 64 20 3d 20 2a 28  nt bEnabled = *(
80a0: 69 6e 74 20 2a 29 70 41 72 67 3b 0a 20 20 20 20  int *)pArg;.    
80b0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 62 45 6e 61      pGroup->bEna
80c0: 62 6c 65 64 20 3d 20 62 45 6e 61 62 6c 65 64 3b  bled = bEnabled;
80d0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
80e0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d  LITE_OK;.      }
80f0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
8100: 20 20 63 61 73 65 20 4d 55 4c 54 49 50 4c 45 58    case MULTIPLEX
8110: 5f 43 54 52 4c 5f 53 45 54 5f 43 48 55 4e 4b 5f  _CTRL_SET_CHUNK_
8120: 53 49 5a 45 3a 0a 20 20 20 20 20 20 69 66 28 20  SIZE:.      if( 
8130: 70 41 72 67 20 29 20 7b 0a 20 20 20 20 20 20 20  pArg ) {.       
8140: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73 7a   unsigned int sz
8150: 43 68 75 6e 6b 20 3d 20 2a 28 75 6e 73 69 67 6e  Chunk = *(unsign
8160: 65 64 2a 29 70 41 72 67 3b 0a 20 20 20 20 20 20  ed*)pArg;.      
8170: 20 20 69 66 28 20 73 7a 43 68 75 6e 6b 3c 31 20    if( szChunk<1 
8180: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
8190: 3d 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b  = SQLITE_MISUSE;
81a0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  .        }else{.
81b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 6f 75            /* Rou
81c0: 6e 64 20 75 70 20 74 6f 20 6e 65 61 72 65 73 74  nd up to nearest
81d0: 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 4d 41 58   multiple of MAX
81e0: 5f 50 41 47 45 5f 53 49 5a 45 2e 20 2a 2f 0a 20  _PAGE_SIZE. */. 
81f0: 20 20 20 20 20 20 20 20 20 73 7a 43 68 75 6e 6b           szChunk
8200: 20 3d 20 28 73 7a 43 68 75 6e 6b 20 2b 20 28 4d   = (szChunk + (M
8210: 41 58 5f 50 41 47 45 5f 53 49 5a 45 2d 31 29 29  AX_PAGE_SIZE-1))
8220: 3b 0a 20 20 20 20 20 20 20 20 20 20 73 7a 43 68  ;.          szCh
8230: 75 6e 6b 20 26 3d 20 7e 28 4d 41 58 5f 50 41 47  unk &= ~(MAX_PAG
8240: 45 5f 53 49 5a 45 2d 31 29 3b 0a 20 20 20 20 20  E_SIZE-1);.     
8250: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 73 7a 43       pGroup->szC
8260: 68 75 6e 6b 20 3d 20 73 7a 43 68 75 6e 6b 3b 0a  hunk = szChunk;.
8270: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53            rc = S
8280: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20  QLITE_OK;.      
8290: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
82a0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
82b0: 65 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54 52 4c  e MULTIPLEX_CTRL
82c0: 5f 53 45 54 5f 4d 41 58 5f 43 48 55 4e 4b 53 3a  _SET_MAX_CHUNKS:
82d0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
82e0: 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 62 72 65  TE_OK;.      bre
82f0: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 53 51 4c  ak;.    case SQL
8300: 49 54 45 5f 46 43 4e 54 4c 5f 53 49 5a 45 5f 48  ITE_FCNTL_SIZE_H
8310: 49 4e 54 3a 0a 20 20 20 20 63 61 73 65 20 53 51  INT:.    case SQ
8320: 4c 49 54 45 5f 46 43 4e 54 4c 5f 43 48 55 4e 4b  LITE_FCNTL_CHUNK
8330: 5f 53 49 5a 45 3a 0a 20 20 20 20 20 20 2f 2a 20  _SIZE:.      /* 
8340: 6e 6f 2d 6f 70 20 74 68 65 73 65 20 2a 2f 0a 20  no-op these */. 
8350: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
8360: 5f 4f 4b 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  _OK;.      break
8370: 3b 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20  ;.    default:. 
8380: 20 20 20 20 20 70 53 75 62 4f 70 65 6e 20 3d 20       pSubOpen = 
8390: 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e  multiplexSubOpen
83a0: 28 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c  (pGroup, 0, &rc,
83b0: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 20 20 20   NULL, 0);.     
83c0: 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b   if( pSubOpen ){
83d0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 53  .        rc = pS
83e0: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
83f0: 2d 3e 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 70  ->xFileControl(p
8400: 53 75 62 4f 70 65 6e 2c 20 6f 70 2c 20 70 41 72  SubOpen, op, pAr
8410: 67 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  g);.        if( 
8420: 6f 70 3d 3d 53 51 4c 49 54 45 5f 46 43 4e 54 4c  op==SQLITE_FCNTL
8430: 5f 56 46 53 4e 41 4d 45 20 26 26 20 72 63 3d 3d  _VFSNAME && rc==
8440: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
8450: 20 20 20 20 20 20 2a 28 63 68 61 72 2a 2a 29 70        *(char**)p
8460: 41 72 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Arg = sqlite3_mp
8470: 72 69 6e 74 66 28 22 6d 75 6c 74 69 70 6c 65 78  rintf("multiplex
8480: 2f 25 7a 22 2c 20 2a 28 63 68 61 72 2a 2a 29 70  /%z", *(char**)p
8490: 41 72 67 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  Arg);.        }.
84a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
84b0: 65 61 6b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  eak;.  }.  retur
84c0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  n rc;.}../* Pass
84d0: 20 78 53 65 63 74 6f 72 53 69 7a 65 20 72 65 71   xSectorSize req
84e0: 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f  uests through to
84f0: 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46   the original VF
8500: 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a  S unchanged..*/.
8510: 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69  static int multi
8520: 70 6c 65 78 53 65 63 74 6f 72 53 69 7a 65 28 73  plexSectorSize(s
8530: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
8540: 6e 6e 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78  nn){.  multiplex
8550: 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69  Conn *p = (multi
8560: 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b  plexConn*)pConn;
8570: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c  .  int rc;.  sql
8580: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
8590: 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  pen = multiplexS
85a0: 75 62 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75 70  ubOpen(p->pGroup
85b0: 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20  , 0, &rc, NULL, 
85c0: 30 29 3b 0a 20 20 69 66 28 20 70 53 75 62 4f 70  0);.  if( pSubOp
85d0: 65 6e 20 26 26 20 70 53 75 62 4f 70 65 6e 2d 3e  en && pSubOpen->
85e0: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 65 63 74 6f  pMethods->xSecto
85f0: 72 53 69 7a 65 20 29 7b 0a 20 20 20 20 72 65 74  rSize ){.    ret
8600: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
8610: 65 74 68 6f 64 73 2d 3e 78 53 65 63 74 6f 72 53  ethods->xSectorS
8620: 69 7a 65 28 70 53 75 62 4f 70 65 6e 29 3b 0a 20  ize(pSubOpen);. 
8630: 20 7d 0a 20 20 72 65 74 75 72 6e 20 44 45 46 41   }.  return DEFA
8640: 55 4c 54 5f 53 45 43 54 4f 52 5f 53 49 5a 45 3b  ULT_SECTOR_SIZE;
8650: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 44 65 76  .}../* Pass xDev
8660: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
8670: 63 73 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  cs requests thro
8680: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
8690: 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65  nal VFS unchange
86a0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
86b0: 20 6d 75 6c 74 69 70 6c 65 78 44 65 76 69 63 65   multiplexDevice
86c0: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28  Characteristics(
86d0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
86e0: 6f 6e 6e 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65  onn){.  multiple
86f0: 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74  xConn *p = (mult
8700: 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e  iplexConn*)pConn
8710: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71  ;.  int rc;.  sq
8720: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
8730: 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78  Open = multiplex
8740: 53 75 62 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75  SubOpen(p->pGrou
8750: 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c  p, 0, &rc, NULL,
8760: 20 30 29 3b 0a 20 20 69 66 28 20 70 53 75 62 4f   0);.  if( pSubO
8770: 70 65 6e 20 29 7b 0a 20 20 20 20 72 65 74 75 72  pen ){.    retur
8780: 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74  n pSubOpen->pMet
8790: 68 6f 64 73 2d 3e 78 44 65 76 69 63 65 43 68 61  hods->xDeviceCha
87a0: 72 61 63 74 65 72 69 73 74 69 63 73 28 70 53 75  racteristics(pSu
87b0: 62 4f 70 65 6e 29 3b 0a 20 20 7d 0a 20 20 72 65  bOpen);.  }.  re
87c0: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 50 61  turn 0;.}../* Pa
87d0: 73 73 20 78 53 68 6d 4d 61 70 20 72 65 71 75 65  ss xShmMap reque
87e0: 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  sts through to t
87f0: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
8800: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74  unchanged..*/.st
8810: 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c  atic int multipl
8820: 65 78 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69  exShmMap(.  sqli
8830: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
8840: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
8850: 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61  andle open on da
8860: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
8870: 20 69 6e 74 20 69 52 65 67 69 6f 6e 2c 20 20 20   int iRegion,   
8880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8890: 20 2f 2a 20 52 65 67 69 6f 6e 20 74 6f 20 72 65   /* Region to re
88a0: 74 72 69 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20  trieve */.  int 
88b0: 73 7a 52 65 67 69 6f 6e 2c 20 20 20 20 20 20 20  szRegion,       
88c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
88d0: 69 7a 65 20 6f 66 20 72 65 67 69 6f 6e 73 20 2a  ize of regions *
88e0: 2f 0a 20 20 69 6e 74 20 62 45 78 74 65 6e 64 2c  /.  int bExtend,
88f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8900: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 65      /* True to e
8910: 78 74 65 6e 64 20 66 69 6c 65 20 69 66 20 6e 65  xtend file if ne
8920: 63 65 73 73 61 72 79 20 2a 2f 0a 20 20 76 6f 69  cessary */.  voi
8930: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 70 70 20  d volatile **pp 
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8950: 4f 55 54 3a 20 4d 61 70 70 65 64 20 6d 65 6d 6f  OUT: Mapped memo
8960: 72 79 20 2a 2f 0a 29 7b 0a 20 20 6d 75 6c 74 69  ry */.){.  multi
8970: 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d  plexConn *p = (m
8980: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43  ultiplexConn*)pC
8990: 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  onn;.  int rc;. 
89a0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
89b0: 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70  SubOpen = multip
89c0: 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d 3e 70 47  lexSubOpen(p->pG
89d0: 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55  roup, 0, &rc, NU
89e0: 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 53  LL, 0);.  if( pS
89f0: 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20 72 65  ubOpen ){.    re
8a00: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
8a10: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61 70  Methods->xShmMap
8a20: 28 70 53 75 62 4f 70 65 6e 2c 20 69 52 65 67 69  (pSubOpen, iRegi
8a30: 6f 6e 2c 20 73 7a 52 65 67 69 6f 6e 2c 20 62 45  on, szRegion, bE
8a40: 78 74 65 6e 64 2c 70 70 29 3b 0a 20 20 7d 0a 20  xtend,pp);.  }. 
8a50: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49   return SQLITE_I
8a60: 4f 45 52 52 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  OERR;.}../* Pass
8a70: 20 78 53 68 6d 4c 6f 63 6b 20 72 65 71 75 65 73   xShmLock reques
8a80: 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68  ts through to th
8a90: 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75  e original VFS u
8aa0: 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61  nchanged..*/.sta
8ab0: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
8ac0: 78 53 68 6d 4c 6f 63 6b 28 0a 20 20 73 71 6c 69  xShmLock(.  sqli
8ad0: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
8ae0: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
8af0: 73 65 20 66 69 6c 65 20 68 6f 6c 64 69 6e 67 20  se file holding 
8b00: 74 68 65 20 73 68 61 72 65 64 20 6d 65 6d 6f 72  the shared memor
8b10: 79 20 2a 2f 0a 20 20 69 6e 74 20 6f 66 73 74 2c  y */.  int ofst,
8b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b30: 20 20 2f 2a 20 46 69 72 73 74 20 6c 6f 63 6b 20    /* First lock 
8b40: 74 6f 20 61 63 71 75 69 72 65 20 6f 72 20 72 65  to acquire or re
8b50: 6c 65 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  lease */.  int n
8b60: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8b70: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
8b80: 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 61 63 71 75  of locks to acqu
8b90: 69 72 65 20 6f 72 20 72 65 6c 65 61 73 65 20 2a  ire or release *
8ba0: 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 20 20 20  /.  int flags   
8bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8bc0: 2a 20 57 68 61 74 20 74 6f 20 64 6f 20 77 69 74  * What to do wit
8bd0: 68 20 74 68 65 20 6c 6f 63 6b 20 2a 2f 0a 29 7b  h the lock */.){
8be0: 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e  .  multiplexConn
8bf0: 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78   *p = (multiplex
8c00: 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69  Conn*)pConn;.  i
8c10: 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33  nt rc;.  sqlite3
8c20: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
8c30: 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70  = multiplexSubOp
8c40: 65 6e 28 70 2d 3e 70 47 72 6f 75 70 2c 20 30 2c  en(p->pGroup, 0,
8c50: 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a   &rc, NULL, 0);.
8c60: 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20 29    if( pSubOpen )
8c70: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 53 75  {.    return pSu
8c80: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
8c90: 3e 78 53 68 6d 4c 6f 63 6b 28 70 53 75 62 4f 70  >xShmLock(pSubOp
8ca0: 65 6e 2c 20 6f 66 73 74 2c 20 6e 2c 20 66 6c 61  en, ofst, n, fla
8cb0: 67 73 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  gs);.  }.  retur
8cc0: 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 7d  n SQLITE_BUSY;.}
8cd0: 0a 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 42 61  ../* Pass xShmBa
8ce0: 72 72 69 65 72 20 72 65 71 75 65 73 74 73 20 74  rrier requests t
8cf0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
8d00: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
8d10: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
8d20: 76 6f 69 64 20 6d 75 6c 74 69 70 6c 65 78 53 68  void multiplexSh
8d30: 6d 42 61 72 72 69 65 72 28 73 71 6c 69 74 65 33  mBarrier(sqlite3
8d40: 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20  _file *pConn){. 
8d50: 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a   multiplexConn *
8d60: 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f  p = (multiplexCo
8d70: 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74  nn*)pConn;.  int
8d80: 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66   rc;.  sqlite3_f
8d90: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
8da0: 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e  multiplexSubOpen
8db0: 28 70 2d 3e 70 47 72 6f 75 70 2c 20 30 2c 20 26  (p->pGroup, 0, &
8dc0: 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20  rc, NULL, 0);.  
8dd0: 69 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a  if( pSubOpen ){.
8de0: 20 20 20 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d      pSubOpen->pM
8df0: 65 74 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72  ethods->xShmBarr
8e00: 69 65 72 28 70 53 75 62 4f 70 65 6e 29 3b 0a 20  ier(pSubOpen);. 
8e10: 20 7d 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53   }.}../* Pass xS
8e20: 68 6d 55 6e 6d 61 70 20 72 65 71 75 65 73 74 73  hmUnmap requests
8e30: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20   through to the 
8e40: 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63  original VFS unc
8e50: 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  hanged..*/.stati
8e60: 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53  c int multiplexS
8e70: 68 6d 55 6e 6d 61 70 28 73 71 6c 69 74 65 33 5f  hmUnmap(sqlite3_
8e80: 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74  file *pConn, int
8e90: 20 64 65 6c 65 74 65 46 6c 61 67 29 7b 0a 20 20   deleteFlag){.  
8ea0: 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70  multiplexConn *p
8eb0: 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e   = (multiplexCon
8ec0: 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20  n*)pConn;.  int 
8ed0: 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  rc;.  sqlite3_fi
8ee0: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d  le *pSubOpen = m
8ef0: 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28  ultiplexSubOpen(
8f00: 70 2d 3e 70 47 72 6f 75 70 2c 20 30 2c 20 26 72  p->pGroup, 0, &r
8f10: 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 69  c, NULL, 0);.  i
8f20: 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20  f( pSubOpen ){. 
8f30: 20 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70     return pSubOp
8f40: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53  en->pMethods->xS
8f50: 68 6d 55 6e 6d 61 70 28 70 53 75 62 4f 70 65 6e  hmUnmap(pSubOpen
8f60: 2c 20 64 65 6c 65 74 65 46 6c 61 67 29 3b 0a 20  , deleteFlag);. 
8f70: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
8f80: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  TE_OK;.}../*****
8f90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8fa0: 2a 2a 2a 2a 2a 20 50 75 62 6c 69 63 20 49 6e 74  ***** Public Int
8fb0: 65 72 66 61 63 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a  erfaces ********
8fc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8fd0: 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 43 41 50  *****/./*.** CAP
8fe0: 49 3a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68  I: Initialize th
8ff0: 65 20 6d 75 6c 74 69 70 6c 65 78 20 56 46 53 20  e multiplex VFS 
9000: 73 68 69 6d 20 2d 20 73 71 6c 69 74 65 33 5f 6d  shim - sqlite3_m
9010: 75 6c 74 69 70 6c 65 78 5f 69 6e 69 74 69 61 6c  ultiplex_initial
9020: 69 7a 65 28 29 0a 2a 2a 0a 2a 2a 20 55 73 65 20  ize().**.** Use 
9030: 74 68 65 20 56 46 53 20 6e 61 6d 65 64 20 7a 4f  the VFS named zO
9040: 72 69 67 56 66 73 4e 61 6d 65 20 61 73 20 74 68  rigVfsName as th
9050: 65 20 56 46 53 20 74 68 61 74 20 64 6f 65 73 20  e VFS that does 
9060: 74 68 65 20 61 63 74 75 61 6c 20 77 6f 72 6b 2e  the actual work.
9070: 20 20 0a 2a 2a 20 55 73 65 20 74 68 65 20 64 65    .** Use the de
9080: 66 61 75 6c 74 20 69 66 20 7a 4f 72 69 67 56 66  fault if zOrigVf
9090: 73 4e 61 6d 65 3d 3d 4e 55 4c 4c 2e 20 20 0a 2a  sName==NULL.  .*
90a0: 2a 0a 2a 2a 20 54 68 65 20 6d 75 6c 74 69 70 6c  *.** The multipl
90b0: 65 78 20 56 46 53 20 73 68 69 6d 20 69 73 20 6e  ex VFS shim is n
90c0: 61 6d 65 64 20 22 6d 75 6c 74 69 70 6c 65 78 22  amed "multiplex"
90d0: 2e 20 20 49 74 20 77 69 6c 6c 20 62 65 63 6f 6d  .  It will becom
90e0: 65 20 74 68 65 20 64 65 66 61 75 6c 74 0a 2a 2a  e the default.**
90f0: 20 56 46 53 20 69 66 20 6d 61 6b 65 44 65 66 61   VFS if makeDefa
9100: 75 6c 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e  ult is non-zero.
9110: 0a 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54  .**.** THIS ROUT
9120: 49 4e 45 20 49 53 20 4e 4f 54 20 54 48 52 45 41  INE IS NOT THREA
9130: 44 53 41 46 45 2e 20 20 43 61 6c 6c 20 74 68 69  DSAFE.  Call thi
9140: 73 20 72 6f 75 74 69 6e 65 20 65 78 61 63 74 6c  s routine exactl
9150: 79 20 6f 6e 63 65 0a 2a 2a 20 64 75 72 69 6e 67  y once.** during
9160: 20 73 74 61 72 74 2d 75 70 2e 0a 2a 2f 0a 69 6e   start-up..*/.in
9170: 74 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70  t sqlite3_multip
9180: 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65 28 63  lex_initialize(c
9190: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f 72 69 67  onst char *zOrig
91a0: 56 66 73 4e 61 6d 65 2c 20 69 6e 74 20 6d 61 6b  VfsName, int mak
91b0: 65 44 65 66 61 75 6c 74 29 7b 0a 20 20 73 71 6c  eDefault){.  sql
91c0: 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56  ite3_vfs *pOrigV
91d0: 66 73 3b 0a 20 20 69 66 28 20 67 4d 75 6c 74 69  fs;.  if( gMulti
91e0: 70 6c 65 78 2e 69 73 49 6e 69 74 69 61 6c 69 7a  plex.isInitializ
91f0: 65 64 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  ed ) return SQLI
9200: 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 70 4f 72  TE_MISUSE;.  pOr
9210: 69 67 56 66 73 20 3d 20 73 71 6c 69 74 65 33 5f  igVfs = sqlite3_
9220: 76 66 73 5f 66 69 6e 64 28 7a 4f 72 69 67 56 66  vfs_find(zOrigVf
9230: 73 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 70 4f  sName);.  if( pO
9240: 72 69 67 56 66 73 3d 3d 30 20 29 20 72 65 74 75  rigVfs==0 ) retu
9250: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
9260: 0a 20 20 61 73 73 65 72 74 28 20 70 4f 72 69 67  .  assert( pOrig
9270: 56 66 73 21 3d 26 67 4d 75 6c 74 69 70 6c 65 78  Vfs!=&gMultiplex
9280: 2e 73 54 68 69 73 56 66 73 20 29 3b 0a 20 20 67  .sThisVfs );.  g
9290: 4d 75 6c 74 69 70 6c 65 78 2e 70 4d 75 74 65 78  Multiplex.pMutex
92a0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78   = sqlite3_mutex
92b0: 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55  _alloc(SQLITE_MU
92c0: 54 45 58 5f 46 41 53 54 29 3b 0a 20 20 69 66 28  TEX_FAST);.  if(
92d0: 20 21 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4d 75   !gMultiplex.pMu
92e0: 74 65 78 20 29 7b 0a 20 20 20 20 72 65 74 75 72  tex ){.    retur
92f0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
9300: 20 20 7d 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78    }.  gMultiplex
9310: 2e 70 47 72 6f 75 70 73 20 3d 20 4e 55 4c 4c 3b  .pGroups = NULL;
9320: 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 69 73  .  gMultiplex.is
9330: 49 6e 69 74 69 61 6c 69 7a 65 64 20 3d 20 31 3b  Initialized = 1;
9340: 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f  .  gMultiplex.pO
9350: 72 69 67 56 66 73 20 3d 20 70 4f 72 69 67 56 66  rigVfs = pOrigVf
9360: 73 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  s;.  gMultiplex.
9370: 73 54 68 69 73 56 66 73 20 3d 20 2a 70 4f 72 69  sThisVfs = *pOri
9380: 67 56 66 73 3b 0a 20 20 67 4d 75 6c 74 69 70 6c  gVfs;.  gMultipl
9390: 65 78 2e 73 54 68 69 73 56 66 73 2e 73 7a 4f 73  ex.sThisVfs.szOs
93a0: 46 69 6c 65 20 2b 3d 20 73 69 7a 65 6f 66 28 6d  File += sizeof(m
93b0: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 29 3b 0a 20  ultiplexConn);. 
93c0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69   gMultiplex.sThi
93d0: 73 56 66 73 2e 7a 4e 61 6d 65 20 3d 20 53 51 4c  sVfs.zName = SQL
93e0: 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f 56 46  ITE_MULTIPLEX_VF
93f0: 53 5f 4e 41 4d 45 3b 0a 20 20 67 4d 75 6c 74 69  S_NAME;.  gMulti
9400: 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e 78 4f  plex.sThisVfs.xO
9410: 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 4f  pen = multiplexO
9420: 70 65 6e 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65  pen;.  gMultiple
9430: 78 2e 73 54 68 69 73 56 66 73 2e 78 44 65 6c 65  x.sThisVfs.xDele
9440: 74 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78 44 65  te = multiplexDe
9450: 6c 65 74 65 3b 0a 20 20 67 4d 75 6c 74 69 70 6c  lete;.  gMultipl
9460: 65 78 2e 73 54 68 69 73 56 66 73 2e 78 41 63 63  ex.sThisVfs.xAcc
9470: 65 73 73 20 3d 20 6d 75 6c 74 69 70 6c 65 78 41  ess = multiplexA
9480: 63 63 65 73 73 3b 0a 20 20 67 4d 75 6c 74 69 70  ccess;.  gMultip
9490: 6c 65 78 2e 73 54 68 69 73 56 66 73 2e 78 46 75  lex.sThisVfs.xFu
94a0: 6c 6c 50 61 74 68 6e 61 6d 65 20 3d 20 6d 75 6c  llPathname = mul
94b0: 74 69 70 6c 65 78 46 75 6c 6c 50 61 74 68 6e 61  tiplexFullPathna
94c0: 6d 65 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78  me;.  gMultiplex
94d0: 2e 73 54 68 69 73 56 66 73 2e 78 44 6c 4f 70 65  .sThisVfs.xDlOpe
94e0: 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 44 6c 4f  n = multiplexDlO
94f0: 70 65 6e 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65  pen;.  gMultiple
9500: 78 2e 73 54 68 69 73 56 66 73 2e 78 44 6c 45 72  x.sThisVfs.xDlEr
9510: 72 6f 72 20 3d 20 6d 75 6c 74 69 70 6c 65 78 44  ror = multiplexD
9520: 6c 45 72 72 6f 72 3b 0a 20 20 67 4d 75 6c 74 69  lError;.  gMulti
9530: 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e 78 44  plex.sThisVfs.xD
9540: 6c 53 79 6d 20 3d 20 6d 75 6c 74 69 70 6c 65 78  lSym = multiplex
9550: 44 6c 53 79 6d 3b 0a 20 20 67 4d 75 6c 74 69 70  DlSym;.  gMultip
9560: 6c 65 78 2e 73 54 68 69 73 56 66 73 2e 78 44 6c  lex.sThisVfs.xDl
9570: 43 6c 6f 73 65 20 3d 20 6d 75 6c 74 69 70 6c 65  Close = multiple
9580: 78 44 6c 43 6c 6f 73 65 3b 0a 20 20 67 4d 75 6c  xDlClose;.  gMul
9590: 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e  tiplex.sThisVfs.
95a0: 78 52 61 6e 64 6f 6d 6e 65 73 73 20 3d 20 6d 75  xRandomness = mu
95b0: 6c 74 69 70 6c 65 78 52 61 6e 64 6f 6d 6e 65 73  ltiplexRandomnes
95c0: 73 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  s;.  gMultiplex.
95d0: 73 54 68 69 73 56 66 73 2e 78 53 6c 65 65 70 20  sThisVfs.xSleep 
95e0: 3d 20 6d 75 6c 74 69 70 6c 65 78 53 6c 65 65 70  = multiplexSleep
95f0: 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73  ;.  gMultiplex.s
9600: 54 68 69 73 56 66 73 2e 78 43 75 72 72 65 6e 74  ThisVfs.xCurrent
9610: 54 69 6d 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78  Time = multiplex
9620: 43 75 72 72 65 6e 74 54 69 6d 65 3b 0a 20 20 67  CurrentTime;.  g
9630: 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56  Multiplex.sThisV
9640: 66 73 2e 78 47 65 74 4c 61 73 74 45 72 72 6f 72  fs.xGetLastError
9650: 20 3d 20 6d 75 6c 74 69 70 6c 65 78 47 65 74 4c   = multiplexGetL
9660: 61 73 74 45 72 72 6f 72 3b 0a 20 20 67 4d 75 6c  astError;.  gMul
9670: 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e  tiplex.sThisVfs.
9680: 78 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36  xCurrentTimeInt6
9690: 34 20 3d 20 6d 75 6c 74 69 70 6c 65 78 43 75 72  4 = multiplexCur
96a0: 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 3b 0a 0a  rentTimeInt64;..
96b0: 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f    gMultiplex.sIo
96c0: 4d 65 74 68 6f 64 73 56 31 2e 69 56 65 72 73 69  MethodsV1.iVersi
96d0: 6f 6e 20 3d 20 31 3b 0a 20 20 67 4d 75 6c 74 69  on = 1;.  gMulti
96e0: 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56  plex.sIoMethodsV
96f0: 31 2e 78 43 6c 6f 73 65 20 3d 20 6d 75 6c 74 69  1.xClose = multi
9700: 70 6c 65 78 43 6c 6f 73 65 3b 0a 20 20 67 4d 75  plexClose;.  gMu
9710: 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f  ltiplex.sIoMetho
9720: 64 73 56 31 2e 78 52 65 61 64 20 3d 20 6d 75 6c  dsV1.xRead = mul
9730: 74 69 70 6c 65 78 52 65 61 64 3b 0a 20 20 67 4d  tiplexRead;.  gM
9740: 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68  ultiplex.sIoMeth
9750: 6f 64 73 56 31 2e 78 57 72 69 74 65 20 3d 20 6d  odsV1.xWrite = m
9760: 75 6c 74 69 70 6c 65 78 57 72 69 74 65 3b 0a 20  ultiplexWrite;. 
9770: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9780: 65 74 68 6f 64 73 56 31 2e 78 54 72 75 6e 63 61  ethodsV1.xTrunca
9790: 74 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78 54 72  te = multiplexTr
97a0: 75 6e 63 61 74 65 3b 0a 20 20 67 4d 75 6c 74 69  uncate;.  gMulti
97b0: 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56  plex.sIoMethodsV
97c0: 31 2e 78 53 79 6e 63 20 3d 20 6d 75 6c 74 69 70  1.xSync = multip
97d0: 6c 65 78 53 79 6e 63 3b 0a 20 20 67 4d 75 6c 74  lexSync;.  gMult
97e0: 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73  iplex.sIoMethods
97f0: 56 31 2e 78 46 69 6c 65 53 69 7a 65 20 3d 20 6d  V1.xFileSize = m
9800: 75 6c 74 69 70 6c 65 78 46 69 6c 65 53 69 7a 65  ultiplexFileSize
9810: 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73  ;.  gMultiplex.s
9820: 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 4c 6f 63  IoMethodsV1.xLoc
9830: 6b 20 3d 20 6d 75 6c 74 69 70 6c 65 78 4c 6f 63  k = multiplexLoc
9840: 6b 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  k;.  gMultiplex.
9850: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 55 6e  sIoMethodsV1.xUn
9860: 6c 6f 63 6b 20 3d 20 6d 75 6c 74 69 70 6c 65 78  lock = multiplex
9870: 55 6e 6c 6f 63 6b 3b 0a 20 20 67 4d 75 6c 74 69  Unlock;.  gMulti
9880: 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56  plex.sIoMethodsV
9890: 31 2e 78 43 68 65 63 6b 52 65 73 65 72 76 65 64  1.xCheckReserved
98a0: 4c 6f 63 6b 20 3d 20 6d 75 6c 74 69 70 6c 65 78  Lock = multiplex
98b0: 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63  CheckReservedLoc
98c0: 6b 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  k;.  gMultiplex.
98d0: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 46 69  sIoMethodsV1.xFi
98e0: 6c 65 43 6f 6e 74 72 6f 6c 20 3d 20 6d 75 6c 74  leControl = mult
98f0: 69 70 6c 65 78 46 69 6c 65 43 6f 6e 74 72 6f 6c  iplexFileControl
9900: 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73  ;.  gMultiplex.s
9910: 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 53 65 63  IoMethodsV1.xSec
9920: 74 6f 72 53 69 7a 65 20 3d 20 6d 75 6c 74 69 70  torSize = multip
9930: 6c 65 78 53 65 63 74 6f 72 53 69 7a 65 3b 0a 20  lexSectorSize;. 
9940: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9950: 65 74 68 6f 64 73 56 31 2e 78 44 65 76 69 63 65  ethodsV1.xDevice
9960: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 20  Characteristics 
9970: 3d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  =.              
9980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 75                mu
99a0: 6c 74 69 70 6c 65 78 44 65 76 69 63 65 43 68 61  ltiplexDeviceCha
99b0: 72 61 63 74 65 72 69 73 74 69 63 73 3b 0a 20 20  racteristics;.  
99c0: 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65  gMultiplex.sIoMe
99d0: 74 68 6f 64 73 56 32 20 3d 20 67 4d 75 6c 74 69  thodsV2 = gMulti
99e0: 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56  plex.sIoMethodsV
99f0: 31 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  1;.  gMultiplex.
9a00: 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 69 56 65  sIoMethodsV2.iVe
9a10: 72 73 69 6f 6e 20 3d 20 32 3b 0a 20 20 67 4d 75  rsion = 2;.  gMu
9a20: 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f  ltiplex.sIoMetho
9a30: 64 73 56 32 2e 78 53 68 6d 4d 61 70 20 3d 20 6d  dsV2.xShmMap = m
9a40: 75 6c 74 69 70 6c 65 78 53 68 6d 4d 61 70 3b 0a  ultiplexShmMap;.
9a50: 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f    gMultiplex.sIo
9a60: 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 4c 6f  MethodsV2.xShmLo
9a70: 63 6b 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 68  ck = multiplexSh
9a80: 6d 4c 6f 63 6b 3b 0a 20 20 67 4d 75 6c 74 69 70  mLock;.  gMultip
9a90: 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32  lex.sIoMethodsV2
9aa0: 2e 78 53 68 6d 42 61 72 72 69 65 72 20 3d 20 6d  .xShmBarrier = m
9ab0: 75 6c 74 69 70 6c 65 78 53 68 6d 42 61 72 72 69  ultiplexShmBarri
9ac0: 65 72 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78  er;.  gMultiplex
9ad0: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53  .sIoMethodsV2.xS
9ae0: 68 6d 55 6e 6d 61 70 20 3d 20 6d 75 6c 74 69 70  hmUnmap = multip
9af0: 6c 65 78 53 68 6d 55 6e 6d 61 70 3b 0a 20 20 73  lexShmUnmap;.  s
9b00: 71 6c 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73  qlite3_vfs_regis
9b10: 74 65 72 28 26 67 4d 75 6c 74 69 70 6c 65 78 2e  ter(&gMultiplex.
9b20: 73 54 68 69 73 56 66 73 2c 20 6d 61 6b 65 44 65  sThisVfs, makeDe
9b30: 66 61 75 6c 74 29 3b 0a 0a 20 20 73 71 6c 69 74  fault);..  sqlit
9b40: 65 33 5f 61 75 74 6f 5f 65 78 74 65 6e 73 69 6f  e3_auto_extensio
9b50: 6e 28 28 76 6f 69 64 2a 29 6d 75 6c 74 69 70 6c  n((void*)multipl
9b60: 65 78 46 75 6e 63 49 6e 69 74 29 3b 0a 0a 20 20  exFuncInit);..  
9b70: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
9b80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 41 50 49 3a  ;.}../*.** CAPI:
9b90: 20 53 68 75 74 64 6f 77 6e 20 74 68 65 20 6d 75   Shutdown the mu
9ba0: 6c 74 69 70 6c 65 78 20 73 79 73 74 65 6d 20 2d  ltiplex system -
9bb0: 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c   sqlite3_multipl
9bc0: 65 78 5f 73 68 75 74 64 6f 77 6e 28 29 0a 2a 2a  ex_shutdown().**
9bd0: 0a 2a 2a 20 41 6c 6c 20 53 51 4c 69 74 65 20 64  .** All SQLite d
9be0: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
9bf0: 6f 6e 73 20 6d 75 73 74 20 62 65 20 63 6c 6f 73  ons must be clos
9c00: 65 64 20 62 65 66 6f 72 65 20 63 61 6c 6c 69 6e  ed before callin
9c10: 67 20 74 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e  g this.** routin
9c20: 65 2e 0a 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f  e..**.** THIS RO
9c30: 55 54 49 4e 45 20 49 53 20 4e 4f 54 20 54 48 52  UTINE IS NOT THR
9c40: 45 41 44 53 41 46 45 2e 20 20 43 61 6c 6c 20 74  EADSAFE.  Call t
9c50: 68 69 73 20 72 6f 75 74 69 6e 65 20 65 78 61 63  his routine exac
9c60: 74 6c 79 20 6f 6e 63 65 20 77 68 69 6c 65 0a 2a  tly once while.*
9c70: 2a 20 73 68 75 74 74 69 6e 67 20 64 6f 77 6e 20  * shutting down 
9c80: 69 6e 20 6f 72 64 65 72 20 74 6f 20 66 72 65 65  in order to free
9c90: 20 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20 6d   all remaining m
9ca0: 75 6c 74 69 70 6c 65 78 20 67 72 6f 75 70 73 2e  ultiplex groups.
9cb0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f  .*/.int sqlite3_
9cc0: 6d 75 6c 74 69 70 6c 65 78 5f 73 68 75 74 64 6f  multiplex_shutdo
9cd0: 77 6e 28 76 6f 69 64 29 7b 0a 20 20 69 66 28 20  wn(void){.  if( 
9ce0: 67 4d 75 6c 74 69 70 6c 65 78 2e 69 73 49 6e 69  gMultiplex.isIni
9cf0: 74 69 61 6c 69 7a 65 64 3d 3d 30 20 29 20 72 65  tialized==0 ) re
9d00: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55  turn SQLITE_MISU
9d10: 53 45 3b 0a 20 20 69 66 28 20 67 4d 75 6c 74 69  SE;.  if( gMulti
9d20: 70 6c 65 78 2e 70 47 72 6f 75 70 73 20 29 20 72  plex.pGroups ) r
9d30: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53  eturn SQLITE_MIS
9d40: 55 53 45 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65  USE;.  gMultiple
9d50: 78 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 20  x.isInitialized 
9d60: 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d  = 0;.  sqlite3_m
9d70: 75 74 65 78 5f 66 72 65 65 28 67 4d 75 6c 74 69  utex_free(gMulti
9d80: 70 6c 65 78 2e 70 4d 75 74 65 78 29 3b 0a 20 20  plex.pMutex);.  
9d90: 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72 65  sqlite3_vfs_unre
9da0: 67 69 73 74 65 72 28 26 67 4d 75 6c 74 69 70 6c  gister(&gMultipl
9db0: 65 78 2e 73 54 68 69 73 56 66 73 29 3b 0a 20 20  ex.sThisVfs);.  
9dc0: 6d 65 6d 73 65 74 28 26 67 4d 75 6c 74 69 70 6c  memset(&gMultipl
9dd0: 65 78 2c 20 30 2c 20 73 69 7a 65 6f 66 28 67 4d  ex, 0, sizeof(gM
9de0: 75 6c 74 69 70 6c 65 78 29 29 3b 0a 20 20 72 65  ultiplex));.  re
9df0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
9e00: 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }../************
9e10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9e20: 2a 20 54 65 73 74 20 43 6f 64 65 20 2a 2a 2a 2a  * Test Code ****
9e30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
9e50: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54  .#ifdef SQLITE_T
9e60: 45 53 54 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63  EST.#include <tc
9e70: 6c 2e 68 3e 0a 65 78 74 65 72 6e 20 63 6f 6e 73  l.h>.extern cons
9e80: 74 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33 54  t char *sqlite3T
9e90: 65 73 74 45 72 72 6f 72 4e 61 6d 65 28 69 6e 74  estErrorName(int
9ea0: 29 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d  );.../*.** tclcm
9eb0: 64 3a 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69  d: sqlite3_multi
9ec0: 70 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65 20  plex_initialize 
9ed0: 4e 41 4d 45 20 4d 41 4b 45 44 45 46 41 55 4c 54  NAME MAKEDEFAULT
9ee0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .*/.static int t
9ef0: 65 73 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 69 6e  est_multiplex_in
9f00: 69 74 69 61 6c 69 7a 65 28 0a 20 20 76 6f 69 64  itialize(.  void
9f10: 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20   * clientData,. 
9f20: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
9f30: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
9f40: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
9f50: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f  T objv[].){.  co
9f60: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b  nst char *zName;
9f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9f80: 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20 6d 75 6c   Name of new mul
9f90: 74 69 70 6c 65 78 20 56 46 53 20 2a 2f 0a 20 20  tiplex VFS */.  
9fa0: 69 6e 74 20 6d 61 6b 65 44 65 66 61 75 6c 74 3b  int makeDefault;
9fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9fc0: 2f 2a 20 54 72 75 65 20 74 6f 20 6d 61 6b 65 20  /* True to make 
9fd0: 74 68 65 20 6e 65 77 20 56 46 53 20 74 68 65 20  the new VFS the 
9fe0: 64 65 66 61 75 6c 74 20 2a 2f 0a 20 20 69 6e 74  default */.  int
9ff0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
a000: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a010: 56 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62  Value returned b
a020: 79 20 6d 75 6c 74 69 70 6c 65 78 5f 69 6e 69 74  y multiplex_init
a030: 69 61 6c 69 7a 65 28 29 20 2a 2f 0a 0a 20 20 55  ialize() */..  U
a040: 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28  NUSED_PARAMETER(
a050: 63 6c 69 65 6e 74 44 61 74 61 29 3b 0a 0a 20 20  clientData);..  
a060: 2f 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d  /* Process argum
a070: 65 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20 6f 62  ents */.  if( ob
a080: 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=3 ){.    Tcl
a090: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
a0a0: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
a0b0: 4e 41 4d 45 20 4d 41 4b 45 44 45 46 41 55 4c 54  NAME MAKEDEFAULT
a0c0: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
a0d0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
a0e0: 7a 4e 61 6d 65 20 3d 20 54 63 6c 5f 47 65 74 53  zName = Tcl_GetS
a0f0: 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a  tring(objv[1]);.
a100: 20 20 69 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f    if( Tcl_GetBoo
a110: 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  leanFromObj(inte
a120: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6d 61  rp, objv[2], &ma
a130: 6b 65 44 65 66 61 75 6c 74 29 20 29 20 72 65 74  keDefault) ) ret
a140: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
a150: 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 3d 3d 27   if( zName[0]=='
a160: 5c 30 27 20 29 20 7a 4e 61 6d 65 20 3d 20 30 3b  \0' ) zName = 0;
a170: 0a 0a 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69  ..  /* Call sqli
a180: 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 69 6e  te3_multiplex_in
a190: 69 74 69 61 6c 69 7a 65 28 29 20 2a 2f 0a 20 20  itialize() */.  
a1a0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 6c  rc = sqlite3_mul
a1b0: 74 69 70 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a  tiplex_initializ
a1c0: 65 28 7a 4e 61 6d 65 2c 20 6d 61 6b 65 44 65 66  e(zName, makeDef
a1d0: 61 75 6c 74 29 3b 0a 20 20 54 63 6c 5f 53 65 74  ault);.  Tcl_Set
a1e0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28  Result(interp, (
a1f0: 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 54 65  char *)sqlite3Te
a200: 73 74 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c  stErrorName(rc),
a210: 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a 20   TCL_STATIC);.. 
a220: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
a230: 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a  }../*.** tclcmd:
a240: 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c   sqlite3_multipl
a250: 65 78 5f 73 68 75 74 64 6f 77 6e 0a 2a 2f 0a 73  ex_shutdown.*/.s
a260: 74 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 6d  tatic int test_m
a270: 75 6c 74 69 70 6c 65 78 5f 73 68 75 74 64 6f 77  ultiplex_shutdow
a280: 6e 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  n(.  void * clie
a290: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
a2a0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
a2b0: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
a2c0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a2d0: 5d 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  ].){.  int rc;  
a2e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a2f0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
a300: 72 65 74 75 72 6e 65 64 20 62 79 20 6d 75 6c 74  returned by mult
a310: 69 70 6c 65 78 5f 73 68 75 74 64 6f 77 6e 28 29  iplex_shutdown()
a320: 20 2a 2f 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41   */..  UNUSED_PA
a330: 52 41 4d 45 54 45 52 28 63 6c 69 65 6e 74 44 61  RAMETER(clientDa
a340: 74 61 29 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63  ta);..  if( objc
a350: 21 3d 31 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=1 ){.    Tcl_W
a360: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
a370: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 22 29  rp, 1, objv, "")
a380: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
a390: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f  _ERROR;.  }..  /
a3a0: 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 6d  * Call sqlite3_m
a3b0: 75 6c 74 69 70 6c 65 78 5f 73 68 75 74 64 6f 77  ultiplex_shutdow
a3c0: 6e 28 29 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  n() */.  rc = sq
a3d0: 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f  lite3_multiplex_
a3e0: 73 68 75 74 64 6f 77 6e 28 29 3b 0a 20 20 54 63  shutdown();.  Tc
a3f0: 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65  l_SetResult(inte
a400: 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c 69  rp, (char *)sqli
a410: 74 65 33 54 65 73 74 45 72 72 6f 72 4e 61 6d 65  te3TestErrorName
a420: 28 72 63 29 2c 20 54 43 4c 5f 53 54 41 54 49 43  (rc), TCL_STATIC
a430: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  );..  return TCL
a440: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63  _OK;.}../*.** tc
a450: 6c 63 6d 64 3a 20 20 73 71 6c 69 74 65 33 5f 6d  lcmd:  sqlite3_m
a460: 75 6c 74 69 70 6c 65 78 5f 64 75 6d 70 0a 2a 2f  ultiplex_dump.*/
a470: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 65 73 74  .static int test
a480: 5f 6d 75 6c 74 69 70 6c 65 78 5f 64 75 6d 70 28  _multiplex_dump(
a490: 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74  .  void * client
a4a0: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
a4b0: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
a4c0: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
a4d0: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
a4e0: 29 7b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 52  ){.  Tcl_Obj *pR
a4f0: 65 73 75 6c 74 3b 0a 20 20 54 63 6c 5f 4f 62 6a  esult;.  Tcl_Obj
a500: 20 2a 70 47 72 6f 75 70 54 65 72 6d 3b 0a 20 20   *pGroupTerm;.  
a510: 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a  multiplexGroup *
a520: 70 47 72 6f 75 70 3b 0a 20 20 69 6e 74 20 69 3b  pGroup;.  int i;
a530: 0a 20 20 69 6e 74 20 6e 43 68 75 6e 6b 73 20 3d  .  int nChunks =
a540: 20 30 3b 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41   0;..  UNUSED_PA
a550: 52 41 4d 45 54 45 52 28 63 6c 69 65 6e 74 44 61  RAMETER(clientDa
a560: 74 61 29 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41  ta);.  UNUSED_PA
a570: 52 41 4d 45 54 45 52 28 6f 62 6a 63 29 3b 0a 20  RAMETER(objc);. 
a580: 20 55 4e 55 53 45 44 5f 50 41 52 41 4d 45 54 45   UNUSED_PARAMETE
a590: 52 28 6f 62 6a 76 29 3b 0a 0a 20 20 70 52 65 73  R(objv);..  pRes
a5a0: 75 6c 74 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  ult = Tcl_NewObj
a5b0: 28 29 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 45  ();.  multiplexE
a5c0: 6e 74 65 72 28 29 3b 0a 20 20 66 6f 72 28 70 47  nter();.  for(pG
a5d0: 72 6f 75 70 3d 67 4d 75 6c 74 69 70 6c 65 78 2e  roup=gMultiplex.
a5e0: 70 47 72 6f 75 70 73 3b 20 70 47 72 6f 75 70 3b  pGroups; pGroup;
a5f0: 20 70 47 72 6f 75 70 3d 70 47 72 6f 75 70 2d 3e   pGroup=pGroup->
a600: 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 47 72 6f  pNext){.    pGro
a610: 75 70 54 65 72 6d 20 3d 20 54 63 6c 5f 4e 65 77  upTerm = Tcl_New
a620: 4f 62 6a 28 29 3b 0a 0a 20 20 20 20 69 66 28 20  Obj();..    if( 
a630: 70 47 72 6f 75 70 2d 3e 7a 4e 61 6d 65 20 29 7b  pGroup->zName ){
a640: 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 7a  .      pGroup->z
a650: 4e 61 6d 65 5b 70 47 72 6f 75 70 2d 3e 6e 4e 61  Name[pGroup->nNa
a660: 6d 65 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 20 20  me] = '\0';.    
a670: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
a680: 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72  endElement(inter
a690: 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20  p, pGroupTerm,. 
a6a0: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77           Tcl_New
a6b0: 53 74 72 69 6e 67 4f 62 6a 28 70 47 72 6f 75 70  StringObj(pGroup
a6c0: 2d 3e 7a 4e 61 6d 65 2c 20 2d 31 29 29 3b 0a 20  ->zName, -1));. 
a6d0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
a6e0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
a6f0: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
a700: 20 70 47 72 6f 75 70 54 65 72 6d 2c 20 54 63 6c   pGroupTerm, Tcl
a710: 5f 4e 65 77 4f 62 6a 28 29 29 3b 0a 20 20 20 20  _NewObj());.    
a720: 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  }.    Tcl_ListOb
a730: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
a740: 6e 74 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72  nterp, pGroupTer
a750: 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c  m,.          Tcl
a760: 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 47 72 6f 75  _NewIntObj(pGrou
a770: 70 2d 3e 6e 4e 61 6d 65 29 29 3b 0a 20 20 20 20  p->nName));.    
a780: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
a790: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
a7a0: 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20 20 20   pGroupTerm,.   
a7b0: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 49 6e         Tcl_NewIn
a7c0: 74 4f 62 6a 28 70 47 72 6f 75 70 2d 3e 66 6c 61  tObj(pGroup->fla
a7d0: 67 73 29 29 3b 0a 0a 20 20 20 20 2f 2a 20 63 6f  gs));..    /* co
a7e0: 75 6e 74 20 6e 75 6d 62 65 72 20 6f 66 20 63 68  unt number of ch
a7f0: 75 6e 6b 73 20 77 69 74 68 20 6f 70 65 6e 20 68  unks with open h
a800: 61 6e 64 6c 65 73 20 2a 2f 0a 20 20 20 20 66 6f  andles */.    fo
a810: 72 28 69 3d 30 3b 20 69 3c 70 47 72 6f 75 70 2d  r(i=0; i<pGroup-
a820: 3e 6e 52 65 61 6c 3b 20 69 2b 2b 29 7b 0a 20 20  >nReal; i++){.  
a830: 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e      if( pGroup->
a840: 61 52 65 61 6c 5b 69 5d 2e 70 21 3d 30 20 29 20  aReal[i].p!=0 ) 
a850: 6e 43 68 75 6e 6b 73 2b 2b 3b 0a 20 20 20 20 7d  nChunks++;.    }
a860: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
a870: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e  AppendElement(in
a880: 74 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d  terp, pGroupTerm
a890: 2c 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f  ,.          Tcl_
a8a0: 4e 65 77 49 6e 74 4f 62 6a 28 6e 43 68 75 6e 6b  NewIntObj(nChunk
a8b0: 73 29 29 3b 0a 0a 20 20 20 20 54 63 6c 5f 4c 69  s));..    Tcl_Li
a8c0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
a8d0: 6e 74 28 69 6e 74 65 72 70 2c 20 70 47 72 6f 75  nt(interp, pGrou
a8e0: 70 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20  pTerm,.         
a8f0: 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70   Tcl_NewIntObj(p
a900: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 29  Group->szChunk))
a910: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
a920: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
a930: 6e 74 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72  nterp, pGroupTer
a940: 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c  m,.          Tcl
a950: 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 47 72 6f 75  _NewIntObj(pGrou
a960: 70 2d 3e 6e 52 65 61 6c 29 29 3b 0a 0a 20 20 20  p->nReal));..   
a970: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
a980: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
a990: 2c 20 70 52 65 73 75 6c 74 2c 20 70 47 72 6f 75  , pResult, pGrou
a9a0: 70 54 65 72 6d 29 3b 0a 20 20 7d 0a 20 20 6d 75  pTerm);.  }.  mu
a9b0: 6c 74 69 70 6c 65 78 4c 65 61 76 65 28 29 3b 0a  ltiplexLeave();.
a9c0: 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75    Tcl_SetObjResu
a9d0: 6c 74 28 69 6e 74 65 72 70 2c 20 70 52 65 73 75  lt(interp, pResu
a9e0: 6c 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  lt);.  return TC
a9f0: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  L_OK;.}../*.** T
aa00: 63 6c 63 6d 64 3a 20 74 65 73 74 5f 6d 75 6c 74  clcmd: test_mult
aa10: 69 70 6c 65 78 5f 63 6f 6e 74 72 6f 6c 20 48 41  iplex_control HA
aa20: 4e 44 4c 45 20 44 42 4e 41 4d 45 20 53 55 42 2d  NDLE DBNAME SUB-
aa30: 43 4f 4d 4d 41 4e 44 20 3f 49 4e 54 2d 56 41 4c  COMMAND ?INT-VAL
aa40: 55 45 3f 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  UE?.*/.static in
aa50: 74 20 74 65 73 74 5f 6d 75 6c 74 69 70 6c 65 78  t test_multiplex
aa60: 5f 63 6f 6e 74 72 6f 6c 28 0a 20 20 43 6c 69 65  _control(.  Clie
aa70: 6e 74 44 61 74 61 20 63 64 2c 0a 20 20 54 63 6c  ntData cd,.  Tcl
aa80: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
aa90: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54  .  int objc,.  T
aaa0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
aab0: 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e 74 20 72 63  jv[].){.  int rc
aac0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
aad0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
aae0: 75 72 6e 20 63 6f 64 65 20 66 72 6f 6d 20 66 69  urn code from fi
aaf0: 6c 65 5f 63 6f 6e 74 72 6f 6c 28 29 20 2a 2f 0a  le_control() */.
ab00: 20 20 69 6e 74 20 69 64 78 3b 20 20 20 20 20 20    int idx;      
ab10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab20: 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 20 61 53    /* Index in aS
ab30: 75 62 5b 5d 20 2a 2f 0a 20 20 54 63 6c 5f 43 6d  ub[] */.  Tcl_Cm
ab40: 64 49 6e 66 6f 20 63 6d 64 49 6e 66 6f 3b 20 20  dInfo cmdInfo;  
ab50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6d            /* Com
ab60: 6d 61 6e 64 20 69 6e 66 6f 20 73 74 72 75 63 74  mand info struct
ab70: 75 72 65 20 66 6f 72 20 48 41 4e 44 4c 45 20 2a  ure for HANDLE *
ab80: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
ab90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aba0: 20 20 20 20 2f 2a 20 55 6e 64 65 72 6c 79 69 6e      /* Underlyin
abb0: 67 20 64 62 20 68 61 6e 64 6c 65 20 66 6f 72 20  g db handle for 
abc0: 48 41 4e 44 4c 45 20 2a 2f 0a 20 20 69 6e 74 20  HANDLE */.  int 
abd0: 69 56 61 6c 75 65 20 3d 20 30 3b 0a 20 20 76 6f  iValue = 0;.  vo
abe0: 69 64 20 2a 70 41 72 67 20 3d 20 30 3b 0a 0a 20  id *pArg = 0;.. 
abf0: 20 73 74 72 75 63 74 20 53 75 62 43 6f 6d 6d 61   struct SubComma
ac00: 6e 64 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  nd {.    const c
ac10: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
ac20: 69 6e 74 20 6f 70 3b 0a 20 20 20 20 69 6e 74 20  int op;.    int 
ac30: 61 72 67 74 79 70 65 3b 0a 20 20 7d 20 61 53 75  argtype;.  } aSu
ac40: 62 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 65  b[] = {.    { "e
ac50: 6e 61 62 6c 65 22 2c 20 20 20 20 20 20 20 4d 55  nable",       MU
ac60: 4c 54 49 50 4c 45 58 5f 43 54 52 4c 5f 45 4e 41  LTIPLEX_CTRL_ENA
ac70: 42 4c 45 2c 20 20 20 20 20 20 20 20 20 20 20 31  BLE,           1
ac80: 20 7d 2c 0a 20 20 20 20 7b 20 22 63 68 75 6e 6b   },.    { "chunk
ac90: 5f 73 69 7a 65 22 2c 20 20 20 4d 55 4c 54 49 50  _size",   MULTIP
aca0: 4c 45 58 5f 43 54 52 4c 5f 53 45 54 5f 43 48 55  LEX_CTRL_SET_CHU
acb0: 4e 4b 5f 53 49 5a 45 2c 20 20 20 31 20 7d 2c 0a  NK_SIZE,   1 },.
acc0: 20 20 20 20 7b 20 22 6d 61 78 5f 63 68 75 6e 6b      { "max_chunk
acd0: 73 22 2c 20 20 20 4d 55 4c 54 49 50 4c 45 58 5f  s",   MULTIPLEX_
ace0: 43 54 52 4c 5f 53 45 54 5f 4d 41 58 5f 43 48 55  CTRL_SET_MAX_CHU
acf0: 4e 4b 53 2c 20 20 20 31 20 7d 2c 0a 20 20 20 20  NKS,   1 },.    
ad00: 7b 20 30 2c 20 30 2c 20 30 20 7d 0a 20 20 7d 3b  { 0, 0, 0 }.  };
ad10: 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 35 20  ..  if( objc!=5 
ad20: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
ad30: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
ad40: 31 2c 20 6f 62 6a 76 2c 20 22 48 41 4e 44 4c 45  1, objv, "HANDLE
ad50: 20 44 42 4e 41 4d 45 20 53 55 42 2d 43 4f 4d 4d   DBNAME SUB-COMM
ad60: 41 4e 44 20 49 4e 54 2d 56 41 4c 55 45 22 29 3b  AND INT-VALUE");
ad70: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
ad80: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66  ERROR;.  }..  if
ad90: 28 20 30 3d 3d 54 63 6c 5f 47 65 74 43 6f 6d 6d  ( 0==Tcl_GetComm
ada0: 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20  andInfo(interp, 
adb0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
adc0: 6a 76 5b 31 5d 29 2c 20 26 63 6d 64 49 6e 66 6f  jv[1]), &cmdInfo
add0: 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  ) ){.    Tcl_App
ade0: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
adf0: 2c 20 22 65 78 70 65 63 74 65 64 20 64 61 74 61  , "expected data
ae00: 62 61 73 65 20 68 61 6e 64 6c 65 2c 20 67 6f 74  base handle, got
ae10: 20 5c 22 22 2c 20 30 29 3b 0a 20 20 20 20 54 63   \"", 0);.    Tc
ae20: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
ae30: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74  nterp, Tcl_GetSt
ae40: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 22  ring(objv[1]), "
ae50: 5c 22 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  \"", 0);.    ret
ae60: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
ae70: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 64 62 20 3d   }else{.    db =
ae80: 20 2a 28 73 71 6c 69 74 65 33 20 2a 2a 29 63 6d   *(sqlite3 **)cm
ae90: 64 49 6e 66 6f 2e 6f 62 6a 43 6c 69 65 6e 74 44  dInfo.objClientD
aea0: 61 74 61 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  ata;.  }..  rc =
aeb0: 20 54 63 6c 5f 47 65 74 49 6e 64 65 78 46 72 6f   Tcl_GetIndexFro
aec0: 6d 4f 62 6a 53 74 72 75 63 74 28 0a 20 20 20 20  mObjStruct(.    
aed0: 20 20 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 33    interp, objv[3
aee0: 5d 2c 20 61 53 75 62 2c 20 73 69 7a 65 6f 66 28  ], aSub, sizeof(
aef0: 61 53 75 62 5b 30 5d 29 2c 20 22 73 75 62 2d 63  aSub[0]), "sub-c
af00: 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20 26 69 64 78  ommand", 0, &idx
af10: 0a 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  .  );.  if( rc!=
af20: 54 43 4c 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  TCL_OK ) return 
af30: 72 63 3b 0a 0a 20 20 73 77 69 74 63 68 28 20 61  rc;..  switch( a
af40: 53 75 62 5b 69 64 78 5d 2e 61 72 67 74 79 70 65  Sub[idx].argtype
af50: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 31 3a 0a   ){.    case 1:.
af60: 20 20 20 20 20 20 69 66 28 20 54 63 6c 5f 47 65        if( Tcl_Ge
af70: 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  tIntFromObj(inte
af80: 72 70 2c 20 6f 62 6a 76 5b 34 5d 2c 20 26 69 56  rp, objv[4], &iV
af90: 61 6c 75 65 29 20 29 7b 0a 20 20 20 20 20 20 20  alue) ){.       
afa0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
afb0: 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  R;.      }.     
afc0: 20 70 41 72 67 20 3d 20 28 76 6f 69 64 20 2a 29   pArg = (void *)
afd0: 26 69 56 61 6c 75 65 3b 0a 20 20 20 20 20 20 62  &iValue;.      b
afe0: 72 65 61 6b 3b 0a 20 20 20 20 64 65 66 61 75 6c  reak;.    defaul
aff0: 74 3a 0a 20 20 20 20 20 20 54 63 6c 5f 57 72 6f  t:.      Tcl_Wro
b000: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
b010: 2c 20 34 2c 20 6f 62 6a 76 2c 20 22 53 55 42 2d  , 4, objv, "SUB-
b020: 43 4f 4d 4d 41 4e 44 22 29 3b 0a 20 20 20 20 20  COMMAND");.     
b030: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
b040: 52 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 73  R;.  }..  rc = s
b050: 71 6c 69 74 65 33 5f 66 69 6c 65 5f 63 6f 6e 74  qlite3_file_cont
b060: 72 6f 6c 28 64 62 2c 20 54 63 6c 5f 47 65 74 53  rol(db, Tcl_GetS
b070: 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 2c 20  tring(objv[2]), 
b080: 61 53 75 62 5b 69 64 78 5d 2e 6f 70 2c 20 70 41  aSub[idx].op, pA
b090: 72 67 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52 65  rg);.  Tcl_SetRe
b0a0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68  sult(interp, (ch
b0b0: 61 72 20 2a 29 73 71 6c 69 74 65 33 54 65 73 74  ar *)sqlite3Test
b0c0: 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20 54  ErrorName(rc), T
b0d0: 43 4c 5f 53 54 41 54 49 43 29 3b 0a 20 20 72 65  CL_STATIC);.  re
b0e0: 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45  turn (rc==SQLITE
b0f0: 5f 4f 4b 29 20 3f 20 54 43 4c 5f 4f 4b 20 3a 20  _OK) ? TCL_OK : 
b100: 54 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a  TCL_ERROR;.}../*
b110: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
b120: 20 72 65 67 69 73 74 65 72 73 20 74 68 65 20 63   registers the c
b130: 75 73 74 6f 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e  ustom TCL comman
b140: 64 73 20 64 65 66 69 6e 65 64 20 69 6e 20 74 68  ds defined in th
b150: 69 73 0a 2a 2a 20 6d 6f 64 75 6c 65 2e 20 20 54  is.** module.  T
b160: 68 69 73 20 73 68 6f 75 6c 64 20 62 65 20 74 68  his should be th
b170: 65 20 6f 6e 6c 79 20 70 72 6f 63 65 64 75 72 65  e only procedure
b180: 20 76 69 73 69 62 6c 65 20 66 72 6f 6d 20 6f 75   visible from ou
b190: 74 73 69 64 65 0a 2a 2a 20 6f 66 20 74 68 69 73  tside.** of this
b1a0: 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20   module..*/.int 
b1b0: 53 71 6c 69 74 65 6d 75 6c 74 69 70 6c 65 78 5f  Sqlitemultiplex_
b1c0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
b1d0: 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74  *interp){.  stat
b1e0: 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20  ic struct {.    
b1f0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
b200: 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f     Tcl_ObjCmdPro
b210: 63 20 2a 78 50 72 6f 63 3b 0a 20 20 7d 20 61 43  c *xProc;.  } aC
b220: 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22  md[] = {.    { "
b230: 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65  sqlite3_multiple
b240: 78 5f 69 6e 69 74 69 61 6c 69 7a 65 22 2c 20 74  x_initialize", t
b250: 65 73 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 69 6e  est_multiplex_in
b260: 69 74 69 61 6c 69 7a 65 20 7d 2c 0a 20 20 20 20  itialize },.    
b270: 7b 20 22 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69  { "sqlite3_multi
b280: 70 6c 65 78 5f 73 68 75 74 64 6f 77 6e 22 2c 20  plex_shutdown", 
b290: 74 65 73 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 73  test_multiplex_s
b2a0: 68 75 74 64 6f 77 6e 20 7d 2c 0a 20 20 20 20 7b  hutdown },.    {
b2b0: 20 22 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70   "sqlite3_multip
b2c0: 6c 65 78 5f 64 75 6d 70 22 2c 20 74 65 73 74 5f  lex_dump", test_
b2d0: 6d 75 6c 74 69 70 6c 65 78 5f 64 75 6d 70 20 7d  multiplex_dump }
b2e0: 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  ,.    { "sqlite3
b2f0: 5f 6d 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74 72  _multiplex_contr
b300: 6f 6c 22 2c 20 74 65 73 74 5f 6d 75 6c 74 69 70  ol", test_multip
b310: 6c 65 78 5f 63 6f 6e 74 72 6f 6c 20 7d 2c 0a 20  lex_control },. 
b320: 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20   };.  int i;..  
b330: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f  for(i=0; i<sizeo
b340: 66 28 61 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  f(aCmd)/sizeof(a
b350: 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  Cmd[0]); i++){. 
b360: 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a     Tcl_CreateObj
b370: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
b380: 61 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 61  aCmd[i].zName, a
b390: 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 30 2c  Cmd[i].xProc, 0,
b3a0: 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75   0);.  }..  retu
b3b0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 23 65 6e  rn TCL_OK;.}.#en
b3c0: 64 69 66 0a                                      dif.