/ Hex Artifact Content
Login

Artifact e054459f7633f3ff8ce1245da724f9a8be189e4e:


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 61 72 61 74 65 6c 79 20 68 65  ed separately 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 20  SIZE 0x1000../* 
0ad0: 4d 61 78 69 6d 75 6d 20 63 68 75 6e 6b 20 6e 75  Maximum chunk nu
0ae0: 6d 62 65 72 20 2a 2f 0a 23 64 65 66 69 6e 65 20  mber */.#define 
0af0: 4d 58 5f 43 48 55 4e 4b 5f 4e 55 4d 42 45 52 20  MX_CHUNK_NUMBER 
0b00: 32 39 39 0a 0a 2f 2a 20 46 69 72 73 74 20 63 68  299../* First ch
0b10: 75 6e 6b 20 66 6f 72 20 72 6f 6c 6c 62 61 63 6b  unk for rollback
0b20: 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 73 20 2a   journal files *
0b30: 2f 0a 23 64 65 66 69 6e 65 20 53 51 4c 49 54 45  /.#define SQLITE
0b40: 5f 4d 55 4c 54 49 50 4c 45 58 5f 4a 4f 55 52 4e  _MULTIPLEX_JOURN
0b50: 41 4c 5f 38 5f 33 5f 4f 46 46 53 45 54 20 34 30  AL_8_3_OFFSET 40
0b60: 30 0a 23 64 65 66 69 6e 65 20 53 51 4c 49 54 45  0.#define SQLITE
0b70: 5f 4d 55 4c 54 49 50 4c 45 58 5f 57 41 4c 5f 38  _MULTIPLEX_WAL_8
0b80: 5f 33 5f 4f 46 46 53 45 54 20 37 30 30 0a 0a 0a  _3_OFFSET 700...
0b90: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
0ba0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 53 68 69 6d 20 44  ********* Shim D
0bb0: 65 66 69 6e 69 74 69 6f 6e 73 20 2a 2a 2a 2a 2a  efinitions *****
0bc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0bd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 23 69 66 6e  *********/..#ifn
0be0: 64 65 66 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49  def SQLITE_MULTI
0bf0: 50 4c 45 58 5f 56 46 53 5f 4e 41 4d 45 0a 23 20  PLEX_VFS_NAME.# 
0c00: 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 4d 55  define SQLITE_MU
0c10: 4c 54 49 50 4c 45 58 5f 56 46 53 5f 4e 41 4d 45  LTIPLEX_VFS_NAME
0c20: 20 22 6d 75 6c 74 69 70 6c 65 78 22 0a 23 65 6e   "multiplex".#en
0c30: 64 69 66 0a 0a 2f 2a 20 54 68 69 73 20 69 73 20  dif../* This is 
0c40: 74 68 65 20 6c 69 6d 69 74 20 6f 6e 20 74 68 65  the limit on the
0c50: 20 63 68 75 6e 6b 20 73 69 7a 65 2e 20 20 49 74   chunk size.  It
0c60: 20 6d 61 79 20 62 65 20 63 68 61 6e 67 65 64 20   may be changed 
0c70: 62 79 20 63 61 6c 6c 69 6e 67 0a 2a 2a 20 74 68  by calling.** th
0c80: 65 20 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 29  e xFileControl()
0c90: 20 69 6e 74 65 72 66 61 63 65 2e 20 20 49 74 20   interface.  It 
0ca0: 77 69 6c 6c 20 62 65 20 72 6f 75 6e 64 65 64 20  will be rounded 
0cb0: 75 70 20 74 6f 20 61 20 0a 2a 2a 20 6d 75 6c 74  up to a .** mult
0cc0: 69 70 6c 65 20 6f 66 20 4d 41 58 5f 50 41 47 45  iple of MAX_PAGE
0cd0: 5f 53 49 5a 45 2e 20 20 57 65 20 64 65 66 61 75  _SIZE.  We defau
0ce0: 6c 74 20 69 74 20 68 65 72 65 20 74 6f 20 32 47  lt it here to 2G
0cf0: 69 42 20 6c 65 73 73 20 36 34 4b 69 42 2e 0a 2a  iB less 64KiB..*
0d00: 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /.#ifndef SQLITE
0d10: 5f 4d 55 4c 54 49 50 4c 45 58 5f 43 48 55 4e 4b  _MULTIPLEX_CHUNK
0d20: 5f 53 49 5a 45 0a 23 20 64 65 66 69 6e 65 20 53  _SIZE.# define S
0d30: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
0d40: 43 48 55 4e 4b 5f 53 49 5a 45 20 32 31 34 37 34  CHUNK_SIZE 21474
0d50: 31 38 31 31 32 0a 23 65 6e 64 69 66 0a 0a 2f 2a  18112.#endif../*
0d60: 20 54 68 69 73 20 75 73 65 64 20 74 6f 20 62 65   This used to be
0d70: 20 74 68 65 20 64 65 66 61 75 6c 74 20 6c 69 6d   the default lim
0d80: 69 74 20 6f 6e 20 6e 75 6d 62 65 72 20 6f 66 20  it on number of 
0d90: 63 68 75 6e 6b 73 2c 20 62 75 74 0a 2a 2a 20 69  chunks, but.** i
0da0: 74 20 69 73 20 6e 6f 20 6c 6f 6e 67 65 72 20 65  t is no longer e
0db0: 6e 66 6f 72 63 65 64 2e 20 54 68 65 72 65 20 69  nforced. There i
0dc0: 73 20 63 75 72 72 65 6e 74 6c 79 20 6e 6f 20 6c  s currently no l
0dd0: 69 6d 69 74 20 74 6f 20 74 68 65 0a 2a 2a 20 6e  imit to the.** n
0de0: 75 6d 62 65 72 20 6f 66 20 63 68 75 6e 6b 73 2e  umber of chunks.
0df0: 0a 2a 2a 0a 2a 2a 20 4d 61 79 20 62 65 20 63 68  .**.** May be ch
0e00: 61 6e 67 65 64 20 62 79 20 63 61 6c 6c 69 6e 67  anged by calling
0e10: 20 74 68 65 20 78 46 69 6c 65 43 6f 6e 74 72 6f   the xFileContro
0e20: 6c 28 29 20 69 6e 74 65 72 66 61 63 65 2e 0a 2a  l() interface..*
0e30: 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /.#ifndef SQLITE
0e40: 5f 4d 55 4c 54 49 50 4c 45 58 5f 4d 41 58 5f 43  _MULTIPLEX_MAX_C
0e50: 48 55 4e 4b 53 0a 23 20 64 65 66 69 6e 65 20 53  HUNKS.# define S
0e60: 51 4c 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f  QLITE_MULTIPLEX_
0e70: 4d 41 58 5f 43 48 55 4e 4b 53 20 31 32 0a 23 65  MAX_CHUNKS 12.#e
0e80: 6e 64 69 66 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  ndif../*********
0e90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20  *************** 
0ea0: 4f 62 6a 65 63 74 20 44 65 66 69 6e 69 74 69 6f  Object Definitio
0eb0: 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ns *************
0ec0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0ed0: 2a 2f 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 64  */../* Forward d
0ee0: 65 63 6c 61 72 61 74 69 6f 6e 20 6f 66 20 61 6c  eclaration of al
0ef0: 6c 20 6f 62 6a 65 63 74 20 74 79 70 65 73 20 2a  l object types *
0f00: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
0f10: 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20   multiplexGroup 
0f20: 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 3b 0a  multiplexGroup;.
0f30: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 6d  typedef struct m
0f40: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 6d 75 6c  ultiplexConn mul
0f50: 74 69 70 6c 65 78 43 6f 6e 6e 3b 0a 0a 2f 2a 0a  tiplexConn;../*.
0f60: 2a 2a 20 41 20 22 6d 75 6c 74 69 70 6c 65 78 20  ** A "multiplex 
0f70: 67 72 6f 75 70 22 20 69 73 20 61 20 63 6f 6c 6c  group" is a coll
0f80: 65 63 74 69 6f 6e 20 6f 66 20 66 69 6c 65 73 20  ection of files 
0f90: 74 68 61 74 20 63 6f 6c 6c 65 63 74 69 76 65 6c  that collectivel
0fa0: 79 0a 2a 2a 20 6d 61 6b 65 75 70 20 61 20 73 69  y.** makeup a si
0fb0: 6e 67 6c 65 20 53 51 4c 69 74 65 20 44 42 20 66  ngle SQLite DB f
0fc0: 69 6c 65 2e 20 20 54 68 69 73 20 61 6c 6c 6f 77  ile.  This allow
0fd0: 73 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  s the size of th
0fe0: 65 20 44 42 0a 2a 2a 20 74 6f 20 65 78 63 65 65  e DB.** to excee
0ff0: 64 20 74 68 65 20 6c 69 6d 69 74 73 20 69 6d 70  d the limits imp
1000: 6f 73 65 64 20 62 79 20 74 68 65 20 66 69 6c 65  osed by the file
1010: 20 73 79 73 74 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54   system..**.** T
1020: 68 65 72 65 20 69 73 20 61 6e 20 69 6e 73 74 61  here is an insta
1030: 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  nce of the follo
1040: 77 69 6e 67 20 6f 62 6a 65 63 74 20 66 6f 72 20  wing object for 
1050: 65 61 63 68 20 64 65 66 69 6e 65 64 20 6d 75 6c  each defined mul
1060: 74 69 70 6c 65 78 0a 2a 2a 20 67 72 6f 75 70 2e  tiplex.** group.
1070: 0a 2a 2f 0a 73 74 72 75 63 74 20 6d 75 6c 74 69  .*/.struct multi
1080: 70 6c 65 78 47 72 6f 75 70 20 7b 0a 20 20 73 74  plexGroup {.  st
1090: 72 75 63 74 20 6d 75 6c 74 69 70 6c 65 78 52 65  ruct multiplexRe
10a0: 61 6c 20 7b 20 20 20 20 20 20 20 20 20 20 20 2f  al {           /
10b0: 2a 20 46 6f 72 20 65 61 63 68 20 63 68 75 6e 6b  * For each chunk
10c0: 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   */.    sqlite3_
10d0: 66 69 6c 65 20 2a 70 3b 20 20 20 20 20 20 20 20  file *p;        
10e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e            /* Han
10f0: 64 6c 65 20 66 6f 72 20 74 68 65 20 63 68 75 6e  dle for the chun
1100: 6b 20 2a 2f 0a 20 20 20 20 63 68 61 72 20 2a 7a  k */.    char *z
1110: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1120: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
1130: 6d 65 20 6f 66 20 74 68 69 73 20 63 68 75 6e 6b  me of this chunk
1140: 20 2a 2f 0a 20 20 7d 20 2a 61 52 65 61 6c 3b 20   */.  } *aReal; 
1150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1160: 20 20 20 20 20 20 20 2f 2a 20 6c 69 73 74 20 6f         /* list o
1170: 66 20 61 6c 6c 20 63 68 75 6e 6b 73 20 2a 2f 0a  f all chunks */.
1180: 20 20 69 6e 74 20 6e 52 65 61 6c 3b 20 20 20 20    int nReal;    
1190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11a0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
11b0: 63 68 75 6e 6b 73 20 2a 2f 0a 20 20 63 68 61 72  chunks */.  char
11c0: 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20   *zName;        
11d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11e0: 42 61 73 65 20 66 69 6c 65 6e 61 6d 65 20 6f 66  Base filename of
11f0: 20 74 68 69 73 20 67 72 6f 75 70 20 2a 2f 0a 20   this group */. 
1200: 20 69 6e 74 20 6e 4e 61 6d 65 3b 20 20 20 20 20   int nName;     
1210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1220: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 62    /* Length of b
1230: 61 73 65 20 66 69 6c 65 6e 61 6d 65 20 2a 2f 0a  ase filename */.
1240: 20 20 69 6e 74 20 66 6c 61 67 73 3b 20 20 20 20    int flags;    
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1260: 20 20 20 2f 2a 20 46 6c 61 67 73 20 75 73 65 64     /* Flags used
1270: 20 66 6f 72 20 6f 72 69 67 69 6e 61 6c 20 6f 70   for original op
1280: 65 6e 69 6e 67 20 2a 2f 0a 20 20 75 6e 73 69 67  ening */.  unsig
1290: 6e 65 64 20 69 6e 74 20 73 7a 43 68 75 6e 6b 3b  ned int szChunk;
12a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
12b0: 68 75 6e 6b 20 73 69 7a 65 20 75 73 65 64 20 66  hunk size used f
12c0: 6f 72 20 74 68 69 73 20 67 72 6f 75 70 20 2a 2f  or this group */
12d0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
12e0: 20 62 45 6e 61 62 6c 65 64 3b 20 20 20 20 20 20   bEnabled;      
12f0: 20 20 20 20 2f 2a 20 54 52 55 45 20 74 6f 20 75      /* TRUE to u
1300: 73 65 20 4d 75 6c 74 69 70 6c 65 78 20 56 46 53  se Multiplex VFS
1310: 20 66 6f 72 20 74 68 69 73 20 66 69 6c 65 20 2a   for this file *
1320: 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61  /.  unsigned cha
1330: 72 20 62 54 72 75 6e 63 61 74 65 3b 20 20 20 20  r bTruncate;    
1340: 20 20 20 20 20 2f 2a 20 54 52 55 45 20 74 6f 20       /* TRUE to 
1350: 65 6e 61 62 6c 65 20 74 72 75 6e 63 61 74 69 6f  enable truncatio
1360: 6e 20 6f 66 20 64 61 74 61 62 61 73 65 73 20 2a  n of databases *
1370: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69  /.};../*.** An i
1380: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66  nstance of the f
1390: 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20  ollowing object 
13a0: 72 65 70 72 65 73 65 6e 74 73 20 65 61 63 68 20  represents each 
13b0: 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a  open connection.
13c0: 2a 2a 20 74 6f 20 61 20 66 69 6c 65 20 74 68 61  ** to a file tha
13d0: 74 20 69 73 20 6d 75 6c 74 69 70 6c 65 78 27 65  t is multiplex'e
13e0: 64 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20  d.  This object 
13f0: 69 73 20 61 20 0a 2a 2a 20 73 75 62 63 6c 61 73  is a .** subclas
1400: 73 20 6f 66 20 73 71 6c 69 74 65 33 5f 66 69 6c  s of sqlite3_fil
1410: 65 2e 20 20 54 68 65 20 73 71 6c 69 74 65 33 5f  e.  The sqlite3_
1420: 66 69 6c 65 20 6f 62 6a 65 63 74 20 66 6f 72 20  file object for 
1430: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a  the underlying.*
1440: 2a 20 56 46 53 20 69 73 20 61 70 70 65 6e 64 65  * VFS is appende
1450: 64 20 74 6f 20 74 68 69 73 20 73 74 72 75 63 74  d to this struct
1460: 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 6d  ure..*/.struct m
1470: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 7b 0a 20  ultiplexConn {. 
1480: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 62 61   sqlite3_file ba
1490: 73 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  se;             
14a0: 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d   /* Base class -
14b0: 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20 2a   must be first *
14c0: 2f 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f  /.  multiplexGro
14d0: 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20  up *pGroup;     
14e0: 20 20 20 20 2f 2a 20 54 68 65 20 75 6e 64 65 72      /* The under
14f0: 6c 79 69 6e 67 20 67 72 6f 75 70 20 6f 66 20 66  lying group of f
1500: 69 6c 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 2a 2a  iles */.};../***
1510: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1520: 2a 2a 2a 2a 2a 2a 20 47 6c 6f 62 61 6c 20 56 61  ****** Global Va
1530: 72 69 61 62 6c 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a  riables ********
1540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1550: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a  **********/./*.*
1560: 2a 20 41 6c 6c 20 67 6c 6f 62 61 6c 20 76 61 72  * All global var
1570: 69 61 62 6c 65 73 20 75 73 65 64 20 62 79 20 74  iables used by t
1580: 68 69 73 20 66 69 6c 65 20 61 72 65 20 63 6f 6e  his file are con
1590: 74 61 69 6e 69 6e 67 20 77 69 74 68 69 6e 20 74  taining within t
15a0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20  he following.** 
15b0: 67 4d 75 6c 74 69 70 6c 65 78 20 73 74 72 75 63  gMultiplex struc
15c0: 74 75 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ture..*/.static 
15d0: 73 74 72 75 63 74 20 7b 0a 20 20 2f 2a 20 54 68  struct {.  /* Th
15e0: 65 20 70 4f 72 69 67 56 66 73 20 69 73 20 74 68  e pOrigVfs is th
15f0: 65 20 72 65 61 6c 2c 20 6f 72 69 67 69 6e 61 6c  e real, original
1600: 20 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20   underlying VFS 
1610: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a  implementation..
1620: 20 20 2a 2a 20 4d 6f 73 74 20 6f 70 65 72 61 74    ** Most operat
1630: 69 6f 6e 73 20 70 61 73 73 2d 74 68 72 6f 75 67  ions pass-throug
1640: 68 20 74 6f 20 74 68 65 20 72 65 61 6c 20 56 46  h to the real VF
1650: 53 2e 20 20 54 68 69 73 20 76 61 6c 75 65 20 69  S.  This value i
1660: 73 20 72 65 61 64 2d 6f 6e 6c 79 0a 20 20 2a 2a  s read-only.  **
1670: 20 64 75 72 69 6e 67 20 6f 70 65 72 61 74 69 6f   during operatio
1680: 6e 2e 20 20 49 74 20 69 73 20 6f 6e 6c 79 20 6d  n.  It is only m
1690: 6f 64 69 66 69 65 64 20 61 74 20 73 74 61 72 74  odified at start
16a0: 2d 74 69 6d 65 20 61 6e 64 20 74 68 75 73 20 64  -time and thus d
16b0: 6f 65 73 20 6e 6f 74 0a 20 20 2a 2a 20 72 65 71  oes not.  ** req
16c0: 75 69 72 65 20 61 20 6d 75 74 65 78 2e 0a 20 20  uire a mutex..  
16d0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  */.  sqlite3_vfs
16e0: 20 2a 70 4f 72 69 67 56 66 73 3b 0a 0a 20 20 2f   *pOrigVfs;..  /
16f0: 2a 20 54 68 65 20 73 54 68 69 73 56 66 73 20 69  * The sThisVfs i
1700: 73 20 74 68 65 20 56 46 53 20 73 74 72 75 63 74  s the VFS struct
1710: 75 72 65 20 75 73 65 64 20 62 79 20 74 68 69 73  ure used by this
1720: 20 73 68 69 6d 2e 20 20 49 74 20 69 73 20 69 6e   shim.  It is in
1730: 69 74 69 61 6c 69 7a 65 64 0a 20 20 2a 2a 20 61  itialized.  ** a
1740: 74 20 73 74 61 72 74 2d 74 69 6d 65 20 61 6e 64  t start-time and
1750: 20 74 68 75 73 20 64 6f 65 73 20 6e 6f 74 20 72   thus does not r
1760: 65 71 75 69 72 65 20 61 20 6d 75 74 65 78 0a 20  equire a mutex. 
1770: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66   */.  sqlite3_vf
1780: 73 20 73 54 68 69 73 56 66 73 3b 0a 0a 20 20 2f  s sThisVfs;..  /
1790: 2a 20 54 68 65 20 73 49 6f 4d 65 74 68 6f 64 73  * The sIoMethods
17a0: 20 64 65 66 69 6e 65 73 20 74 68 65 20 6d 65 74   defines the met
17b0: 68 6f 64 73 20 75 73 65 64 20 62 79 20 73 71 6c  hods used by sql
17c0: 69 74 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74  ite3_file object
17d0: 73 20 0a 20 20 2a 2a 20 61 73 73 6f 63 69 61 74  s .  ** associat
17e0: 65 64 20 77 69 74 68 20 74 68 69 73 20 73 68 69  ed with this shi
17f0: 6d 2e 20 20 49 74 20 69 73 20 69 6e 69 74 69 61  m.  It is initia
1800: 6c 69 7a 65 64 20 61 74 20 73 74 61 72 74 2d 74  lized at start-t
1810: 69 6d 65 20 61 6e 64 20 64 6f 65 73 0a 20 20 2a  ime and does.  *
1820: 2a 20 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20  * not require a 
1830: 6d 75 74 65 78 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  mutex..  **.  **
1840: 20 57 68 65 6e 20 74 68 65 20 75 6e 64 65 72 6c   When the underl
1850: 79 69 6e 67 20 56 46 53 20 69 73 20 63 61 6c 6c  ying VFS is call
1860: 65 64 20 74 6f 20 6f 70 65 6e 20 61 20 66 69 6c  ed to open a fil
1870: 65 2c 20 69 74 20 6d 69 67 68 74 20 72 65 74 75  e, it might retu
1880: 72 6e 20 0a 20 20 2a 2a 20 65 69 74 68 65 72 20  rn .  ** either 
1890: 61 20 76 65 72 73 69 6f 6e 20 31 20 6f 72 20 61  a version 1 or a
18a0: 20 76 65 72 73 69 6f 6e 20 32 20 73 71 6c 69 74   version 2 sqlit
18b0: 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74 2e 20  e3_file object. 
18c0: 20 54 68 69 73 20 73 68 69 6d 0a 20 20 2a 2a 20   This shim.  ** 
18d0: 68 61 73 20 74 6f 20 63 72 65 61 74 65 20 61 20  has to create a 
18e0: 77 72 61 70 70 65 72 20 73 71 6c 69 74 65 33 5f  wrapper sqlite3_
18f0: 66 69 6c 65 20 6f 66 20 74 68 65 20 73 61 6d 65  file of the same
1900: 20 76 65 72 73 69 6f 6e 2e 20 20 48 65 6e 63 65   version.  Hence
1910: 0a 20 20 2a 2a 20 74 68 65 72 65 20 61 72 65 20  .  ** there are 
1920: 74 77 6f 20 49 2f 4f 20 6d 65 74 68 6f 64 20 73  two I/O method s
1930: 74 72 75 63 74 75 72 65 73 2c 20 6f 6e 65 20 66  tructures, one f
1940: 6f 72 20 76 65 72 73 69 6f 6e 20 31 20 61 6e 64  or version 1 and
1950: 20 74 68 65 20 6f 74 68 65 72 0a 20 20 2a 2a 20   the other.  ** 
1960: 66 6f 72 20 76 65 72 73 69 6f 6e 20 32 2e 0a 20  for version 2.. 
1970: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6f   */.  sqlite3_io
1980: 5f 6d 65 74 68 6f 64 73 20 73 49 6f 4d 65 74 68  _methods sIoMeth
1990: 6f 64 73 56 31 3b 0a 20 20 73 71 6c 69 74 65 33  odsV1;.  sqlite3
19a0: 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 73 49 6f 4d  _io_methods sIoM
19b0: 65 74 68 6f 64 73 56 32 3b 0a 0a 20 20 2f 2a 20  ethodsV2;..  /* 
19c0: 54 72 75 65 20 77 68 65 6e 20 74 68 69 73 20 73  True when this s
19d0: 68 69 6d 20 68 61 73 20 62 65 65 6e 20 69 6e 69  him has been ini
19e0: 74 69 61 6c 69 7a 65 64 2e 0a 20 20 2a 2f 0a 20  tialized..  */. 
19f0: 20 69 6e 74 20 69 73 49 6e 69 74 69 61 6c 69 7a   int isInitializ
1a00: 65 64 3b 0a 7d 20 67 4d 75 6c 74 69 70 6c 65 78  ed;.} gMultiplex
1a10: 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ;../************
1a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 55 74  ************* Ut
1a30: 69 6c 69 74 79 20 52 6f 75 74 69 6e 65 73 20 2a  ility Routines *
1a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1a60: 2f 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20  /./*.** Compute 
1a70: 61 20 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  a string length 
1a80: 74 68 61 74 20 69 73 20 6c 69 6d 69 74 65 64 20  that is limited 
1a90: 74 6f 20 77 68 61 74 20 63 61 6e 20 62 65 20 73  to what can be s
1aa0: 74 6f 72 65 64 20 69 6e 0a 2a 2a 20 6c 6f 77 65  tored in.** lowe
1ab0: 72 20 33 30 20 62 69 74 73 20 6f 66 20 61 20 33  r 30 bits of a 3
1ac0: 32 2d 62 69 74 20 73 69 67 6e 65 64 20 69 6e 74  2-bit signed int
1ad0: 65 67 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  eger..**.** The 
1ae0: 76 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 77  value returned w
1af0: 69 6c 6c 20 6e 65 76 65 72 20 62 65 20 6e 65 67  ill never be neg
1b00: 61 74 69 76 65 2e 20 20 4e 6f 72 20 77 69 6c 6c  ative.  Nor will
1b10: 20 69 74 20 65 76 65 72 20 62 65 20 67 72 65 61   it ever be grea
1b20: 74 65 72 0a 2a 2a 20 74 68 61 6e 20 74 68 65 20  ter.** than the 
1b30: 61 63 74 75 61 6c 20 6c 65 6e 67 74 68 20 6f 66  actual length of
1b40: 20 74 68 65 20 73 74 72 69 6e 67 2e 20 20 46 6f   the string.  Fo
1b50: 72 20 76 65 72 79 20 6c 6f 6e 67 20 73 74 72 69  r very long stri
1b60: 6e 67 73 20 28 67 72 65 61 74 65 72 0a 2a 2a 20  ngs (greater.** 
1b70: 74 68 61 6e 20 31 47 69 42 29 20 74 68 65 20 76  than 1GiB) the v
1b80: 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 6d 69  alue returned mi
1b90: 67 68 74 20 62 65 20 6c 65 73 73 20 74 68 61 6e  ght be less than
1ba0: 20 74 68 65 20 74 72 75 65 20 73 74 72 69 6e 67   the true string
1bb0: 20 6c 65 6e 67 74 68 2e 0a 2a 2f 0a 73 74 61 74   length..*/.stat
1bc0: 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78  ic int multiplex
1bd0: 53 74 72 6c 65 6e 33 30 28 63 6f 6e 73 74 20 63  Strlen30(const c
1be0: 68 61 72 20 2a 7a 29 7b 0a 20 20 63 6f 6e 73 74  har *z){.  const
1bf0: 20 63 68 61 72 20 2a 7a 32 20 3d 20 7a 3b 0a 20   char *z2 = z;. 
1c00: 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74 75   if( z==0 ) retu
1c10: 72 6e 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 2a  rn 0;.  while( *
1c20: 7a 32 20 29 7b 20 7a 32 2b 2b 3b 20 7d 0a 20 20  z2 ){ z2++; }.  
1c30: 72 65 74 75 72 6e 20 30 78 33 66 66 66 66 66 66  return 0x3ffffff
1c40: 66 20 26 20 28 69 6e 74 29 28 7a 32 20 2d 20 7a  f & (int)(z2 - z
1c50: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65  );.}../*.** Gene
1c60: 72 61 74 65 20 74 68 65 20 66 69 6c 65 2d 6e 61  rate the file-na
1c70: 6d 65 20 66 6f 72 20 63 68 75 6e 6b 20 69 43 68  me for chunk iCh
1c80: 75 6e 6b 20 6f 66 20 74 68 65 20 67 72 6f 75 70  unk of the group
1c90: 20 77 69 74 68 20 62 61 73 65 20 6e 61 6d 65 0a   with base name.
1ca0: 2a 2a 20 7a 42 61 73 65 2e 20 54 68 65 20 66 69  ** zBase. The fi
1cb0: 6c 65 2d 6e 61 6d 65 20 69 73 20 77 72 69 74 74  le-name is writt
1cc0: 65 6e 20 74 6f 20 62 75 66 66 65 72 20 7a 4f 75  en to buffer zOu
1cd0: 74 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  t before returni
1ce0: 6e 67 2e 20 42 75 66 66 65 72 0a 2a 2a 20 7a 4f  ng. Buffer.** zO
1cf0: 75 74 20 6d 75 73 74 20 62 65 20 61 6c 6c 6f 63  ut must be alloc
1d00: 61 74 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c  ated by the call
1d10: 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 69 73  er so that it is
1d20: 20 61 74 20 6c 65 61 73 74 20 28 6e 42 61 73 65   at least (nBase
1d30: 2b 35 29 0a 2a 2a 20 62 79 74 65 73 20 69 6e 20  +5).** bytes in 
1d40: 73 69 7a 65 2c 20 77 68 65 72 65 20 6e 42 61 73  size, where nBas
1d50: 65 20 69 73 20 74 68 65 20 6c 65 6e 67 74 68 20  e is the length 
1d60: 6f 66 20 7a 42 61 73 65 2c 20 6e 6f 74 20 69 6e  of zBase, not in
1d70: 63 6c 75 64 69 6e 67 20 74 68 65 0a 2a 2a 20 6e  cluding the.** n
1d80: 75 6c 2d 74 65 72 6d 69 6e 61 74 6f 72 2e 0a 2a  ul-terminator..*
1d90: 2a 0a 2a 2a 20 49 66 20 69 43 68 75 6e 6b 20 69  *.** If iChunk i
1da0: 73 20 30 20 28 6f 72 20 34 30 30 20 2d 20 74 68  s 0 (or 400 - th
1db0: 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 74 68 65  e number for the
1dc0: 20 66 69 72 73 74 20 6a 6f 75 72 6e 61 6c 20 66   first journal f
1dd0: 69 6c 65 20 63 68 75 6e 6b 29 2c 0a 2a 2a 20 74  ile chunk),.** t
1de0: 68 65 20 6f 75 74 70 75 74 20 69 73 20 61 20 63  he output is a c
1df0: 6f 70 79 20 6f 66 20 74 68 65 20 69 6e 70 75 74  opy of the input
1e00: 20 73 74 72 69 6e 67 2e 20 4f 74 68 65 72 77 69   string. Otherwi
1e10: 73 65 2c 20 69 66 20 0a 2a 2a 20 53 51 4c 49 54  se, if .** SQLIT
1e20: 45 5f 45 4e 41 42 4c 45 5f 38 5f 33 5f 4e 41 4d  E_ENABLE_8_3_NAM
1e30: 45 53 20 69 73 20 6e 6f 74 20 64 65 66 69 6e 65  ES is not define
1e40: 64 20 6f 72 20 74 68 65 20 69 6e 70 75 74 20 62  d or the input b
1e50: 75 66 66 65 72 20 64 6f 65 73 20 6e 6f 74 20 63  uffer does not c
1e60: 6f 6e 74 61 69 6e 0a 2a 2a 20 61 20 22 2e 22 20  ontain.** a "." 
1e70: 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e 20  character, then 
1e80: 74 68 65 20 6f 75 74 70 75 74 20 69 73 20 61 20  the output is a 
1e90: 63 6f 70 79 20 6f 66 20 74 68 65 20 69 6e 70 75  copy of the inpu
1ea0: 74 20 73 74 72 69 6e 67 20 77 69 74 68 20 74 68  t string with th
1eb0: 65 20 0a 2a 2a 20 74 68 72 65 65 2d 64 69 67 69  e .** three-digi
1ec0: 74 20 7a 65 72 6f 2d 70 61 64 64 65 64 20 64 65  t zero-padded de
1ed0: 63 69 6d 61 6c 20 72 65 70 72 65 73 65 6e 74 61  cimal representa
1ee0: 74 69 6f 6e 20 69 66 20 69 43 68 75 6e 6b 20 61  tion if iChunk a
1ef0: 70 70 65 6e 64 65 64 20 74 6f 20 69 74 2e 20 0a  ppended to it. .
1f00: 2a 2a 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a  ** For example:.
1f10: 2a 2a 0a 2a 2a 20 20 20 7a 42 61 73 65 3d 22 74  **.**   zBase="t
1f20: 65 73 74 2e 64 62 22 2c 20 69 43 68 75 6e 6b 3d  est.db", iChunk=
1f30: 34 20 20 2d 3e 20 20 7a 4f 75 74 3d 22 74 65 73  4  ->  zOut="tes
1f40: 74 2e 64 62 30 30 34 22 0a 2a 2a 0a 2a 2a 20 4f  t.db004".**.** O
1f50: 72 2c 20 69 66 20 53 51 4c 49 54 45 5f 45 4e 41  r, if SQLITE_ENA
1f60: 42 4c 45 5f 38 5f 33 5f 4e 41 4d 45 53 20 69 73  BLE_8_3_NAMES is
1f70: 20 64 65 66 69 6e 65 64 20 61 6e 64 20 74 68 65   defined and the
1f80: 20 69 6e 70 75 74 20 62 75 66 66 65 72 20 63 6f   input buffer co
1f90: 6e 74 61 69 6e 73 0a 2a 2a 20 61 20 22 2e 22 20  ntains.** a "." 
1fa0: 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e 20  character, then 
1fb0: 65 76 65 72 79 74 68 69 6e 67 20 61 66 74 65 72  everything after
1fc0: 20 74 68 65 20 22 2e 22 20 69 73 20 72 65 70 6c   the "." is repl
1fd0: 61 63 65 64 20 62 79 20 74 68 65 20 0a 2a 2a 20  aced by the .** 
1fe0: 74 68 72 65 65 2d 64 69 67 69 74 20 72 65 70 72  three-digit repr
1ff0: 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 69 43  esentation of iC
2000: 68 75 6e 6b 2e 0a 2a 2a 0a 2a 2a 20 20 20 7a 42  hunk..**.**   zB
2010: 61 73 65 3d 22 74 65 73 74 2e 64 62 22 2c 20 69  ase="test.db", i
2020: 43 68 75 6e 6b 3d 34 20 20 2d 3e 20 20 7a 4f 75  Chunk=4  ->  zOu
2030: 74 3d 22 74 65 73 74 2e 30 30 34 22 0a 2a 2a 0a  t="test.004".**.
2040: 2a 2a 20 54 68 65 20 6f 75 74 70 75 74 20 62 75  ** The output bu
2050: 66 66 65 72 20 73 74 72 69 6e 67 20 69 73 20 74  ffer string is t
2060: 65 72 6d 69 6e 61 74 65 64 20 62 79 20 32 20 30  erminated by 2 0
2070: 78 30 30 20 62 79 74 65 73 2e 20 54 68 69 73 20  x00 bytes. This 
2080: 6d 61 6b 65 73 20 69 74 20 73 61 66 65 0a 2a 2a  makes it safe.**
2090: 20 74 6f 20 70 61 73 73 20 74 6f 20 73 71 6c 69   to pass to sqli
20a0: 74 65 33 5f 75 72 69 5f 70 61 72 61 6d 65 74 65  te3_uri_paramete
20b0: 72 28 29 20 61 6e 64 20 73 69 6d 69 6c 61 72 2e  r() and similar.
20c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
20d0: 6d 75 6c 74 69 70 6c 65 78 46 69 6c 65 6e 61 6d  multiplexFilenam
20e0: 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  e(.  const char 
20f0: 2a 7a 42 61 73 65 2c 20 20 20 20 20 20 20 20 20  *zBase,         
2100: 20 20 20 20 20 2f 2a 20 46 69 6c 65 6e 61 6d 65       /* Filename
2110: 20 66 6f 72 20 63 68 75 6e 6b 20 30 20 2a 2f 0a   for chunk 0 */.
2120: 20 20 69 6e 74 20 6e 42 61 73 65 2c 20 20 20 20    int nBase,    
2130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2140: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 42 61    /* Size of zBa
2150: 73 65 20 69 6e 20 62 79 74 65 73 20 28 77 69 74  se in bytes (wit
2160: 68 6f 75 74 20 5c 30 29 20 2a 2f 0a 20 20 69 6e  hout \0) */.  in
2170: 74 20 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20  t flags,        
2180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2190: 20 46 6c 61 67 73 20 75 73 65 64 20 74 6f 20 6f   Flags used to o
21a0: 70 65 6e 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  pen file */.  in
21b0: 74 20 69 43 68 75 6e 6b 2c 20 20 20 20 20 20 20  t iChunk,       
21c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21d0: 20 43 68 75 6e 6b 20 74 6f 20 67 65 6e 65 72 61   Chunk to genera
21e0: 74 65 20 66 69 6c 65 6e 61 6d 65 20 66 6f 72 20  te filename for 
21f0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 20  */.  char *zOut 
2200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2210: 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74       /* Buffer t
2220: 6f 20 77 72 69 74 65 20 67 65 6e 65 72 61 74 65  o write generate
2230: 64 20 6e 61 6d 65 20 74 6f 20 2a 2f 0a 29 7b 0a  d name to */.){.
2240: 20 20 69 6e 74 20 6e 20 3d 20 6e 42 61 73 65 3b    int n = nBase;
2250: 0a 20 20 6d 65 6d 63 70 79 28 7a 4f 75 74 2c 20  .  memcpy(zOut, 
2260: 7a 42 61 73 65 2c 20 6e 2b 31 29 3b 0a 20 20 69  zBase, n+1);.  i
2270: 66 28 20 69 43 68 75 6e 6b 21 3d 30 20 26 26 20  f( iChunk!=0 && 
2280: 69 43 68 75 6e 6b 3c 3d 4d 58 5f 43 48 55 4e 4b  iChunk<=MX_CHUNK
2290: 5f 4e 55 4d 42 45 52 20 29 7b 0a 23 69 66 64 65  _NUMBER ){.#ifde
22a0: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
22b0: 38 5f 33 5f 4e 41 4d 45 53 0a 20 20 20 20 69 6e  8_3_NAMES.    in
22c0: 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 6e  t i;.    for(i=n
22d0: 2d 31 3b 20 69 3e 30 20 26 26 20 69 3e 3d 6e 2d  -1; i>0 && i>=n-
22e0: 34 20 26 26 20 7a 4f 75 74 5b 69 5d 21 3d 27 2e  4 && zOut[i]!='.
22f0: 27 3b 20 69 2d 2d 29 7b 7d 0a 20 20 20 20 69 66  '; i--){}.    if
2300: 28 20 69 3e 3d 6e 2d 34 20 29 20 6e 20 3d 20 69  ( i>=n-4 ) n = i
2310: 2b 31 3b 0a 20 20 20 20 69 66 28 20 66 6c 61 67  +1;.    if( flag
2320: 73 20 26 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  s & SQLITE_OPEN_
2330: 4d 41 49 4e 5f 4a 4f 55 52 4e 41 4c 20 29 7b 0a  MAIN_JOURNAL ){.
2340: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 65 78 74        /* The ext
2350: 65 6e 73 69 6f 6e 73 20 6f 6e 20 6f 76 65 72 66  ensions on overf
2360: 6c 6f 77 20 66 69 6c 65 73 20 66 6f 72 20 6d 61  low files for ma
2370: 69 6e 20 64 61 74 61 62 61 73 65 73 20 61 72 65  in databases are
2380: 20 30 30 31 2c 20 30 30 32 2c 0a 20 20 20 20 20   001, 002,.     
2390: 20 2a 2a 20 30 30 33 20 61 6e 64 20 73 6f 20 66   ** 003 and so f
23a0: 6f 72 74 68 2e 20 20 54 6f 20 61 76 6f 69 64 20  orth.  To avoid 
23b0: 6e 61 6d 65 20 63 6f 6c 6c 69 73 69 6f 6e 73 2c  name collisions,
23c0: 20 61 64 64 20 34 30 30 20 74 6f 20 74 68 65 20   add 400 to the 
23d0: 0a 20 20 20 20 20 20 2a 2a 20 65 78 74 65 6e 73  .      ** extens
23e0: 69 6f 6e 73 20 6f 66 20 6a 6f 75 72 6e 61 6c 20  ions of journal 
23f0: 66 69 6c 65 73 20 73 6f 20 74 68 61 74 20 74 68  files so that th
2400: 65 79 20 61 72 65 20 34 30 31 2c 20 34 30 32 2c  ey are 401, 402,
2410: 20 34 30 33 2c 20 2e 2e 2e 2e 0a 20 20 20 20 20   403, .....     
2420: 20 2a 2f 0a 20 20 20 20 20 20 69 43 68 75 6e 6b   */.      iChunk
2430: 20 2b 3d 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49   += SQLITE_MULTI
2440: 50 4c 45 58 5f 4a 4f 55 52 4e 41 4c 5f 38 5f 33  PLEX_JOURNAL_8_3
2450: 5f 4f 46 46 53 45 54 3b 0a 20 20 20 20 7d 65 6c  _OFFSET;.    }el
2460: 73 65 20 69 66 28 20 66 6c 61 67 73 20 26 20 53  se if( flags & S
2470: 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 20 29  QLITE_OPEN_WAL )
2480: 7b 0a 20 20 20 20 20 20 2f 2a 20 54 6f 20 61 76  {.      /* To av
2490: 6f 69 64 20 6e 61 6d 65 20 63 6f 6c 6c 69 73 69  oid name collisi
24a0: 6f 6e 73 2c 20 61 64 64 20 37 30 30 20 74 6f 20  ons, add 700 to 
24b0: 74 68 65 20 0a 20 20 20 20 20 20 2a 2a 20 65 78  the .      ** ex
24c0: 74 65 6e 73 69 6f 6e 73 20 6f 66 20 57 41 4c 20  tensions of WAL 
24d0: 66 69 6c 65 73 20 73 6f 20 74 68 61 74 20 74 68  files so that th
24e0: 65 79 20 61 72 65 20 37 30 31 2c 20 37 30 32 2c  ey are 701, 702,
24f0: 20 37 30 33 2c 20 2e 2e 2e 2e 0a 20 20 20 20 20   703, .....     
2500: 20 2a 2f 0a 20 20 20 20 20 20 69 43 68 75 6e 6b   */.      iChunk
2510: 20 2b 3d 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49   += SQLITE_MULTI
2520: 50 4c 45 58 5f 57 41 4c 5f 38 5f 33 5f 4f 46 46  PLEX_WAL_8_3_OFF
2530: 53 45 54 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69  SET;.    }.#endi
2540: 66 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e  f.    sqlite3_sn
2550: 70 72 69 6e 74 66 28 34 2c 26 7a 4f 75 74 5b 6e  printf(4,&zOut[n
2560: 5d 2c 22 25 30 33 64 22 2c 69 43 68 75 6e 6b 29  ],"%03d",iChunk)
2570: 3b 0a 20 20 20 20 6e 20 2b 3d 20 33 3b 0a 20 20  ;.    n += 3;.  
2580: 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 7a 4f 75  }..  assert( zOu
2590: 74 5b 6e 5d 3d 3d 27 5c 30 27 20 29 3b 0a 20 20  t[n]=='\0' );.  
25a0: 7a 4f 75 74 5b 6e 2b 31 5d 20 3d 20 27 5c 30 27  zOut[n+1] = '\0'
25b0: 3b 0a 7d 0a 0a 2f 2a 20 43 6f 6d 70 75 74 65 20  ;.}../* Compute 
25c0: 74 68 65 20 66 69 6c 65 6e 61 6d 65 20 66 6f 72  the filename for
25d0: 20 74 68 65 20 69 43 68 75 6e 6b 2d 74 68 20 63   the iChunk-th c
25e0: 68 75 6e 6b 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hunk.*/.static i
25f0: 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 46  nt multiplexSubF
2600: 69 6c 65 6e 61 6d 65 28 6d 75 6c 74 69 70 6c 65  ilename(multiple
2610: 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 2c 20  xGroup *pGroup, 
2620: 69 6e 74 20 69 43 68 75 6e 6b 29 7b 0a 20 20 69  int iChunk){.  i
2630: 66 28 20 69 43 68 75 6e 6b 3e 3d 70 47 72 6f 75  f( iChunk>=pGrou
2640: 70 2d 3e 6e 52 65 61 6c 20 29 7b 0a 20 20 20 20  p->nReal ){.    
2650: 73 74 72 75 63 74 20 6d 75 6c 74 69 70 6c 65 78  struct multiplex
2660: 52 65 61 6c 20 2a 70 3b 0a 20 20 20 20 70 20 3d  Real *p;.    p =
2670: 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63   sqlite3_realloc
2680: 36 34 28 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c  64(pGroup->aReal
2690: 2c 20 28 69 43 68 75 6e 6b 2b 31 29 2a 73 69 7a  , (iChunk+1)*siz
26a0: 65 6f 66 28 2a 70 29 29 3b 0a 20 20 20 20 69 66  eof(*p));.    if
26b0: 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ( p==0 ){.      
26c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
26d0: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d  MEM;.    }.    m
26e0: 65 6d 73 65 74 28 26 70 5b 70 47 72 6f 75 70 2d  emset(&p[pGroup-
26f0: 3e 6e 52 65 61 6c 5d 2c 20 30 2c 20 73 69 7a 65  >nReal], 0, size
2700: 6f 66 28 70 5b 30 5d 29 2a 28 69 43 68 75 6e 6b  of(p[0])*(iChunk
2710: 2b 31 2d 70 47 72 6f 75 70 2d 3e 6e 52 65 61 6c  +1-pGroup->nReal
2720: 29 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  ));.    pGroup->
2730: 61 52 65 61 6c 20 3d 20 70 3b 0a 20 20 20 20 70  aReal = p;.    p
2740: 47 72 6f 75 70 2d 3e 6e 52 65 61 6c 20 3d 20 69  Group->nReal = i
2750: 43 68 75 6e 6b 2b 31 3b 0a 20 20 7d 0a 20 20 69  Chunk+1;.  }.  i
2760: 66 28 20 70 47 72 6f 75 70 2d 3e 7a 4e 61 6d 65  f( pGroup->zName
2770: 20 26 26 20 70 47 72 6f 75 70 2d 3e 61 52 65 61   && pGroup->aRea
2780: 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 3d 3d 30 20 29  l[iChunk].z==0 )
2790: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 3b 0a 20  {.    char *z;. 
27a0: 20 20 20 69 6e 74 20 6e 20 3d 20 70 47 72 6f 75     int n = pGrou
27b0: 70 2d 3e 6e 4e 61 6d 65 3b 0a 20 20 20 20 70 47  p->nName;.    pG
27c0: 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75  roup->aReal[iChu
27d0: 6e 6b 5d 2e 7a 20 3d 20 7a 20 3d 20 73 71 6c 69  nk].z = z = sqli
27e0: 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 20 6e 2b  te3_malloc64( n+
27f0: 35 20 29 3b 0a 20 20 20 20 69 66 28 20 7a 3d 3d  5 );.    if( z==
2800: 30 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  0 ){.      retur
2810: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2820: 20 20 20 20 7d 0a 20 20 20 20 6d 75 6c 74 69 70      }.    multip
2830: 6c 65 78 46 69 6c 65 6e 61 6d 65 28 70 47 72 6f  lexFilename(pGro
2840: 75 70 2d 3e 7a 4e 61 6d 65 2c 20 70 47 72 6f 75  up->zName, pGrou
2850: 70 2d 3e 6e 4e 61 6d 65 2c 20 70 47 72 6f 75 70  p->nName, pGroup
2860: 2d 3e 66 6c 61 67 73 2c 20 69 43 68 75 6e 6b 2c  ->flags, iChunk,
2870: 20 7a 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72   z);.  }.  retur
2880: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
2890: 2f 2a 20 54 72 61 6e 73 6c 61 74 65 20 61 6e 20  /* Translate an 
28a0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 20 74 68  sqlite3_file* th
28b0: 61 74 20 69 73 20 72 65 61 6c 6c 79 20 61 20 6d  at is really a m
28c0: 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 2a 20 69  ultiplexGroup* i
28d0: 6e 74 6f 0a 2a 2a 20 74 68 65 20 73 71 6c 69 74  nto.** the sqlit
28e0: 65 33 5f 66 69 6c 65 2a 20 66 6f 72 20 74 68 65  e3_file* for the
28f0: 20 75 6e 64 65 72 6c 79 69 6e 67 20 6f 72 69 67   underlying orig
2900: 69 6e 61 6c 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20  inal VFS..**.** 
2910: 46 6f 72 20 63 68 75 6e 6b 20 30 2c 20 74 68 65  For chunk 0, the
2920: 20 70 47 72 6f 75 70 2d 3e 66 6c 61 67 73 20 64   pGroup->flags d
2930: 65 74 65 72 6d 69 6e 65 73 20 77 68 65 74 68 65  etermines whethe
2940: 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65 77 20 66  r or not a new f
2950: 69 6c 65 0a 2a 2a 20 69 73 20 63 72 65 61 74 65  ile.** is create
2960: 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74  d if it does not
2970: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 2e 20   already exist. 
2980: 20 46 6f 72 20 63 68 75 6e 6b 73 20 31 20 61 6e   For chunks 1 an
2990: 64 20 68 69 67 68 65 72 2c 20 74 68 65 0a 2a 2a  d higher, the.**
29a0: 20 66 69 6c 65 20 69 73 20 63 72 65 61 74 65 64   file is created
29b0: 20 6f 6e 6c 79 20 69 66 20 63 72 65 61 74 65 46   only if createF
29c0: 6c 61 67 20 69 73 20 31 2e 0a 2a 2f 0a 73 74 61  lag is 1..*/.sta
29d0: 74 69 63 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  tic sqlite3_file
29e0: 20 2a 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70   *multiplexSubOp
29f0: 65 6e 28 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47  en(.  multiplexG
2a00: 72 6f 75 70 20 2a 70 47 72 6f 75 70 2c 20 20 20  roup *pGroup,   
2a10: 20 2f 2a 20 54 68 65 20 6d 75 6c 74 69 70 6c 65   /* The multiple
2a20: 78 6f 72 20 67 72 6f 75 70 20 2a 2f 0a 20 20 69  xor group */.  i
2a30: 6e 74 20 69 43 68 75 6e 6b 2c 20 20 20 20 20 20  nt iChunk,      
2a40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 68 69            /* Whi
2a50: 63 68 20 63 68 75 6e 6b 20 74 6f 20 6f 70 65 6e  ch chunk to open
2a60: 2e 20 20 30 3d 3d 6f 72 69 67 69 6e 61 6c 20 66  .  0==original f
2a70: 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 72 63  ile */.  int *rc
2a80: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2a90: 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f      /* Result co
2aa0: 64 65 20 69 6e 20 61 6e 64 20 6f 75 74 20 2a 2f  de in and out */
2ab0: 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67  .  int *pOutFlag
2ac0: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  s,            /*
2ad0: 20 4f 75 74 70 75 74 20 66 6c 61 67 73 20 2a 2f   Output flags */
2ae0: 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46 6c 61  .  int createFla
2af0: 67 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  g             /*
2b00: 20 54 72 75 65 20 74 6f 20 63 72 65 61 74 65 20   True to create 
2b10: 69 66 20 69 43 68 75 6e 6b 3e 30 20 2a 2f 0a 29  if iChunk>0 */.)
2b20: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  {.  sqlite3_file
2b30: 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 30 3b 0a   *pSubOpen = 0;.
2b40: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70    sqlite3_vfs *p
2b50: 4f 72 69 67 56 66 73 20 3d 20 67 4d 75 6c 74 69  OrigVfs = gMulti
2b60: 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 3b 20 20  plex.pOrigVfs;  
2b70: 20 20 20 20 20 20 2f 2a 20 52 65 61 6c 20 56 46        /* Real VF
2b80: 53 20 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c  S */..#ifdef SQL
2b90: 49 54 45 5f 45 4e 41 42 4c 45 5f 38 5f 33 5f 4e  ITE_ENABLE_8_3_N
2ba0: 41 4d 45 53 0a 20 20 2f 2a 20 49 66 20 4a 4f 55  AMES.  /* If JOU
2bb0: 52 4e 41 4c 5f 38 5f 33 5f 4f 46 46 53 45 54 20  RNAL_8_3_OFFSET 
2bc0: 69 73 20 73 65 74 20 74 6f 20 28 73 61 79 29 20  is set to (say) 
2bd0: 34 30 30 2c 20 74 68 65 6e 20 61 6e 79 20 6f 76  400, then any ov
2be0: 65 72 66 6c 6f 77 20 66 69 6c 65 73 20 61 72 65  erflow files are
2bf0: 20 0a 20 20 2a 2a 20 70 61 72 74 20 6f 66 20 61   .  ** part of a
2c00: 20 64 61 74 61 62 61 73 65 20 6a 6f 75 72 6e 61   database journa
2c10: 6c 20 61 72 65 20 6e 61 6d 65 64 20 64 62 2e 34  l are named db.4
2c20: 30 31 2c 20 64 62 2e 34 30 32 2c 20 61 6e 64 20  01, db.402, and 
2c30: 73 6f 20 6f 6e 2e 20 41 20 0a 20 20 2a 2a 20 64  so on. A .  ** d
2c40: 61 74 61 62 61 73 65 20 6d 61 79 20 74 68 65 72  atabase may ther
2c50: 65 66 6f 72 65 20 6e 6f 74 20 67 72 6f 77 20 74  efore not grow t
2c60: 6f 20 6c 61 72 67 65 72 20 74 68 61 6e 20 34 30  o larger than 40
2c70: 30 20 63 68 75 6e 6b 73 2e 20 41 74 74 65 6d 70  0 chunks. Attemp
2c80: 74 69 6e 67 0a 20 20 2a 2a 20 74 6f 20 6f 70 65  ting.  ** to ope
2c90: 6e 20 63 68 75 6e 6b 20 34 30 31 20 69 6e 64 69  n chunk 401 indi
2ca0: 63 61 74 65 73 20 74 68 65 20 64 61 74 61 62 61  cates the databa
2cb0: 73 65 20 69 73 20 66 75 6c 6c 2e 20 2a 2f 0a 20  se is full. */. 
2cc0: 20 69 66 28 20 69 43 68 75 6e 6b 3e 3d 53 51 4c   if( iChunk>=SQL
2cd0: 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f 4a 4f  ITE_MULTIPLEX_JO
2ce0: 55 52 4e 41 4c 5f 38 5f 33 5f 4f 46 46 53 45 54  URNAL_8_3_OFFSET
2cf0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
2d00: 6c 6f 67 28 53 51 4c 49 54 45 5f 46 55 4c 4c 2c  log(SQLITE_FULL,
2d10: 20 22 6d 75 6c 74 69 70 6c 65 78 65 64 20 63 68   "multiplexed ch
2d20: 75 6e 6b 20 6f 76 65 72 66 6c 6f 77 3a 20 25 73  unk overflow: %s
2d30: 22 2c 20 70 47 72 6f 75 70 2d 3e 7a 4e 61 6d 65  ", pGroup->zName
2d40: 29 3b 0a 20 20 20 20 2a 72 63 20 3d 20 53 51 4c  );.    *rc = SQL
2d50: 49 54 45 5f 46 55 4c 4c 3b 0a 20 20 20 20 72 65  ITE_FULL;.    re
2d60: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 23 65 6e 64  turn 0;.  }.#end
2d70: 69 66 0a 0a 20 20 2a 72 63 20 3d 20 6d 75 6c 74  if..  *rc = mult
2d80: 69 70 6c 65 78 53 75 62 46 69 6c 65 6e 61 6d 65  iplexSubFilename
2d90: 28 70 47 72 6f 75 70 2c 20 69 43 68 75 6e 6b 29  (pGroup, iChunk)
2da0: 3b 0a 20 20 69 66 28 20 28 2a 72 63 29 3d 3d 53  ;.  if( (*rc)==S
2db0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 28 70 53 75  QLITE_OK && (pSu
2dc0: 62 4f 70 65 6e 20 3d 20 70 47 72 6f 75 70 2d 3e  bOpen = pGroup->
2dd0: 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 70 29  aReal[iChunk].p)
2de0: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 66  ==0 ){.    int f
2df0: 6c 61 67 73 2c 20 62 45 78 69 73 74 73 3b 0a 20  lags, bExists;. 
2e00: 20 20 20 66 6c 61 67 73 20 3d 20 70 47 72 6f 75     flags = pGrou
2e10: 70 2d 3e 66 6c 61 67 73 3b 0a 20 20 20 20 69 66  p->flags;.    if
2e20: 28 20 63 72 65 61 74 65 46 6c 61 67 20 29 7b 0a  ( createFlag ){.
2e30: 20 20 20 20 20 20 66 6c 61 67 73 20 7c 3d 20 53        flags |= S
2e40: 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54  QLITE_OPEN_CREAT
2e50: 45 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  E;.    }else if(
2e60: 20 69 43 68 75 6e 6b 3d 3d 30 20 29 7b 0a 20 20   iChunk==0 ){.  
2e70: 20 20 20 20 2f 2a 20 46 61 6c 6c 20 74 68 72 6f      /* Fall thro
2e80: 75 67 68 20 2a 2f 0a 20 20 20 20 7d 65 6c 73 65  ugh */.    }else
2e90: 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 61 52 65   if( pGroup->aRe
2ea0: 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 3d 3d 30 20  al[iChunk].z==0 
2eb0: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
2ec0: 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  0;.    }else{.  
2ed0: 20 20 20 20 2a 72 63 20 3d 20 70 4f 72 69 67 56      *rc = pOrigV
2ee0: 66 73 2d 3e 78 41 63 63 65 73 73 28 70 4f 72 69  fs->xAccess(pOri
2ef0: 67 56 66 73 2c 20 70 47 72 6f 75 70 2d 3e 61 52  gVfs, pGroup->aR
2f00: 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 2c 0a 20  eal[iChunk].z,. 
2f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
2f30: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
2f40: 53 2c 20 26 62 45 78 69 73 74 73 29 3b 0a 20 20  S, &bExists);.  
2f50: 20 20 20 69 66 28 20 2a 72 63 20 7c 7c 20 21 62     if( *rc || !b
2f60: 45 78 69 73 74 73 20 29 7b 0a 20 20 20 20 20 20  Exists ){.      
2f70: 20 20 69 66 28 20 2a 72 63 20 29 7b 0a 20 20 20    if( *rc ){.   
2f80: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c         sqlite3_l
2f90: 6f 67 28 2a 72 63 2c 20 22 6d 75 6c 74 69 70 6c  og(*rc, "multipl
2fa0: 65 78 6f 72 2e 78 41 63 63 65 73 73 20 66 61 69  exor.xAccess fai
2fb0: 6c 75 72 65 20 6f 6e 20 25 73 22 2c 0a 20 20 20  lure on %s",.   
2fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fd0: 20 20 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c     pGroup->aReal
2fe0: 5b 69 43 68 75 6e 6b 5d 2e 7a 29 3b 0a 20 20 20  [iChunk].z);.   
2ff0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72       }.        r
3000: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d  eturn 0;.      }
3010: 0a 20 20 20 20 20 20 66 6c 61 67 73 20 26 3d 20  .      flags &= 
3020: 7e 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45  ~SQLITE_OPEN_CRE
3030: 41 54 45 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  ATE;.    }.    p
3040: 53 75 62 4f 70 65 6e 20 3d 20 73 71 6c 69 74 65  SubOpen = sqlite
3050: 33 5f 6d 61 6c 6c 6f 63 36 34 28 20 70 4f 72 69  3_malloc64( pOri
3060: 67 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20 29  gVfs->szOsFile )
3070: 3b 0a 20 20 20 20 69 66 28 20 70 53 75 62 4f 70  ;.    if( pSubOp
3080: 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a  en==0 ){.      *
3090: 72 63 20 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52  rc = SQLITE_IOER
30a0: 52 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 72  R_NOMEM;.      r
30b0: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20  eturn 0;.    }. 
30c0: 20 20 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c     pGroup->aReal
30d0: 5b 69 43 68 75 6e 6b 5d 2e 70 20 3d 20 70 53 75  [iChunk].p = pSu
30e0: 62 4f 70 65 6e 3b 0a 20 20 20 20 2a 72 63 20 3d  bOpen;.    *rc =
30f0: 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f 70 65 6e   pOrigVfs->xOpen
3100: 28 70 4f 72 69 67 56 66 73 2c 20 70 47 72 6f 75  (pOrigVfs, pGrou
3110: 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d  p->aReal[iChunk]
3120: 2e 7a 2c 20 70 53 75 62 4f 70 65 6e 2c 0a 20 20  .z, pSubOpen,.  
3130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3140: 20 20 20 20 20 20 20 20 66 6c 61 67 73 2c 20 70          flags, p
3150: 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 20 20 69  OutFlags);.    i
3160: 66 28 20 28 2a 72 63 29 21 3d 53 51 4c 49 54 45  f( (*rc)!=SQLITE
3170: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  _OK ){.      sql
3180: 69 74 65 33 5f 6c 6f 67 28 2a 72 63 2c 20 22 6d  ite3_log(*rc, "m
3190: 75 6c 74 69 70 6c 65 78 6f 72 2e 78 4f 70 65 6e  ultiplexor.xOpen
31a0: 20 66 61 69 6c 75 72 65 20 6f 6e 20 25 73 22 2c   failure on %s",
31b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
31c0: 20 20 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c     pGroup->aReal
31d0: 5b 69 43 68 75 6e 6b 5d 2e 7a 29 3b 0a 20 20 20  [iChunk].z);.   
31e0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
31f0: 70 53 75 62 4f 70 65 6e 29 3b 0a 20 20 20 20 20  pSubOpen);.     
3200: 20 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69   pGroup->aReal[i
3210: 43 68 75 6e 6b 5d 2e 70 20 3d 20 30 3b 0a 20 20  Chunk].p = 0;.  
3220: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
3230: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
3240: 20 70 53 75 62 4f 70 65 6e 3b 0a 7d 0a 0a 2f 2a   pSubOpen;.}../*
3250: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73  .** Return the s
3260: 69 7a 65 2c 20 69 6e 20 62 79 74 65 73 2c 20 6f  ize, in bytes, o
3270: 66 20 63 68 75 6e 6b 20 6e 75 6d 62 65 72 20 69  f chunk number i
3280: 43 68 75 6e 6b 2e 20 20 49 66 20 74 68 61 74 20  Chunk.  If that 
3290: 63 68 75 6e 6b 0a 2a 2a 20 64 6f 65 73 20 6e 6f  chunk.** does no
32a0: 74 20 65 78 69 73 74 2c 20 74 68 65 6e 20 72 65  t exist, then re
32b0: 74 75 72 6e 20 30 2e 20 20 54 68 69 73 20 66 75  turn 0.  This fu
32c0: 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74 20  nction does not 
32d0: 64 69 73 74 69 6e 67 69 73 68 20 62 65 74 77 65  distingish betwe
32e0: 65 6e 0a 2a 2a 20 6e 6f 6e 2d 65 78 69 73 74 61  en.** non-exista
32f0: 6e 74 20 66 69 6c 65 73 20 61 6e 64 20 7a 65 72  nt files and zer
3300: 6f 2d 6c 65 6e 67 74 68 20 66 69 6c 65 73 2e 0a  o-length files..
3310: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
3320: 33 5f 69 6e 74 36 34 20 6d 75 6c 74 69 70 6c 65  3_int64 multiple
3330: 78 53 75 62 53 69 7a 65 28 0a 20 20 6d 75 6c 74  xSubSize(.  mult
3340: 69 70 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f  iplexGroup *pGro
3350: 75 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 6d 75  up,    /* The mu
3360: 6c 74 69 70 6c 65 78 6f 72 20 67 72 6f 75 70 20  ltiplexor group 
3370: 2a 2f 0a 20 20 69 6e 74 20 69 43 68 75 6e 6b 2c  */.  int iChunk,
3380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3390: 2f 2a 20 57 68 69 63 68 20 63 68 75 6e 6b 20 74  /* Which chunk t
33a0: 6f 20 6f 70 65 6e 2e 20 20 30 3d 3d 6f 72 69 67  o open.  0==orig
33b0: 69 6e 61 6c 20 66 69 6c 65 20 2a 2f 0a 20 20 69  inal file */.  i
33c0: 6e 74 20 2a 72 63 20 20 20 20 20 20 20 20 20 20  nt *rc          
33d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73            /* Res
33e0: 75 6c 74 20 63 6f 64 65 20 69 6e 20 61 6e 64 20  ult code in and 
33f0: 6f 75 74 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  out */.){.  sqli
3400: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 3b 0a  te3_file *pSub;.
3410: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
3420: 73 7a 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 2a  sz = 0;..  if( *
3430: 72 63 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  rc ) return 0;. 
3440: 20 70 53 75 62 20 3d 20 6d 75 6c 74 69 70 6c 65   pSub = multiple
3450: 78 53 75 62 4f 70 65 6e 28 70 47 72 6f 75 70 2c  xSubOpen(pGroup,
3460: 20 69 43 68 75 6e 6b 2c 20 72 63 2c 20 4e 55 4c   iChunk, rc, NUL
3470: 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 53 75  L, 0);.  if( pSu
3480: 62 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  b==0 ) return 0;
3490: 0a 20 20 2a 72 63 20 3d 20 70 53 75 62 2d 3e 70  .  *rc = pSub->p
34a0: 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69  Methods->xFileSi
34b0: 7a 65 28 70 53 75 62 2c 20 26 73 7a 29 3b 0a 20  ze(pSub, &sz);. 
34c0: 20 72 65 74 75 72 6e 20 73 7a 3b 0a 7d 20 20 20   return sz;.}   
34d0: 20 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73   ../*.** This is
34e0: 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74   the implementat
34f0: 69 6f 6e 20 6f 66 20 74 68 65 20 6d 75 6c 74 69  ion of the multi
3500: 70 6c 65 78 5f 63 6f 6e 74 72 6f 6c 28 29 20 53  plex_control() S
3510: 51 4c 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  QL function..*/.
3520: 73 74 61 74 69 63 20 76 6f 69 64 20 6d 75 6c 74  static void mult
3530: 69 70 6c 65 78 43 6f 6e 74 72 6f 6c 46 75 6e 63  iplexControlFunc
3540: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  (.  sqlite3_cont
3550: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20  ext *context,.  
3560: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
3570: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
3580: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
3590: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 73 71 6c 69  QLITE_OK;.  sqli
35a0: 74 65 33 20 2a 64 62 20 3d 20 73 71 6c 69 74 65  te3 *db = sqlite
35b0: 33 5f 63 6f 6e 74 65 78 74 5f 64 62 5f 68 61 6e  3_context_db_han
35c0: 64 6c 65 28 63 6f 6e 74 65 78 74 29 3b 0a 20 20  dle(context);.  
35d0: 69 6e 74 20 6f 70 20 3d 20 30 3b 0a 20 20 69 6e  int op = 0;.  in
35e0: 74 20 69 56 61 6c 3b 0a 0a 20 20 69 66 28 20 21  t iVal;..  if( !
35f0: 64 62 20 7c 7c 20 61 72 67 63 21 3d 32 20 29 7b  db || argc!=2 ){
3600: 20 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54   .    rc = SQLIT
3610: 45 5f 45 52 52 4f 52 3b 20 0a 20 20 7d 65 6c 73  E_ERROR; .  }els
3620: 65 7b 0a 20 20 20 20 2f 2a 20 65 78 74 72 61 63  e{.    /* extrac
3630: 74 20 70 61 72 61 6d 73 20 2a 2f 0a 20 20 20 20  t params */.    
3640: 6f 70 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  op = sqlite3_val
3650: 75 65 5f 69 6e 74 28 61 72 67 76 5b 30 5d 29 3b  ue_int(argv[0]);
3660: 0a 20 20 20 20 69 56 61 6c 20 3d 20 73 71 6c 69  .    iVal = sqli
3670: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72  te3_value_int(ar
3680: 67 76 5b 31 5d 29 3b 0a 20 20 20 20 2f 2a 20 6d  gv[1]);.    /* m
3690: 61 70 20 66 75 6e 63 74 69 6f 6e 20 6f 70 20 74  ap function op t
36a0: 6f 20 66 69 6c 65 5f 63 6f 6e 74 72 6f 6c 20 6f  o file_control o
36b0: 70 20 2a 2f 0a 20 20 20 20 73 77 69 74 63 68 28  p */.    switch(
36c0: 20 6f 70 20 29 7b 0a 20 20 20 20 20 20 63 61 73   op ){.      cas
36d0: 65 20 31 3a 20 0a 20 20 20 20 20 20 20 20 6f 70  e 1: .        op
36e0: 20 3d 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54 52   = MULTIPLEX_CTR
36f0: 4c 5f 45 4e 41 42 4c 45 3b 20 0a 20 20 20 20 20  L_ENABLE; .     
3700: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
3710: 63 61 73 65 20 32 3a 20 0a 20 20 20 20 20 20 20  case 2: .       
3720: 20 6f 70 20 3d 20 4d 55 4c 54 49 50 4c 45 58 5f   op = MULTIPLEX_
3730: 43 54 52 4c 5f 53 45 54 5f 43 48 55 4e 4b 5f 53  CTRL_SET_CHUNK_S
3740: 49 5a 45 3b 20 0a 20 20 20 20 20 20 20 20 62 72  IZE; .        br
3750: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20  eak;.      case 
3760: 33 3a 20 0a 20 20 20 20 20 20 20 20 6f 70 20 3d  3: .        op =
3770: 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54 52 4c 5f   MULTIPLEX_CTRL_
3780: 53 45 54 5f 4d 41 58 5f 43 48 55 4e 4b 53 3b 20  SET_MAX_CHUNKS; 
3790: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
37a0: 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20        default:. 
37b0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
37c0: 54 45 5f 4e 4f 54 46 4f 55 4e 44 3b 0a 20 20 20  TE_NOTFOUND;.   
37d0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
37e0: 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d  }.  }.  if( rc==
37f0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
3800: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
3810: 6c 65 5f 63 6f 6e 74 72 6f 6c 28 64 62 2c 20 30  le_control(db, 0
3820: 2c 20 6f 70 2c 20 26 69 56 61 6c 29 3b 0a 20 20  , op, &iVal);.  
3830: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75  }.  sqlite3_resu
3840: 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65 28 63 6f  lt_error_code(co
3850: 6e 74 65 78 74 2c 20 72 63 29 3b 0a 7d 0a 0a 2f  ntext, rc);.}../
3860: 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65  *.** This is the
3870: 20 65 6e 74 72 79 20 70 6f 69 6e 74 20 74 6f 20   entry point to 
3880: 72 65 67 69 73 74 65 72 20 74 68 65 20 61 75 74  register the aut
3890: 6f 2d 65 78 74 65 6e 73 69 6f 6e 20 66 6f 72 20  o-extension for 
38a0: 74 68 65 20 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65  the .** multiple
38b0: 78 5f 63 6f 6e 74 72 6f 6c 28 29 20 66 75 6e 63  x_control() func
38c0: 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tion..*/.static 
38d0: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 46 75 6e  int multiplexFun
38e0: 63 49 6e 69 74 28 0a 20 20 73 71 6c 69 74 65 33  cInit(.  sqlite3
38f0: 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20 2a 2a   *db, .  char **
3900: 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20 63 6f 6e  pzErrMsg, .  con
3910: 73 74 20 73 71 6c 69 74 65 33 5f 61 70 69 5f 72  st sqlite3_api_r
3920: 6f 75 74 69 6e 65 73 20 2a 70 41 70 69 0a 29 7b  outines *pApi.){
3930: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20  .  int rc;.  rc 
3940: 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65  = sqlite3_create
3950: 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 6d  _function(db, "m
3960: 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74 72 6f 6c  ultiplex_control
3970: 22 2c 20 32 2c 20 53 51 4c 49 54 45 5f 41 4e 59  ", 2, SQLITE_ANY
3980: 2c 20 0a 20 20 20 20 20 20 30 2c 20 6d 75 6c 74  , .      0, mult
3990: 69 70 6c 65 78 43 6f 6e 74 72 6f 6c 46 75 6e 63  iplexControlFunc
39a0: 2c 20 30 2c 20 30 29 3b 0a 20 20 72 65 74 75 72  , 0, 0);.  retur
39b0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
39c0: 6c 6f 73 65 20 61 20 73 69 6e 67 6c 65 20 73 75  lose a single su
39d0: 62 2d 66 69 6c 65 20 69 6e 20 74 68 65 20 63 6f  b-file in the co
39e0: 6e 6e 65 63 74 69 6f 6e 20 67 72 6f 75 70 2e 0a  nnection group..
39f0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d  */.static void m
3a00: 75 6c 74 69 70 6c 65 78 53 75 62 43 6c 6f 73 65  ultiplexSubClose
3a10: 28 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f  (.  multiplexGro
3a20: 75 70 20 2a 70 47 72 6f 75 70 2c 0a 20 20 69 6e  up *pGroup,.  in
3a30: 74 20 69 43 68 75 6e 6b 2c 0a 20 20 73 71 6c 69  t iChunk,.  sqli
3a40: 74 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66  te3_vfs *pOrigVf
3a50: 73 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  s.){.  sqlite3_f
3a60: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
3a70: 70 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43  pGroup->aReal[iC
3a80: 68 75 6e 6b 5d 2e 70 3b 0a 20 20 69 66 28 20 70  hunk].p;.  if( p
3a90: 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20 70  SubOpen ){.    p
3aa0: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
3ab0: 73 2d 3e 78 43 6c 6f 73 65 28 70 53 75 62 4f 70  s->xClose(pSubOp
3ac0: 65 6e 29 3b 0a 20 20 20 20 69 66 28 20 70 4f 72  en);.    if( pOr
3ad0: 69 67 56 66 73 20 26 26 20 70 47 72 6f 75 70 2d  igVfs && pGroup-
3ae0: 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a  >aReal[iChunk].z
3af0: 20 29 7b 0a 20 20 20 20 20 20 70 4f 72 69 67 56   ){.      pOrigV
3b00: 66 73 2d 3e 78 44 65 6c 65 74 65 28 70 4f 72 69  fs->xDelete(pOri
3b10: 67 56 66 73 2c 20 70 47 72 6f 75 70 2d 3e 61 52  gVfs, pGroup->aR
3b20: 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 2c 20 30  eal[iChunk].z, 0
3b30: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
3b40: 69 74 65 33 5f 66 72 65 65 28 70 47 72 6f 75 70  ite3_free(pGroup
3b50: 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e  ->aReal[iChunk].
3b60: 70 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  p);.  }.  sqlite
3b70: 33 5f 66 72 65 65 28 70 47 72 6f 75 70 2d 3e 61  3_free(pGroup->a
3b80: 52 65 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 29 3b  Real[iChunk].z);
3b90: 0a 20 20 6d 65 6d 73 65 74 28 26 70 47 72 6f 75  .  memset(&pGrou
3ba0: 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b 5d  p->aReal[iChunk]
3bb0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70 47 72 6f  , 0, sizeof(pGro
3bc0: 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e 6b  up->aReal[iChunk
3bd0: 5d 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  ]));.}../*.** De
3be0: 61 6c 6c 6f 63 61 74 65 20 6d 65 6d 6f 72 79 20  allocate memory 
3bf0: 68 65 6c 64 20 62 79 20 61 20 6d 75 6c 74 69 70  held by a multip
3c00: 6c 65 78 47 72 6f 75 70 0a 2a 2f 0a 73 74 61 74  lexGroup.*/.stat
3c10: 69 63 20 76 6f 69 64 20 6d 75 6c 74 69 70 6c 65  ic void multiple
3c20: 78 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74 73 28  xFreeComponents(
3c30: 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a  multiplexGroup *
3c40: 70 47 72 6f 75 70 29 7b 0a 20 20 69 6e 74 20 69  pGroup){.  int i
3c50: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ;.  for(i=0; i<p
3c60: 47 72 6f 75 70 2d 3e 6e 52 65 61 6c 3b 20 69 2b  Group->nReal; i+
3c70: 2b 29 7b 20 6d 75 6c 74 69 70 6c 65 78 53 75 62  +){ multiplexSub
3c80: 43 6c 6f 73 65 28 70 47 72 6f 75 70 2c 20 69 2c  Close(pGroup, i,
3c90: 20 30 29 3b 20 7d 0a 20 20 73 71 6c 69 74 65 33   0); }.  sqlite3
3ca0: 5f 66 72 65 65 28 70 47 72 6f 75 70 2d 3e 61 52  _free(pGroup->aR
3cb0: 65 61 6c 29 3b 0a 20 20 70 47 72 6f 75 70 2d 3e  eal);.  pGroup->
3cc0: 61 52 65 61 6c 20 3d 20 30 3b 0a 20 20 70 47 72  aReal = 0;.  pGr
3cd0: 6f 75 70 2d 3e 6e 52 65 61 6c 20 3d 20 30 3b 0a  oup->nReal = 0;.
3ce0: 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  }.../***********
3cf0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 56  ************** V
3d00: 46 53 20 4d 65 74 68 6f 64 20 57 72 61 70 70 65  FS Method Wrappe
3d10: 72 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  rs *************
3d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3d30: 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73  /../*.** This is
3d40: 20 74 68 65 20 78 4f 70 65 6e 20 6d 65 74 68 6f   the xOpen metho
3d50: 64 20 75 73 65 64 20 66 6f 72 20 74 68 65 20 22  d used for the "
3d60: 6d 75 6c 74 69 70 6c 65 78 22 20 56 46 53 2e 0a  multiplex" VFS..
3d70: 2a 2a 0a 2a 2a 20 4d 6f 73 74 20 6f 66 20 74 68  **.** Most of th
3d80: 65 20 77 6f 72 6b 20 69 73 20 64 6f 6e 65 20 62  e work is done b
3d90: 79 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  y the underlying
3da0: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 20 20   original VFS.  
3db0: 54 68 69 73 20 6d 65 74 68 6f 64 0a 2a 2a 20 73  This method.** s
3dc0: 69 6d 70 6c 79 20 6c 69 6e 6b 73 20 74 68 65 20  imply links the 
3dd0: 6e 65 77 20 66 69 6c 65 20 69 6e 74 6f 20 74 68  new file into th
3de0: 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 6d 75  e appropriate mu
3df0: 6c 74 69 70 6c 65 78 20 67 72 6f 75 70 20 69 66  ltiplex group if
3e00: 20 69 74 20 69 73 20 61 0a 2a 2a 20 66 69 6c 65   it is a.** file
3e10: 20 74 68 61 74 20 6e 65 65 64 73 20 74 6f 20 62   that needs to b
3e20: 65 20 74 72 61 63 6b 65 64 2e 0a 2a 2f 0a 73 74  e tracked..*/.st
3e30: 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c  atic int multipl
3e40: 65 78 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65  exOpen(.  sqlite
3e50: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 20 20 20  3_vfs *pVfs,    
3e60: 20 20 20 20 20 2f 2a 20 54 68 65 20 6d 75 6c 74       /* The mult
3e70: 69 70 6c 65 78 20 56 46 53 20 2a 2f 0a 20 20 63  iplex VFS */.  c
3e80: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
3e90: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d  ,         /* Nam
3ea0: 65 20 6f 66 20 66 69 6c 65 20 74 6f 20 62 65 20  e of file to be 
3eb0: 6f 70 65 6e 65 64 20 2a 2f 0a 20 20 73 71 6c 69  opened */.  sqli
3ec0: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
3ed0: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 6c 20 69         /* Fill i
3ee0: 6e 20 74 68 69 73 20 66 69 6c 65 20 64 65 73 63  n this file desc
3ef0: 72 69 70 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  riptor */.  int 
3f00: 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
3f10: 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
3f20: 74 6f 20 63 6f 6e 74 72 6f 6c 20 74 68 65 20 6f  to control the o
3f30: 70 65 6e 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20  pening */.  int 
3f40: 2a 70 4f 75 74 46 6c 61 67 73 20 20 20 20 20 20  *pOutFlags      
3f50: 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
3f60: 73 68 6f 77 69 6e 67 20 72 65 73 75 6c 74 73 20  showing results 
3f70: 6f 66 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a 29 7b  of opening */.){
3f80: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
3f90: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
3fa0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c          /* Resul
3fb0: 74 20 63 6f 64 65 20 2a 2f 0a 20 20 6d 75 6c 74  t code */.  mult
3fc0: 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 4d 75 6c 74  iplexConn *pMult
3fd0: 69 70 6c 65 78 4f 70 65 6e 3b 20 20 20 20 20 20  iplexOpen;      
3fe0: 20 2f 2a 20 54 68 65 20 6e 65 77 20 6d 75 6c 74   /* The new mult
3ff0: 69 70 6c 65 78 20 66 69 6c 65 20 64 65 73 63 72  iplex file descr
4000: 69 70 74 6f 72 20 2a 2f 0a 20 20 6d 75 6c 74 69  iptor */.  multi
4010: 70 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f 75  plexGroup *pGrou
4020: 70 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  p = 0;          
4030: 2f 2a 20 43 6f 72 72 65 73 70 6f 6e 64 69 6e 67  /* Corresponding
4040: 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70 20   multiplexGroup 
4050: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69  object */.  sqli
4060: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
4070: 65 6e 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  en = 0;         
4080: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
4090: 61 6c 20 66 69 6c 65 20 64 65 73 63 72 69 70 74  al file descript
40a0: 6f 72 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  or */.  sqlite3_
40b0: 76 66 73 20 2a 70 4f 72 69 67 56 66 73 20 3d 20  vfs *pOrigVfs = 
40c0: 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67  gMultiplex.pOrig
40d0: 56 66 73 3b 20 20 20 2f 2a 20 52 65 61 6c 20 56  Vfs;   /* Real V
40e0: 46 53 20 2a 2f 0a 20 20 69 6e 74 20 6e 4e 61 6d  FS */.  int nNam
40f0: 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 73 7a 20  e = 0;.  int sz 
4100: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 54 6f  = 0;.  char *zTo
4110: 46 72 65 65 20 3d 20 30 3b 0a 0a 20 20 55 4e 55  Free = 0;..  UNU
4120: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 70 56  SED_PARAMETER(pV
4130: 66 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 43  fs);.  memset(pC
4140: 6f 6e 6e 2c 20 30 2c 20 70 56 66 73 2d 3e 73 7a  onn, 0, pVfs->sz
4150: 4f 73 46 69 6c 65 29 3b 0a 20 20 61 73 73 65 72  OsFile);.  asser
4160: 74 28 20 7a 4e 61 6d 65 20 7c 7c 20 28 66 6c 61  t( zName || (fla
4170: 67 73 20 26 20 53 51 4c 49 54 45 5f 4f 50 45 4e  gs & SQLITE_OPEN
4180: 5f 44 45 4c 45 54 45 4f 4e 43 4c 4f 53 45 29 20  _DELETEONCLOSE) 
4190: 29 3b 0a 0a 20 20 2f 2a 20 57 65 20 6e 65 65 64  );..  /* We need
41a0: 20 74 6f 20 63 72 65 61 74 65 20 61 20 67 72 6f   to create a gro
41b0: 75 70 20 73 74 72 75 63 74 75 72 65 20 61 6e 64  up structure and
41c0: 20 6d 61 6e 61 67 65 0a 20 20 2a 2a 20 61 63 63   manage.  ** acc
41d0: 65 73 73 20 74 6f 20 74 68 69 73 20 67 72 6f 75  ess to this grou
41e0: 70 20 6f 66 20 66 69 6c 65 73 2e 0a 20 20 2a 2f  p of files..  */
41f0: 0a 20 20 70 4d 75 6c 74 69 70 6c 65 78 4f 70 65  .  pMultiplexOpe
4200: 6e 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f  n = (multiplexCo
4210: 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 0a 20 20 69 66  nn*)pConn;..  if
4220: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4230: 29 7b 0a 20 20 20 20 2f 2a 20 61 6c 6c 6f 63 61  ){.    /* alloca
4240: 74 65 20 73 70 61 63 65 20 66 6f 72 20 67 72 6f  te space for gro
4250: 75 70 20 2a 2f 0a 20 20 20 20 6e 4e 61 6d 65 20  up */.    nName 
4260: 3d 20 7a 4e 61 6d 65 20 3f 20 6d 75 6c 74 69 70  = zName ? multip
4270: 6c 65 78 53 74 72 6c 65 6e 33 30 28 7a 4e 61 6d  lexStrlen30(zNam
4280: 65 29 20 3a 20 30 3b 0a 20 20 20 20 73 7a 20 3d  e) : 0;.    sz =
4290: 20 73 69 7a 65 6f 66 28 6d 75 6c 74 69 70 6c 65   sizeof(multiple
42a0: 78 47 72 6f 75 70 29 20 20 20 20 20 20 20 20 20  xGroup)         
42b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42c0: 20 20 20 20 2f 2a 20 6d 75 6c 74 69 70 6c 65 78      /* multiplex
42d0: 47 72 6f 75 70 20 2a 2f 0a 20 20 20 20 20 20 20  Group */.       
42e0: 2b 20 6e 4e 61 6d 65 20 2b 20 31 3b 20 20 20 20  + nName + 1;    
42f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4310: 20 20 20 20 20 2f 2a 20 7a 4e 61 6d 65 20 2a 2f       /* zName */
4320: 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20 73 71  .    pGroup = sq
4330: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 20  lite3_malloc64( 
4340: 73 7a 20 29 3b 0a 20 20 20 20 69 66 28 20 70 47  sz );.    if( pG
4350: 72 6f 75 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20  roup==0 ){.     
4360: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
4370: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  EM;.    }.  }.. 
4380: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4390: 4f 4b 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  OK ){.    const 
43a0: 63 68 61 72 20 2a 7a 55 72 69 20 3d 20 28 66 6c  char *zUri = (fl
43b0: 61 67 73 20 26 20 53 51 4c 49 54 45 5f 4f 50 45  ags & SQLITE_OPE
43c0: 4e 5f 55 52 49 29 20 3f 20 7a 4e 61 6d 65 20 3a  N_URI) ? zName :
43d0: 20 30 3b 0a 20 20 20 20 2f 2a 20 61 73 73 69 67   0;.    /* assig
43e0: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 65 78  n pointers to ex
43f0: 74 72 61 20 73 70 61 63 65 20 61 6c 6c 6f 63 61  tra space alloca
4400: 74 65 64 20 2a 2f 0a 20 20 20 20 6d 65 6d 73 65  ted */.    memse
4410: 74 28 70 47 72 6f 75 70 2c 20 30 2c 20 73 7a 29  t(pGroup, 0, sz)
4420: 3b 0a 20 20 20 20 70 4d 75 6c 74 69 70 6c 65 78  ;.    pMultiplex
4430: 4f 70 65 6e 2d 3e 70 47 72 6f 75 70 20 3d 20 70  Open->pGroup = p
4440: 47 72 6f 75 70 3b 0a 20 20 20 20 70 47 72 6f 75  Group;.    pGrou
4450: 70 2d 3e 62 45 6e 61 62 6c 65 64 20 3d 20 28 75  p->bEnabled = (u
4460: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 2d 31 3b  nsigned char)-1;
4470: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 62 54 72  .    pGroup->bTr
4480: 75 6e 63 61 74 65 20 3d 20 28 75 6e 73 69 67 6e  uncate = (unsign
4490: 65 64 20 63 68 61 72 29 73 71 6c 69 74 65 33 5f  ed char)sqlite3_
44a0: 75 72 69 5f 62 6f 6f 6c 65 61 6e 28 7a 55 72 69  uri_boolean(zUri
44b0: 2c 20 22 74 72 75 6e 63 61 74 65 22 2c 20 0a 20  , "truncate", . 
44c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44e0: 20 20 28 66 6c 61 67 73 20 26 20 53 51 4c 49 54    (flags & SQLIT
44f0: 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 29 3d  E_OPEN_MAIN_DB)=
4500: 3d 30 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d  =0);.    pGroup-
4510: 3e 73 7a 43 68 75 6e 6b 20 3d 20 28 69 6e 74 29  >szChunk = (int)
4520: 73 71 6c 69 74 65 33 5f 75 72 69 5f 69 6e 74 36  sqlite3_uri_int6
4530: 34 28 7a 55 72 69 2c 20 22 63 68 75 6e 6b 73 69  4(zUri, "chunksi
4540: 7a 65 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ze",.           
4550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4560: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
4570: 49 54 45 5f 4d 55 4c 54 49 50 4c 45 58 5f 43 48  ITE_MULTIPLEX_CH
4580: 55 4e 4b 5f 53 49 5a 45 29 3b 0a 20 20 20 20 70  UNK_SIZE);.    p
4590: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 3d  Group->szChunk =
45a0: 20 28 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e   (pGroup->szChun
45b0: 6b 2b 30 78 66 66 66 66 29 26 7e 30 78 66 66 66  k+0xffff)&~0xfff
45c0: 66 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  f;.    if( zName
45d0: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
45e0: 70 20 3d 20 28 63 68 61 72 20 2a 29 26 70 47 72  p = (char *)&pGr
45f0: 6f 75 70 5b 31 5d 3b 0a 20 20 20 20 20 20 70 47  oup[1];.      pG
4600: 72 6f 75 70 2d 3e 7a 4e 61 6d 65 20 3d 20 70 3b  roup->zName = p;
4610: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 47  .      memcpy(pG
4620: 72 6f 75 70 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61  roup->zName, zNa
4630: 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20  me, nName+1);.  
4640: 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4e 61 6d      pGroup->nNam
4650: 65 20 3d 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 7d  e = nName;.    }
4660: 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d  .    if( pGroup-
4670: 3e 62 45 6e 61 62 6c 65 64 20 29 7b 0a 20 20 20  >bEnabled ){.   
4680: 20 20 20 2f 2a 20 4d 61 6b 65 20 73 75 72 65 20     /* Make sure 
4690: 74 68 61 74 20 74 68 65 20 63 68 75 6e 6b 73 69  that the chunksi
46a0: 7a 65 20 69 73 20 73 75 63 68 20 74 68 61 74 20  ze is such that 
46b0: 74 68 65 20 70 65 6e 64 69 6e 67 20 62 79 74 65  the pending byte
46c0: 20 64 6f 65 73 20 6e 6f 74 0a 20 20 20 20 20 20   does not.      
46d0: 2a 2a 20 66 61 6c 6c 73 20 61 74 20 74 68 65 20  ** falls at the 
46e0: 65 6e 64 20 6f 66 20 61 20 63 68 75 6e 6b 2e 20  end of a chunk. 
46f0: 20 41 20 72 65 67 69 6f 6e 20 6f 66 20 75 70 20   A region of up 
4700: 74 6f 20 36 34 4b 20 66 6f 6c 6c 6f 77 69 6e 67  to 64K following
4710: 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 20 70 65  .      ** the pe
4720: 6e 64 69 6e 67 20 62 79 74 65 20 69 73 20 6e 65  nding byte is ne
4730: 76 65 72 20 77 72 69 74 74 65 6e 2c 20 73 6f 20  ver written, so 
4740: 69 66 20 74 68 65 20 70 65 6e 64 69 6e 67 20 62  if the pending b
4750: 79 74 65 20 6f 63 63 75 72 73 0a 20 20 20 20 20  yte occurs.     
4760: 20 2a 2a 20 6e 65 61 72 20 74 68 65 20 65 6e 64   ** near the end
4770: 20 6f 66 20 61 20 63 68 75 6e 6b 2c 20 74 68 61   of a chunk, tha
4780: 74 20 63 68 75 6e 6b 20 77 69 6c 6c 20 62 65 20  t chunk will be 
4790: 74 6f 6f 20 73 6d 61 6c 6c 2e 20 2a 2f 0a 23 69  too small. */.#i
47a0: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
47b0: 54 5f 57 53 44 0a 20 20 20 20 20 20 65 78 74 65  T_WSD.      exte
47c0: 72 6e 20 69 6e 74 20 73 71 6c 69 74 65 33 50 65  rn int sqlite3Pe
47d0: 6e 64 69 6e 67 42 79 74 65 3b 0a 23 65 6c 73 65  ndingByte;.#else
47e0: 0a 20 20 20 20 20 20 69 6e 74 20 73 71 6c 69 74  .      int sqlit
47f0: 65 33 50 65 6e 64 69 6e 67 42 79 74 65 20 3d 20  e3PendingByte = 
4800: 30 78 34 30 30 30 30 30 30 30 3b 0a 23 65 6e 64  0x40000000;.#end
4810: 69 66 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  if.      while( 
4820: 28 73 71 6c 69 74 65 33 50 65 6e 64 69 6e 67 42  (sqlite3PendingB
4830: 79 74 65 20 25 20 70 47 72 6f 75 70 2d 3e 73 7a  yte % pGroup->sz
4840: 43 68 75 6e 6b 29 3e 3d 28 70 47 72 6f 75 70 2d  Chunk)>=(pGroup-
4850: 3e 73 7a 43 68 75 6e 6b 2d 36 35 35 33 36 29 20  >szChunk-65536) 
4860: 29 7b 0a 20 20 20 20 20 20 20 20 70 47 72 6f 75  ){.        pGrou
4870: 70 2d 3e 73 7a 43 68 75 6e 6b 20 2b 3d 20 36 35  p->szChunk += 65
4880: 35 33 36 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  536;.      }.   
4890: 20 7d 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 66   }.    pGroup->f
48a0: 6c 61 67 73 20 3d 20 66 6c 61 67 73 3b 0a 20 20  lags = flags;.  
48b0: 20 20 72 63 20 3d 20 6d 75 6c 74 69 70 6c 65 78    rc = multiplex
48c0: 53 75 62 46 69 6c 65 6e 61 6d 65 28 70 47 72 6f  SubFilename(pGro
48d0: 75 70 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20  up, 1);.    if( 
48e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
48f0: 0a 20 20 20 20 20 20 70 53 75 62 4f 70 65 6e 20  .      pSubOpen 
4900: 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70  = multiplexSubOp
4910: 65 6e 28 70 47 72 6f 75 70 2c 20 30 2c 20 26 72  en(pGroup, 0, &r
4920: 63 2c 20 70 4f 75 74 46 6c 61 67 73 2c 20 30 29  c, pOutFlags, 0)
4930: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62  ;.      if( pSub
4940: 4f 70 65 6e 3d 3d 30 20 26 26 20 72 63 3d 3d 53  Open==0 && rc==S
4950: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20  QLITE_OK ) rc = 
4960: 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 3b  SQLITE_CANTOPEN;
4970: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
4980: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
4990: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e        sqlite3_in
49a0: 74 36 34 20 73 7a 36 34 3b 0a 0a 20 20 20 20 20  t64 sz64;..     
49b0: 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e   rc = pSubOpen->
49c0: 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53  pMethods->xFileS
49d0: 69 7a 65 28 70 53 75 62 4f 70 65 6e 2c 20 26 73  ize(pSubOpen, &s
49e0: 7a 36 34 29 3b 0a 20 20 20 20 20 20 69 66 28 20  z64);.      if( 
49f0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
4a00: 20 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20 20   zName ){.      
4a10: 20 20 69 6e 74 20 62 45 78 69 73 74 73 3b 0a 20    int bExists;. 
4a20: 20 20 20 20 20 20 20 69 66 28 20 66 6c 61 67 73         if( flags
4a30: 20 26 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d   & SQLITE_OPEN_M
4a40: 41 53 54 45 52 5f 4a 4f 55 52 4e 41 4c 20 29 7b  ASTER_JOURNAL ){
4a50: 0a 20 20 20 20 20 20 20 20 20 20 70 47 72 6f 75  .          pGrou
4a60: 70 2d 3e 62 45 6e 61 62 6c 65 64 20 3d 20 30 3b  p->bEnabled = 0;
4a70: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 0a 20  .        }else. 
4a80: 20 20 20 20 20 20 20 69 66 28 20 73 7a 36 34 3d         if( sz64=
4a90: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
4aa0: 69 66 28 20 66 6c 61 67 73 20 26 20 53 51 4c 49  if( flags & SQLI
4ab0: 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55  TE_OPEN_MAIN_JOU
4ac0: 52 4e 41 4c 20 29 7b 0a 20 20 20 20 20 20 20 20  RNAL ){.        
4ad0: 20 20 20 20 2f 2a 20 49 66 20 6f 70 65 6e 69 6e      /* If openin
4ae0: 67 20 61 20 6d 61 69 6e 20 6a 6f 75 72 6e 61 6c  g a main journal
4af0: 20 66 69 6c 65 20 61 6e 64 20 74 68 65 20 66 69   file and the fi
4b00: 72 73 74 20 63 68 75 6e 6b 20 69 73 20 7a 65 72  rst chunk is zer
4b10: 6f 0a 20 20 20 20 20 20 20 20 20 20 20 20 2a 2a  o.            **
4b20: 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65 2c 20   bytes in size, 
4b30: 64 65 6c 65 74 65 20 61 6e 79 20 73 75 62 73 65  delete any subse
4b40: 71 75 65 6e 74 20 63 68 75 6e 6b 73 20 66 72 6f  quent chunks fro
4b50: 6d 20 74 68 65 20 0a 20 20 20 20 20 20 20 20 20  m the .         
4b60: 20 20 20 2a 2a 20 66 69 6c 65 2d 73 79 73 74 65     ** file-syste
4b70: 6d 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  m. */.          
4b80: 20 20 69 6e 74 20 69 43 68 75 6e 6b 20 3d 20 31    int iChunk = 1
4b90: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 6f  ;.            do
4ba0: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
4bb0: 20 72 63 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e   rc = pOrigVfs->
4bc0: 78 41 63 63 65 73 73 28 70 4f 72 69 67 56 66 73  xAccess(pOrigVfs
4bd0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
4be0: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 61 52 65       pGroup->aRe
4bf0: 61 6c 5b 69 43 68 75 6e 6b 5d 2e 7a 2c 20 53 51  al[iChunk].z, SQ
4c00: 4c 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53  LITE_ACCESS_EXIS
4c10: 54 53 2c 20 26 62 45 78 69 73 74 73 0a 20 20 20  TS, &bExists.   
4c20: 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20 20             );.  
4c30: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
4c40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
4c50: 20 62 45 78 69 73 74 73 20 29 7b 0a 20 20 20 20   bExists ){.    
4c60: 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d              rc =
4c70: 20 70 4f 72 69 67 56 66 73 2d 3e 78 44 65 6c 65   pOrigVfs->xDele
4c80: 74 65 28 70 4f 72 69 67 56 66 73 2c 20 70 47 72  te(pOrigVfs, pGr
4c90: 6f 75 70 2d 3e 61 52 65 61 6c 5b 69 43 68 75 6e  oup->aReal[iChun
4ca0: 6b 5d 2e 7a 2c 20 30 29 3b 0a 20 20 20 20 20 20  k].z, 0);.      
4cb0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63            if( rc
4cc0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
4cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ce0: 20 72 63 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53   rc = multiplexS
4cf0: 75 62 46 69 6c 65 6e 61 6d 65 28 70 47 72 6f 75  ubFilename(pGrou
4d00: 70 2c 20 2b 2b 69 43 68 75 6e 6b 29 3b 0a 20 20  p, ++iChunk);.  
4d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
4d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 7d 77 68 69              }whi
4d40: 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  le( rc==SQLITE_O
4d50: 4b 20 26 26 20 62 45 78 69 73 74 73 20 29 3b 0a  K && bExists );.
4d60: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
4d70: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4d80: 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 66       /* If the f
4d90: 69 72 73 74 20 6f 76 65 72 66 6c 6f 77 20 66 69  irst overflow fi
4da0: 6c 65 20 65 78 69 73 74 73 20 61 6e 64 20 69 66  le exists and if
4db0: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
4dc0: 20 6d 61 69 6e 20 66 69 6c 65 0a 20 20 20 20 20   main file.     
4dd0: 20 20 20 20 20 2a 2a 20 69 73 20 64 69 66 66 65       ** is diffe
4de0: 72 65 6e 74 20 66 72 6f 6d 20 74 68 65 20 63 68  rent from the ch
4df0: 75 6e 6b 20 73 69 7a 65 2c 20 74 68 61 74 20 6d  unk size, that m
4e00: 65 61 6e 73 20 74 68 65 20 63 68 75 6e 6b 20 73  eans the chunk s
4e10: 69 7a 65 20 69 73 20 73 65 74 0a 20 20 20 20 20  ize is set.     
4e20: 20 20 20 20 20 2a 2a 20 73 65 74 20 69 6e 63 6f       ** set inco
4e30: 72 72 65 63 74 6c 79 2e 20 20 53 6f 20 66 69 78  rrectly.  So fix
4e40: 20 69 74 2e 0a 20 20 20 20 20 20 20 20 20 20 2a   it..          *
4e50: 2a 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 4f  *.          ** O
4e60: 72 2c 20 69 66 20 74 68 65 20 66 69 72 73 74 20  r, if the first 
4e70: 6f 76 65 72 66 6c 6f 77 20 66 69 6c 65 20 64 6f  overflow file do
4e80: 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61 6e 64  es not exist and
4e90: 20 74 68 65 20 6d 61 69 6e 20 66 69 6c 65 20 69   the main file i
4ea0: 73 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 6c  s.          ** l
4eb0: 61 72 67 65 72 20 74 68 61 6e 20 74 68 65 20 63  arger than the c
4ec0: 68 75 6e 6b 20 73 69 7a 65 2c 20 74 68 61 74 20  hunk size, that 
4ed0: 6d 65 61 6e 73 20 74 68 65 20 63 68 75 6e 6b 20  means the chunk 
4ee0: 73 69 7a 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c  size is too smal
4ef0: 6c 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  l..          ** 
4f00: 42 75 74 20 77 65 20 68 61 76 65 20 6e 6f 20 77  But we have no w
4f10: 61 79 20 6f 66 20 64 65 74 65 72 6d 69 6e 69 6e  ay of determinin
4f20: 67 20 74 68 65 20 69 6e 74 65 6e 64 65 64 20 63  g the intended c
4f30: 68 75 6e 6b 20 73 69 7a 65 2c 20 73 6f 20 0a 20  hunk size, so . 
4f40: 20 20 20 20 20 20 20 20 20 2a 2a 20 6a 75 73 74           ** just
4f50: 20 64 69 73 61 62 6c 65 20 74 68 65 20 6d 75 6c   disable the mul
4f60: 74 69 70 6c 65 78 6f 72 20 61 6c 6c 20 74 6f 67  tiplexor all tog
4f70: 65 74 68 72 65 2e 0a 20 20 20 20 20 20 20 20 20  ethre..         
4f80: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 72 63   */.          rc
4f90: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 41 63   = pOrigVfs->xAc
4fa0: 63 65 73 73 28 70 4f 72 69 67 56 66 73 2c 20 70  cess(pOrigVfs, p
4fb0: 47 72 6f 75 70 2d 3e 61 52 65 61 6c 5b 31 5d 2e  Group->aReal[1].
4fc0: 7a 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  z,.             
4fd0: 20 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f 45   SQLITE_ACCESS_E
4fe0: 58 49 53 54 53 2c 20 26 62 45 78 69 73 74 73 29  XISTS, &bExists)
4ff0: 3b 0a 20 20 20 20 20 20 20 20 20 20 62 45 78 69  ;.          bExi
5000: 73 74 73 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  sts = multiplexS
5010: 75 62 53 69 7a 65 28 70 47 72 6f 75 70 2c 20 31  ubSize(pGroup, 1
5020: 2c 20 26 72 63 29 3e 30 3b 0a 20 20 20 20 20 20  , &rc)>0;.      
5030: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
5040: 54 45 5f 4f 4b 20 26 26 20 62 45 78 69 73 74 73  TE_OK && bExists
5050: 20 26 26 20 73 7a 36 34 3d 3d 28 73 7a 36 34 26   && sz64==(sz64&
5060: 30 78 66 66 66 66 30 30 30 30 29 20 26 26 20 73  0xffff0000) && s
5070: 7a 36 34 3e 30 0a 20 20 20 20 20 20 20 20 20 20  z64>0.          
5080: 20 20 20 20 26 26 20 73 7a 36 34 21 3d 70 47 72      && sz64!=pGr
5090: 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 29 7b 0a  oup->szChunk ){.
50a0: 20 20 20 20 20 20 20 20 20 20 20 20 70 47 72 6f              pGro
50b0: 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 3d 20 28 69  up->szChunk = (i
50c0: 6e 74 29 73 7a 36 34 3b 0a 20 20 20 20 20 20 20  nt)sz64;.       
50d0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d     }else if( rc=
50e0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 21 62  =SQLITE_OK && !b
50f0: 45 78 69 73 74 73 20 26 26 20 73 7a 36 34 3e 70  Exists && sz64>p
5100: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 29  Group->szChunk )
5110: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 47  {.            pG
5120: 72 6f 75 70 2d 3e 62 45 6e 61 62 6c 65 64 20 3d  roup->bEnabled =
5130: 20 30 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a   0;.          }.
5140: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
5150: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
5160: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
5170: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62  {.      if( pSub
5180: 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Open->pMethods->
5190: 69 56 65 72 73 69 6f 6e 3d 3d 31 20 29 7b 0a 20  iVersion==1 ){. 
51a0: 20 20 20 20 20 20 20 70 4d 75 6c 74 69 70 6c 65         pMultiple
51b0: 78 4f 70 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74  xOpen->base.pMet
51c0: 68 6f 64 73 20 3d 20 26 67 4d 75 6c 74 69 70 6c  hods = &gMultipl
51d0: 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 3b  ex.sIoMethodsV1;
51e0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
51f0: 20 20 20 20 20 20 70 4d 75 6c 74 69 70 6c 65 78        pMultiplex
5200: 4f 70 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74 68  Open->base.pMeth
5210: 6f 64 73 20 3d 20 26 67 4d 75 6c 74 69 70 6c 65  ods = &gMultiple
5220: 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b 0a  x.sIoMethodsV2;.
5230: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
5240: 65 7b 0a 20 20 20 20 20 20 6d 75 6c 74 69 70 6c  e{.      multipl
5250: 65 78 46 72 65 65 43 6f 6d 70 6f 6e 65 6e 74 73  exFreeComponents
5260: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 20 20  (pGroup);.      
5270: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 47 72  sqlite3_free(pGr
5280: 6f 75 70 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  oup);.    }.  }.
5290: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
52a0: 54 6f 46 72 65 65 29 3b 0a 20 20 72 65 74 75 72  ToFree);.  retur
52b0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
52c0: 68 69 73 20 69 73 20 74 68 65 20 78 44 65 6c 65  his is the xDele
52d0: 74 65 20 6d 65 74 68 6f 64 20 75 73 65 64 20 66  te method used f
52e0: 6f 72 20 74 68 65 20 22 6d 75 6c 74 69 70 6c 65  or the "multiple
52f0: 78 22 20 56 46 53 2e 0a 2a 2a 20 49 74 20 61 74  x" VFS..** It at
5300: 74 65 6d 70 74 73 20 74 6f 20 64 65 6c 65 74 65  tempts to delete
5310: 20 74 68 65 20 66 69 6c 65 6e 61 6d 65 20 73 70   the filename sp
5320: 65 63 69 66 69 65 64 2e 0a 2a 2f 0a 73 74 61 74  ecified..*/.stat
5330: 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78  ic int multiplex
5340: 44 65 6c 65 74 65 28 0a 20 20 73 71 6c 69 74 65  Delete(.  sqlite
5350: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 20 20 20  3_vfs *pVfs,    
5360: 20 20 20 20 20 2f 2a 20 54 68 65 20 6d 75 6c 74       /* The mult
5370: 69 70 6c 65 78 20 56 46 53 20 2a 2f 0a 20 20 63  iplex VFS */.  c
5380: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
5390: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d  ,         /* Nam
53a0: 65 20 6f 66 20 66 69 6c 65 20 74 6f 20 64 65 6c  e of file to del
53b0: 65 74 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  ete */.  int syn
53c0: 63 44 69 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63  cDir.){.  int rc
53d0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  ;.  sqlite3_vfs 
53e0: 2a 70 4f 72 69 67 56 66 73 20 3d 20 67 4d 75 6c  *pOrigVfs = gMul
53f0: 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 3b  tiplex.pOrigVfs;
5400: 20 20 20 2f 2a 20 52 65 61 6c 20 56 46 53 20 2a     /* Real VFS *
5410: 2f 0a 20 20 72 63 20 3d 20 70 4f 72 69 67 56 66  /.  rc = pOrigVf
5420: 73 2d 3e 78 44 65 6c 65 74 65 28 70 4f 72 69 67  s->xDelete(pOrig
5430: 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 73 79 6e 63  Vfs, zName, sync
5440: 44 69 72 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  Dir);.  if( rc==
5450: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5460: 20 2f 2a 20 49 66 20 74 68 65 20 6d 61 69 6e 20   /* If the main 
5470: 63 68 75 6e 6b 20 77 61 73 20 64 65 6c 65 74 65  chunk was delete
5480: 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79 2c 20  d successfully, 
5490: 61 6c 73 6f 20 64 65 6c 65 74 65 20 61 6e 79 20  also delete any 
54a0: 73 75 62 73 65 71 75 65 6e 74 0a 20 20 20 20 2a  subsequent.    *
54b0: 2a 20 63 68 75 6e 6b 73 20 2d 20 73 74 61 72 74  * chunks - start
54c0: 69 6e 67 20 77 69 74 68 20 74 68 65 20 6c 61 73  ing with the las
54d0: 74 20 28 68 69 67 68 65 73 74 20 6e 75 6d 62 65  t (highest numbe
54e0: 72 65 64 29 2e 20 0a 20 20 20 20 2a 2f 0a 20 20  red). .    */.  
54f0: 20 20 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 28 69    int nName = (i
5500: 6e 74 29 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29  nt)strlen(zName)
5510: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 3b 0a 20  ;.    char *z;. 
5520: 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d     z = sqlite3_m
5530: 61 6c 6c 6f 63 36 34 28 6e 4e 61 6d 65 20 2b 20  alloc64(nName + 
5540: 35 29 3b 0a 20 20 20 20 69 66 28 20 7a 3d 3d 30  5);.    if( z==0
5550: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
5560: 51 4c 49 54 45 5f 49 4f 45 52 52 5f 4e 4f 4d 45  QLITE_IOERR_NOME
5570: 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  M;.    }else{.  
5580: 20 20 20 20 69 6e 74 20 69 43 68 75 6e 6b 20 3d      int iChunk =
5590: 20 30 3b 0a 20 20 20 20 20 20 69 6e 74 20 62 45   0;.      int bE
55a0: 78 69 73 74 73 3b 0a 20 20 20 20 20 20 64 6f 7b  xists;.      do{
55b0: 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 70 6c  .        multipl
55c0: 65 78 46 69 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65  exFilename(zName
55d0: 2c 20 6e 4e 61 6d 65 2c 20 53 51 4c 49 54 45 5f  , nName, SQLITE_
55e0: 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e 41  OPEN_MAIN_JOURNA
55f0: 4c 2c 20 2b 2b 69 43 68 75 6e 6b 2c 20 7a 29 3b  L, ++iChunk, z);
5600: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 4f  .        rc = pO
5610: 72 69 67 56 66 73 2d 3e 78 41 63 63 65 73 73 28  rigVfs->xAccess(
5620: 70 4f 72 69 67 56 66 73 2c 20 7a 2c 20 53 51 4c  pOrigVfs, z, SQL
5630: 49 54 45 5f 41 43 43 45 53 53 5f 45 58 49 53 54  ITE_ACCESS_EXIST
5640: 53 2c 20 26 62 45 78 69 73 74 73 29 3b 0a 20 20  S, &bExists);.  
5650: 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d      }while( rc==
5660: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 45 78  SQLITE_OK && bEx
5670: 69 73 74 73 20 29 3b 0a 20 20 20 20 20 20 77 68  ists );.      wh
5680: 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
5690: 4f 4b 20 26 26 20 69 43 68 75 6e 6b 3e 31 20 29  OK && iChunk>1 )
56a0: 7b 0a 20 20 20 20 20 20 20 20 6d 75 6c 74 69 70  {.        multip
56b0: 6c 65 78 46 69 6c 65 6e 61 6d 65 28 7a 4e 61 6d  lexFilename(zNam
56c0: 65 2c 20 6e 4e 61 6d 65 2c 20 53 51 4c 49 54 45  e, nName, SQLITE
56d0: 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 4a 4f 55 52 4e  _OPEN_MAIN_JOURN
56e0: 41 4c 2c 20 2d 2d 69 43 68 75 6e 6b 2c 20 7a 29  AL, --iChunk, z)
56f0: 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70  ;.        rc = p
5700: 4f 72 69 67 56 66 73 2d 3e 78 44 65 6c 65 74 65  OrigVfs->xDelete
5710: 28 70 4f 72 69 67 56 66 73 2c 20 7a 2c 20 73 79  (pOrigVfs, z, sy
5720: 6e 63 44 69 72 29 3b 0a 20 20 20 20 20 20 7d 0a  ncDir);.      }.
5730: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
5740: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
5750: 20 20 20 69 43 68 75 6e 6b 20 3d 20 30 3b 0a 20     iChunk = 0;. 
5760: 20 20 20 20 20 20 20 64 6f 7b 0a 20 20 20 20 20         do{.     
5770: 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78 46 69       multiplexFi
5780: 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e  lename(zName, nN
5790: 61 6d 65 2c 20 53 51 4c 49 54 45 5f 4f 50 45 4e  ame, SQLITE_OPEN
57a0: 5f 57 41 4c 2c 20 2b 2b 69 43 68 75 6e 6b 2c 20  _WAL, ++iChunk, 
57b0: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  z);.          rc
57c0: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 41 63   = pOrigVfs->xAc
57d0: 63 65 73 73 28 70 4f 72 69 67 56 66 73 2c 20 7a  cess(pOrigVfs, z
57e0: 2c 20 53 51 4c 49 54 45 5f 41 43 43 45 53 53 5f  , SQLITE_ACCESS_
57f0: 45 58 49 53 54 53 2c 20 26 62 45 78 69 73 74 73  EXISTS, &bExists
5800: 29 3b 0a 20 20 20 20 20 20 20 20 7d 77 68 69 6c  );.        }whil
5810: 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
5820: 20 26 26 20 62 45 78 69 73 74 73 20 29 3b 0a 20   && bExists );. 
5830: 20 20 20 20 20 20 20 77 68 69 6c 65 28 20 72 63         while( rc
5840: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
5850: 43 68 75 6e 6b 3e 31 20 29 7b 0a 20 20 20 20 20  Chunk>1 ){.     
5860: 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78 46 69       multiplexFi
5870: 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e  lename(zName, nN
5880: 61 6d 65 2c 20 53 51 4c 49 54 45 5f 4f 50 45 4e  ame, SQLITE_OPEN
5890: 5f 57 41 4c 2c 20 2d 2d 69 43 68 75 6e 6b 2c 20  _WAL, --iChunk, 
58a0: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  z);.          rc
58b0: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 44 65   = pOrigVfs->xDe
58c0: 6c 65 74 65 28 70 4f 72 69 67 56 66 73 2c 20 7a  lete(pOrigVfs, z
58d0: 2c 20 73 79 6e 63 44 69 72 29 3b 0a 20 20 20 20  , syncDir);.    
58e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
58f0: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
5900: 66 72 65 65 28 7a 29 3b 0a 20 20 7d 0a 20 20 72  free(z);.  }.  r
5910: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
5920: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
5930: 78 41 63 63 65 73 73 28 73 71 6c 69 74 65 33 5f  xAccess(sqlite3_
5940: 76 66 73 20 2a 61 2c 20 63 6f 6e 73 74 20 63 68  vfs *a, const ch
5950: 61 72 20 2a 62 2c 20 69 6e 74 20 63 2c 20 69 6e  ar *b, int c, in
5960: 74 20 2a 64 29 7b 0a 20 20 72 65 74 75 72 6e 20  t *d){.  return 
5970: 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67  gMultiplex.pOrig
5980: 56 66 73 2d 3e 78 41 63 63 65 73 73 28 67 4d 75  Vfs->xAccess(gMu
5990: 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73  ltiplex.pOrigVfs
59a0: 2c 20 62 2c 20 63 2c 20 64 29 3b 0a 7d 0a 73 74  , b, c, d);.}.st
59b0: 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c  atic int multipl
59c0: 65 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 73  exFullPathname(s
59d0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 61 2c 20 63  qlite3_vfs *a, c
59e0: 6f 6e 73 74 20 63 68 61 72 20 2a 62 2c 20 69 6e  onst char *b, in
59f0: 74 20 63 2c 20 63 68 61 72 20 2a 64 29 7b 0a 20  t c, char *d){. 
5a00: 20 72 65 74 75 72 6e 20 67 4d 75 6c 74 69 70 6c   return gMultipl
5a10: 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78 46 75  ex.pOrigVfs->xFu
5a20: 6c 6c 50 61 74 68 6e 61 6d 65 28 67 4d 75 6c 74  llPathname(gMult
5a30: 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2c 20  iplex.pOrigVfs, 
5a40: 62 2c 20 63 2c 20 64 29 3b 0a 7d 0a 73 74 61 74  b, c, d);.}.stat
5a50: 69 63 20 76 6f 69 64 20 2a 6d 75 6c 74 69 70 6c  ic void *multipl
5a60: 65 78 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33  exDlOpen(sqlite3
5a70: 5f 76 66 73 20 2a 61 2c 20 63 6f 6e 73 74 20 63  _vfs *a, const c
5a80: 68 61 72 20 2a 62 29 7b 0a 20 20 72 65 74 75 72  har *b){.  retur
5a90: 6e 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72  n gMultiplex.pOr
5aa0: 69 67 56 66 73 2d 3e 78 44 6c 4f 70 65 6e 28 67  igVfs->xDlOpen(g
5ab0: 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56  Multiplex.pOrigV
5ac0: 66 73 2c 20 62 29 3b 0a 7d 0a 73 74 61 74 69 63  fs, b);.}.static
5ad0: 20 76 6f 69 64 20 6d 75 6c 74 69 70 6c 65 78 44   void multiplexD
5ae0: 6c 45 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76  lError(sqlite3_v
5af0: 66 73 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68  fs *a, int b, ch
5b00: 61 72 20 2a 63 29 7b 0a 20 20 67 4d 75 6c 74 69  ar *c){.  gMulti
5b10: 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78  plex.pOrigVfs->x
5b20: 44 6c 45 72 72 6f 72 28 67 4d 75 6c 74 69 70 6c  DlError(gMultipl
5b30: 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 2c 20  ex.pOrigVfs, b, 
5b40: 63 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  c);.}.static voi
5b50: 64 20 28 2a 6d 75 6c 74 69 70 6c 65 78 44 6c 53  d (*multiplexDlS
5b60: 79 6d 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  ym(sqlite3_vfs *
5b70: 61 2c 20 76 6f 69 64 20 2a 62 2c 20 63 6f 6e 73  a, void *b, cons
5b80: 74 20 63 68 61 72 20 2a 63 29 29 28 76 6f 69 64  t char *c))(void
5b90: 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 4d 75 6c  ){.  return gMul
5ba0: 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d  tiplex.pOrigVfs-
5bb0: 3e 78 44 6c 53 79 6d 28 67 4d 75 6c 74 69 70 6c  >xDlSym(gMultipl
5bc0: 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 2c 20  ex.pOrigVfs, b, 
5bd0: 63 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  c);.}.static voi
5be0: 64 20 6d 75 6c 74 69 70 6c 65 78 44 6c 43 6c 6f  d multiplexDlClo
5bf0: 73 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  se(sqlite3_vfs *
5c00: 61 2c 20 76 6f 69 64 20 2a 62 29 7b 0a 20 20 67  a, void *b){.  g
5c10: 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56  Multiplex.pOrigV
5c20: 66 73 2d 3e 78 44 6c 43 6c 6f 73 65 28 67 4d 75  fs->xDlClose(gMu
5c30: 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73  ltiplex.pOrigVfs
5c40: 2c 20 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  , b);.}.static i
5c50: 6e 74 20 6d 75 6c 74 69 70 6c 65 78 52 61 6e 64  nt multiplexRand
5c60: 6f 6d 6e 65 73 73 28 73 71 6c 69 74 65 33 5f 76  omness(sqlite3_v
5c70: 66 73 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68  fs *a, int b, ch
5c80: 61 72 20 2a 63 29 7b 0a 20 20 72 65 74 75 72 6e  ar *c){.  return
5c90: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69   gMultiplex.pOri
5ca0: 67 56 66 73 2d 3e 78 52 61 6e 64 6f 6d 6e 65 73  gVfs->xRandomnes
5cb0: 73 28 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72  s(gMultiplex.pOr
5cc0: 69 67 56 66 73 2c 20 62 2c 20 63 29 3b 0a 7d 0a  igVfs, b, c);.}.
5cd0: 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74 69  static int multi
5ce0: 70 6c 65 78 53 6c 65 65 70 28 73 71 6c 69 74 65  plexSleep(sqlite
5cf0: 33 5f 76 66 73 20 2a 61 2c 20 69 6e 74 20 62 29  3_vfs *a, int b)
5d00: 7b 0a 20 20 72 65 74 75 72 6e 20 67 4d 75 6c 74  {.  return gMult
5d10: 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e  iplex.pOrigVfs->
5d20: 78 53 6c 65 65 70 28 67 4d 75 6c 74 69 70 6c 65  xSleep(gMultiple
5d30: 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 29 3b 0a  x.pOrigVfs, b);.
5d40: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c  }.static int mul
5d50: 74 69 70 6c 65 78 43 75 72 72 65 6e 74 54 69 6d  tiplexCurrentTim
5d60: 65 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 61  e(sqlite3_vfs *a
5d70: 2c 20 64 6f 75 62 6c 65 20 2a 62 29 7b 0a 20 20  , double *b){.  
5d80: 72 65 74 75 72 6e 20 67 4d 75 6c 74 69 70 6c 65  return gMultiple
5d90: 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78 43 75 72  x.pOrigVfs->xCur
5da0: 72 65 6e 74 54 69 6d 65 28 67 4d 75 6c 74 69 70  rentTime(gMultip
5db0: 6c 65 78 2e 70 4f 72 69 67 56 66 73 2c 20 62 29  lex.pOrigVfs, b)
5dc0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 6d  ;.}.static int m
5dd0: 75 6c 74 69 70 6c 65 78 47 65 74 4c 61 73 74 45  ultiplexGetLastE
5de0: 72 72 6f 72 28 73 71 6c 69 74 65 33 5f 76 66 73  rror(sqlite3_vfs
5df0: 20 2a 61 2c 20 69 6e 74 20 62 2c 20 63 68 61 72   *a, int b, char
5e00: 20 2a 63 29 7b 0a 20 20 69 66 28 20 67 4d 75 6c   *c){.  if( gMul
5e10: 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d  tiplex.pOrigVfs-
5e20: 3e 78 47 65 74 4c 61 73 74 45 72 72 6f 72 20 29  >xGetLastError )
5e30: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 67 4d 75  {.    return gMu
5e40: 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67 56 66 73  ltiplex.pOrigVfs
5e50: 2d 3e 78 47 65 74 4c 61 73 74 45 72 72 6f 72 28  ->xGetLastError(
5e60: 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69 67  gMultiplex.pOrig
5e70: 56 66 73 2c 20 62 2c 20 63 29 3b 0a 20 20 7d 65  Vfs, b, c);.  }e
5e80: 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  lse{.    return 
5e90: 30 3b 0a 20 20 7d 0a 7d 0a 73 74 61 74 69 63 20  0;.  }.}.static 
5ea0: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 43 75 72  int multiplexCur
5eb0: 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 73 71  rentTimeInt64(sq
5ec0: 6c 69 74 65 33 5f 76 66 73 20 2a 61 2c 20 73 71  lite3_vfs *a, sq
5ed0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 62 29 7b  lite3_int64 *b){
5ee0: 0a 20 20 72 65 74 75 72 6e 20 67 4d 75 6c 74 69  .  return gMulti
5ef0: 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 2d 3e 78  plex.pOrigVfs->x
5f00: 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34  CurrentTimeInt64
5f10: 28 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f 72 69  (gMultiplex.pOri
5f20: 67 56 66 73 2c 20 62 29 3b 0a 7d 0a 0a 2f 2a 2a  gVfs, b);.}../**
5f30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f40: 2a 2a 2a 2a 2a 2a 20 49 2f 4f 20 4d 65 74 68 6f  ****** I/O Metho
5f50: 64 20 57 72 61 70 70 65 72 73 20 2a 2a 2a 2a 2a  d Wrappers *****
5f60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5f70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 20  **********/../* 
5f80: 78 43 6c 6f 73 65 20 72 65 71 75 65 73 74 73 20  xClose requests 
5f90: 67 65 74 20 70 61 73 73 65 64 20 74 68 72 6f 75  get passed throu
5fa0: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
5fb0: 61 6c 20 56 46 53 2e 0a 2a 2a 20 57 65 20 6c 6f  al VFS..** We lo
5fc0: 6f 70 20 6f 76 65 72 20 61 6c 6c 20 6f 70 65 6e  op over all open
5fd0: 20 63 68 75 6e 6b 20 68 61 6e 64 6c 65 73 20 61   chunk handles a
5fe0: 6e 64 20 63 6c 6f 73 65 20 74 68 65 6d 2e 0a 2a  nd close them..*
5ff0: 2a 20 54 68 65 20 67 72 6f 75 70 20 73 74 72 75  * The group stru
6000: 63 74 75 72 65 20 66 6f 72 20 74 68 69 73 20 66  cture for this f
6010: 69 6c 65 20 69 73 20 75 6e 6c 69 6e 6b 65 64 20  ile is unlinked 
6020: 66 72 6f 6d 20 0a 2a 2a 20 6f 75 72 20 6c 69 73  from .** our lis
6030: 74 20 6f 66 20 67 72 6f 75 70 73 20 61 6e 64 20  t of groups and 
6040: 66 72 65 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  freed..*/.static
6050: 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 43 6c   int multiplexCl
6060: 6f 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ose(sqlite3_file
6070: 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 6d 75 6c 74   *pConn){.  mult
6080: 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20 28  iplexConn *p = (
6090: 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29 70  multiplexConn*)p
60a0: 43 6f 6e 6e 3b 0a 20 20 6d 75 6c 74 69 70 6c 65  Conn;.  multiple
60b0: 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  xGroup *pGroup =
60c0: 20 70 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 69 6e   p->pGroup;.  in
60d0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
60e0: 3b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 46 72 65  ;.  multiplexFre
60f0: 65 43 6f 6d 70 6f 6e 65 6e 74 73 28 70 47 72 6f  eComponents(pGro
6100: 75 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  up);.  sqlite3_f
6110: 72 65 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 72  ree(pGroup);.  r
6120: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
6130: 50 61 73 73 20 78 52 65 61 64 20 72 65 71 75 65  Pass xRead reque
6140: 73 74 73 20 74 68 72 75 20 74 6f 20 74 68 65 20  sts thru to the 
6150: 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 61 66 74  original VFS aft
6160: 65 72 0a 2a 2a 20 64 65 74 65 72 6d 69 6e 69 6e  er.** determinin
6170: 67 20 74 68 65 20 63 6f 72 72 65 63 74 20 63 68  g the correct ch
6180: 75 6e 6b 20 74 6f 20 6f 70 65 72 61 74 65 20 6f  unk to operate o
6190: 6e 2e 0a 2a 2a 20 42 72 65 61 6b 20 75 70 20 72  n..** Break up r
61a0: 65 61 64 73 20 61 63 72 6f 73 73 20 63 68 75 6e  eads across chun
61b0: 6b 20 62 6f 75 6e 64 61 72 69 65 73 2e 0a 2a 2f  k boundaries..*/
61c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
61d0: 69 70 6c 65 78 52 65 61 64 28 0a 20 20 73 71 6c  iplexRead(.  sql
61e0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e  ite3_file *pConn
61f0: 2c 0a 20 20 76 6f 69 64 20 2a 70 42 75 66 2c 0a  ,.  void *pBuf,.
6200: 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20 20 73 71    int iAmt,.  sq
6210: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
6220: 74 0a 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78  t.){.  multiplex
6230: 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69  Conn *p = (multi
6240: 70 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b  plexConn*)pConn;
6250: 0a 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75  .  multiplexGrou
6260: 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e 70  p *pGroup = p->p
6270: 47 72 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63 20  Group;.  int rc 
6280: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
6290: 66 28 20 21 70 47 72 6f 75 70 2d 3e 62 45 6e 61  f( !pGroup->bEna
62a0: 62 6c 65 64 20 29 7b 0a 20 20 20 20 73 71 6c 69  bled ){.    sqli
62b0: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
62c0: 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75  en = multiplexSu
62d0: 62 4f 70 65 6e 28 70 47 72 6f 75 70 2c 20 30 2c  bOpen(pGroup, 0,
62e0: 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a   &rc, NULL, 0);.
62f0: 20 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e      if( pSubOpen
6300: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
6310: 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 52  = SQLITE_IOERR_R
6320: 45 41 44 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  EAD;.    }else{.
6330: 20 20 20 20 20 20 72 63 20 3d 20 70 53 75 62 4f        rc = pSubO
6340: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
6350: 52 65 61 64 28 70 53 75 62 4f 70 65 6e 2c 20 70  Read(pSubOpen, p
6360: 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74  Buf, iAmt, iOfst
6370: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  );.    }.  }else
6380: 7b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 41 6d  {.    while( iAm
6390: 74 20 3e 20 30 20 29 7b 0a 20 20 20 20 20 20 69  t > 0 ){.      i
63a0: 6e 74 20 69 20 3d 20 28 69 6e 74 29 28 69 4f 66  nt i = (int)(iOf
63b0: 73 74 20 2f 20 70 47 72 6f 75 70 2d 3e 73 7a 43  st / pGroup->szC
63c0: 68 75 6e 6b 29 3b 0a 20 20 20 20 20 20 73 71 6c  hunk);.      sql
63d0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
63e0: 70 65 6e 3b 0a 20 20 20 20 20 20 70 53 75 62 4f  pen;.      pSubO
63f0: 70 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  pen = multiplexS
6400: 75 62 4f 70 65 6e 28 70 47 72 6f 75 70 2c 20 69  ubOpen(pGroup, i
6410: 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 31 29 3b  , &rc, NULL, 1);
6420: 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62 4f  .      if( pSubO
6430: 70 65 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 69  pen ){.        i
6440: 6e 74 20 65 78 74 72 61 20 3d 20 28 28 69 6e 74  nt extra = ((int
6450: 29 28 69 4f 66 73 74 20 25 20 70 47 72 6f 75 70  )(iOfst % pGroup
6460: 2d 3e 73 7a 43 68 75 6e 6b 29 20 2b 20 69 41 6d  ->szChunk) + iAm
6470: 74 29 20 2d 20 70 47 72 6f 75 70 2d 3e 73 7a 43  t) - pGroup->szC
6480: 68 75 6e 6b 3b 0a 20 20 20 20 20 20 20 20 69 66  hunk;.        if
6490: 28 20 65 78 74 72 61 3c 30 20 29 20 65 78 74 72  ( extra<0 ) extr
64a0: 61 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  a = 0;.        i
64b0: 41 6d 74 20 2d 3d 20 65 78 74 72 61 3b 0a 20 20  Amt -= extra;.  
64c0: 20 20 20 20 20 20 72 63 20 3d 20 70 53 75 62 4f        rc = pSubO
64d0: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
64e0: 52 65 61 64 28 70 53 75 62 4f 70 65 6e 2c 20 70  Read(pSubOpen, p
64f0: 42 75 66 2c 20 69 41 6d 74 2c 0a 20 20 20 20 20  Buf, iAmt,.     
6500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6520: 20 20 69 4f 66 73 74 20 25 20 70 47 72 6f 75 70    iOfst % pGroup
6530: 2d 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20 20 20 20  ->szChunk);.    
6540: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
6550: 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
6560: 20 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 63         pBuf = (c
6570: 68 61 72 20 2a 29 70 42 75 66 20 2b 20 69 41 6d  har *)pBuf + iAm
6580: 74 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 73 74  t;.        iOfst
6590: 20 2b 3d 20 69 41 6d 74 3b 0a 20 20 20 20 20 20   += iAmt;.      
65a0: 20 20 69 41 6d 74 20 3d 20 65 78 74 72 61 3b 0a    iAmt = extra;.
65b0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
65c0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
65d0: 5f 49 4f 45 52 52 5f 52 45 41 44 3b 0a 20 20 20  _IOERR_READ;.   
65e0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
65f0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
6600: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
6610: 2a 20 50 61 73 73 20 78 57 72 69 74 65 20 72 65  * Pass xWrite re
6620: 71 75 65 73 74 73 20 74 68 72 75 20 74 6f 20 74  quests thru to t
6630: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
6640: 61 66 74 65 72 0a 2a 2a 20 64 65 74 65 72 6d 69  after.** determi
6650: 6e 69 6e 67 20 74 68 65 20 63 6f 72 72 65 63 74  ning the correct
6660: 20 63 68 75 6e 6b 20 74 6f 20 6f 70 65 72 61 74   chunk to operat
6670: 65 20 6f 6e 2e 0a 2a 2a 20 42 72 65 61 6b 20 75  e on..** Break u
6680: 70 20 77 72 69 74 65 73 20 61 63 72 6f 73 73 20  p writes across 
6690: 63 68 75 6e 6b 20 62 6f 75 6e 64 61 72 69 65 73  chunk boundaries
66a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
66b0: 6d 75 6c 74 69 70 6c 65 78 57 72 69 74 65 28 0a  multiplexWrite(.
66c0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
66d0: 70 43 6f 6e 6e 2c 0a 20 20 63 6f 6e 73 74 20 76  pConn,.  const v
66e0: 6f 69 64 20 2a 70 42 75 66 2c 0a 20 20 69 6e 74  oid *pBuf,.  int
66f0: 20 69 41 6d 74 2c 0a 20 20 73 71 6c 69 74 65 33   iAmt,.  sqlite3
6700: 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a  _int64 iOfst.){.
6710: 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20    multiplexConn 
6720: 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43  *p = (multiplexC
6730: 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 6d 75  onn*)pConn;.  mu
6740: 6c 74 69 70 6c 65 78 47 72 6f 75 70 20 2a 70 47  ltiplexGroup *pG
6750: 72 6f 75 70 20 3d 20 70 2d 3e 70 47 72 6f 75 70  roup = p->pGroup
6760: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
6770: 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 21 70  ITE_OK;.  if( !p
6780: 47 72 6f 75 70 2d 3e 62 45 6e 61 62 6c 65 64 20  Group->bEnabled 
6790: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ){.    sqlite3_f
67a0: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
67b0: 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e  multiplexSubOpen
67c0: 28 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c  (pGroup, 0, &rc,
67d0: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 20 20 69   NULL, 0);.    i
67e0: 66 28 20 70 53 75 62 4f 70 65 6e 3d 3d 30 20 29  f( pSubOpen==0 )
67f0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
6800: 49 54 45 5f 49 4f 45 52 52 5f 57 52 49 54 45 3b  ITE_IOERR_WRITE;
6810: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6820: 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d    rc = pSubOpen-
6830: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57 72 69 74  >pMethods->xWrit
6840: 65 28 70 53 75 62 4f 70 65 6e 2c 20 70 42 75 66  e(pSubOpen, pBuf
6850: 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a  , iAmt, iOfst);.
6860: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
6870: 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51     while( rc==SQ
6880: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 41 6d 74 3e  LITE_OK && iAmt>
6890: 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  0 ){.      int i
68a0: 20 3d 20 28 69 6e 74 29 28 69 4f 66 73 74 20 2f   = (int)(iOfst /
68b0: 20 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b   pGroup->szChunk
68c0: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
68d0: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
68e0: 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70  = multiplexSubOp
68f0: 65 6e 28 70 47 72 6f 75 70 2c 20 69 2c 20 26 72  en(pGroup, i, &r
6900: 63 2c 20 4e 55 4c 4c 2c 20 31 29 3b 0a 20 20 20  c, NULL, 1);.   
6910: 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20     if( pSubOpen 
6920: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 65  ){.        int e
6930: 78 74 72 61 20 3d 20 28 28 69 6e 74 29 28 69 4f  xtra = ((int)(iO
6940: 66 73 74 20 25 20 70 47 72 6f 75 70 2d 3e 73 7a  fst % pGroup->sz
6950: 43 68 75 6e 6b 29 20 2b 20 69 41 6d 74 29 20 2d  Chunk) + iAmt) -
6960: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6970: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 73 7a 43       pGroup->szC
6980: 68 75 6e 6b 3b 0a 20 20 20 20 20 20 20 20 69 66  hunk;.        if
6990: 28 20 65 78 74 72 61 3c 30 20 29 20 65 78 74 72  ( extra<0 ) extr
69a0: 61 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 69  a = 0;.        i
69b0: 41 6d 74 20 2d 3d 20 65 78 74 72 61 3b 0a 20 20  Amt -= extra;.  
69c0: 20 20 20 20 20 20 72 63 20 3d 20 70 53 75 62 4f        rc = pSubO
69d0: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
69e0: 57 72 69 74 65 28 70 53 75 62 4f 70 65 6e 2c 20  Write(pSubOpen, 
69f0: 70 42 75 66 2c 20 69 41 6d 74 2c 0a 20 20 20 20  pBuf, iAmt,.    
6a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a20: 20 20 20 20 69 4f 66 73 74 20 25 20 70 47 72 6f      iOfst % pGro
6a30: 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20 20  up->szChunk);.  
6a40: 20 20 20 20 20 20 70 42 75 66 20 3d 20 28 63 68        pBuf = (ch
6a50: 61 72 20 2a 29 70 42 75 66 20 2b 20 69 41 6d 74  ar *)pBuf + iAmt
6a60: 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 73 74 20  ;.        iOfst 
6a70: 2b 3d 20 69 41 6d 74 3b 0a 20 20 20 20 20 20 20  += iAmt;.       
6a80: 20 69 41 6d 74 20 3d 20 65 78 74 72 61 3b 0a 20   iAmt = extra;. 
6a90: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
6aa0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6ab0: 0a 2f 2a 20 50 61 73 73 20 78 54 72 75 6e 63 61  ./* Pass xTrunca
6ac0: 74 65 20 72 65 71 75 65 73 74 73 20 74 68 72 75  te requests thru
6ad0: 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c   to the original
6ae0: 20 56 46 53 20 61 66 74 65 72 0a 2a 2a 20 64 65   VFS after.** de
6af0: 74 65 72 6d 69 6e 69 6e 67 20 74 68 65 20 63 6f  termining the co
6b00: 72 72 65 63 74 20 63 68 75 6e 6b 20 74 6f 20 6f  rrect chunk to o
6b10: 70 65 72 61 74 65 20 6f 6e 2e 20 20 44 65 6c 65  perate on.  Dele
6b20: 74 65 20 61 6e 79 0a 2a 2a 20 63 68 75 6e 6b 73  te any.** chunks
6b30: 20 61 62 6f 76 65 20 74 68 65 20 74 72 75 6e 63   above the trunc
6b40: 61 74 65 20 6d 61 72 6b 2e 0a 2a 2f 0a 73 74 61  ate mark..*/.sta
6b50: 74 69 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65  tic int multiple
6b60: 78 54 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65  xTruncate(sqlite
6b70: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 73  3_file *pConn, s
6b80: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 69 7a  qlite3_int64 siz
6b90: 65 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43  e){.  multiplexC
6ba0: 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70  onn *p = (multip
6bb0: 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a  lexConn*)pConn;.
6bc0: 20 20 6d 75 6c 74 69 70 6c 65 78 47 72 6f 75 70    multiplexGroup
6bd0: 20 2a 70 47 72 6f 75 70 20 3d 20 70 2d 3e 70 47   *pGroup = p->pG
6be0: 72 6f 75 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d  roup;.  int rc =
6bf0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66   SQLITE_OK;.  if
6c00: 28 20 21 70 47 72 6f 75 70 2d 3e 62 45 6e 61 62  ( !pGroup->bEnab
6c10: 6c 65 64 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  led ){.    sqlit
6c20: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
6c30: 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62  n = multiplexSub
6c40: 4f 70 65 6e 28 70 47 72 6f 75 70 2c 20 30 2c 20  Open(pGroup, 0, 
6c50: 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20  &rc, NULL, 0);. 
6c60: 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 3d     if( pSubOpen=
6c70: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
6c80: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 54 52   SQLITE_IOERR_TR
6c90: 55 4e 43 41 54 45 3b 0a 20 20 20 20 7d 65 6c 73  UNCATE;.    }els
6ca0: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 70 53  e{.      rc = pS
6cb0: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
6cc0: 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 53 75 62  ->xTruncate(pSub
6cd0: 4f 70 65 6e 2c 20 73 69 7a 65 29 3b 0a 20 20 20  Open, size);.   
6ce0: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
6cf0: 69 6e 74 20 69 3b 0a 20 20 20 20 69 6e 74 20 69  int i;.    int i
6d00: 42 61 73 65 47 72 6f 75 70 20 3d 20 28 69 6e 74  BaseGroup = (int
6d10: 29 28 73 69 7a 65 20 2f 20 70 47 72 6f 75 70 2d  )(size / pGroup-
6d20: 3e 73 7a 43 68 75 6e 6b 29 3b 0a 20 20 20 20 73  >szChunk);.    s
6d30: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
6d40: 62 4f 70 65 6e 3b 0a 20 20 20 20 73 71 6c 69 74  bOpen;.    sqlit
6d50: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
6d60: 20 3d 20 67 4d 75 6c 74 69 70 6c 65 78 2e 70 4f   = gMultiplex.pO
6d70: 72 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61  rigVfs;   /* Rea
6d80: 6c 20 56 46 53 20 2a 2f 0a 20 20 20 20 2f 2a 20  l VFS */.    /* 
6d90: 64 65 6c 65 74 65 20 74 68 65 20 63 68 75 6e 6b  delete the chunk
6da0: 73 20 61 62 6f 76 65 20 74 68 65 20 74 72 75 6e  s above the trun
6db0: 63 61 74 65 20 6c 69 6d 69 74 20 2a 2f 0a 20 20  cate limit */.  
6dc0: 20 20 66 6f 72 28 69 20 3d 20 70 47 72 6f 75 70    for(i = pGroup
6dd0: 2d 3e 6e 52 65 61 6c 2d 31 3b 20 69 3e 69 42 61  ->nReal-1; i>iBa
6de0: 73 65 47 72 6f 75 70 20 26 26 20 72 63 3d 3d 53  seGroup && rc==S
6df0: 51 4c 49 54 45 5f 4f 4b 3b 20 69 2d 2d 29 7b 0a  QLITE_OK; i--){.
6e00: 20 20 20 20 20 20 69 66 28 20 70 47 72 6f 75 70        if( pGroup
6e10: 2d 3e 62 54 72 75 6e 63 61 74 65 20 29 7b 0a 20  ->bTruncate ){. 
6e20: 20 20 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78         multiplex
6e30: 53 75 62 43 6c 6f 73 65 28 70 47 72 6f 75 70 2c  SubClose(pGroup,
6e40: 20 69 2c 20 70 4f 72 69 67 56 66 73 29 3b 0a 20   i, pOrigVfs);. 
6e50: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
6e60: 20 20 20 20 70 53 75 62 4f 70 65 6e 20 3d 20 6d      pSubOpen = m
6e70: 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28  ultiplexSubOpen(
6e80: 70 47 72 6f 75 70 2c 20 69 2c 20 26 72 63 2c 20  pGroup, i, &rc, 
6e90: 30 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 69  0, 0);.        i
6ea0: 66 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20  f( pSubOpen ){. 
6eb0: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 53           rc = pS
6ec0: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
6ed0: 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 53 75 62  ->xTruncate(pSub
6ee0: 4f 70 65 6e 2c 20 30 29 3b 0a 20 20 20 20 20 20  Open, 0);.      
6ef0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
6f00: 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  }.    if( rc==SQ
6f10: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
6f20: 20 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74   pSubOpen = mult
6f30: 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 47 72  iplexSubOpen(pGr
6f40: 6f 75 70 2c 20 69 42 61 73 65 47 72 6f 75 70 2c  oup, iBaseGroup,
6f50: 20 26 72 63 2c 20 30 2c 20 30 29 3b 0a 20 20 20   &rc, 0, 0);.   
6f60: 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20     if( pSubOpen 
6f70: 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
6f80: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
6f90: 64 73 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 53  ds->xTruncate(pS
6fa0: 75 62 4f 70 65 6e 2c 20 73 69 7a 65 20 25 20 70  ubOpen, size % p
6fb0: 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b 29 3b  Group->szChunk);
6fc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
6fd0: 20 20 20 69 66 28 20 72 63 20 29 20 72 63 20 3d     if( rc ) rc =
6fe0: 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 54 52   SQLITE_IOERR_TR
6ff0: 55 4e 43 41 54 45 3b 0a 20 20 7d 0a 20 20 72 65  UNCATE;.  }.  re
7000: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50  turn rc;.}../* P
7010: 61 73 73 20 78 53 79 6e 63 20 72 65 71 75 65 73  ass xSync reques
7020: 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68  ts through to th
7030: 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 77  e original VFS w
7040: 69 74 68 6f 75 74 20 63 68 61 6e 67 65 0a 2a 2f  ithout change.*/
7050: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
7060: 69 70 6c 65 78 53 79 6e 63 28 73 71 6c 69 74 65  iplexSync(sqlite
7070: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
7080: 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20 6d 75 6c  nt flags){.  mul
7090: 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20  tiplexConn *p = 
70a0: 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29  (multiplexConn*)
70b0: 70 43 6f 6e 6e 3b 0a 20 20 6d 75 6c 74 69 70 6c  pConn;.  multipl
70c0: 65 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20  exGroup *pGroup 
70d0: 3d 20 70 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 69  = p->pGroup;.  i
70e0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
70f0: 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f  K;.  int i;.  fo
7100: 72 28 69 3d 30 3b 20 69 3c 70 47 72 6f 75 70 2d  r(i=0; i<pGroup-
7110: 3e 6e 52 65 61 6c 3b 20 69 2b 2b 29 7b 0a 20 20  >nReal; i++){.  
7120: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
7130: 70 53 75 62 4f 70 65 6e 20 3d 20 70 47 72 6f 75  pSubOpen = pGrou
7140: 70 2d 3e 61 52 65 61 6c 5b 69 5d 2e 70 3b 0a 20  p->aReal[i].p;. 
7150: 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20     if( pSubOpen 
7160: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 32  ){.      int rc2
7170: 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65   = pSubOpen->pMe
7180: 74 68 6f 64 73 2d 3e 78 53 79 6e 63 28 70 53 75  thods->xSync(pSu
7190: 62 4f 70 65 6e 2c 20 66 6c 61 67 73 29 3b 0a 20  bOpen, flags);. 
71a0: 20 20 20 20 20 69 66 28 20 72 63 32 21 3d 53 51       if( rc2!=SQ
71b0: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72  LITE_OK ) rc = r
71c0: 63 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  c2;.    }.  }.  
71d0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
71e0: 20 50 61 73 73 20 78 46 69 6c 65 53 69 7a 65 20   Pass xFileSize 
71f0: 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68  requests through
7200: 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c   to the original
7210: 20 56 46 53 2e 0a 2a 2a 20 41 67 67 72 65 67 61   VFS..** Aggrega
7220: 74 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20 61  te the size of a
7230: 6c 6c 20 74 68 65 20 63 68 75 6e 6b 73 20 62 65  ll the chunks be
7240: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
7250: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75  */.static int mu
7260: 6c 74 69 70 6c 65 78 46 69 6c 65 53 69 7a 65 28  ltiplexFileSize(
7270: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
7280: 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  onn, sqlite3_int
7290: 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20 6d 75  64 *pSize){.  mu
72a0: 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d  ltiplexConn *p =
72b0: 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a   (multiplexConn*
72c0: 29 70 43 6f 6e 6e 3b 0a 20 20 6d 75 6c 74 69 70  )pConn;.  multip
72d0: 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  lexGroup *pGroup
72e0: 20 3d 20 70 2d 3e 70 47 72 6f 75 70 3b 0a 20 20   = p->pGroup;.  
72f0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7300: 4f 4b 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  OK;.  int i;.  i
7310: 66 28 20 21 70 47 72 6f 75 70 2d 3e 62 45 6e 61  f( !pGroup->bEna
7320: 62 6c 65 64 20 29 7b 0a 20 20 20 20 73 71 6c 69  bled ){.    sqli
7330: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
7340: 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75  en = multiplexSu
7350: 62 4f 70 65 6e 28 70 47 72 6f 75 70 2c 20 30 2c  bOpen(pGroup, 0,
7360: 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a   &rc, NULL, 0);.
7370: 20 20 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e      if( pSubOpen
7380: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
7390: 3d 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 46  = SQLITE_IOERR_F
73a0: 53 54 41 54 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  STAT;.    }else{
73b0: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 53 75 62  .      rc = pSub
73c0: 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Open->pMethods->
73d0: 78 46 69 6c 65 53 69 7a 65 28 70 53 75 62 4f 70  xFileSize(pSubOp
73e0: 65 6e 2c 20 70 53 69 7a 65 29 3b 0a 20 20 20 20  en, pSize);.    
73f0: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a  }.  }else{.    *
7400: 70 53 69 7a 65 20 3d 20 30 3b 0a 20 20 20 20 66  pSize = 0;.    f
7410: 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  or(i=0; rc==SQLI
7420: 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20  TE_OK; i++){.   
7430: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
7440: 20 73 7a 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53   sz = multiplexS
7450: 75 62 53 69 7a 65 28 70 47 72 6f 75 70 2c 20 69  ubSize(pGroup, i
7460: 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 69 66  , &rc);.      if
7470: 28 20 73 7a 3d 3d 30 20 29 20 62 72 65 61 6b 3b  ( sz==0 ) break;
7480: 0a 20 20 20 20 20 20 2a 70 53 69 7a 65 20 3d 20  .      *pSize = 
7490: 69 2a 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  i*(sqlite3_int64
74a0: 29 70 47 72 6f 75 70 2d 3e 73 7a 43 68 75 6e 6b  )pGroup->szChunk
74b0: 20 2b 20 73 7a 3b 0a 20 20 20 20 7d 0a 20 20 7d   + sz;.    }.  }
74c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
74d0: 0a 2f 2a 20 50 61 73 73 20 78 4c 6f 63 6b 20 72  ./* Pass xLock r
74e0: 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20  equests through 
74f0: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
7500: 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a  VFS unchanged..*
7510: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c  /.static int mul
7520: 74 69 70 6c 65 78 4c 6f 63 6b 28 73 71 6c 69 74  tiplexLock(sqlit
7530: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20  e3_file *pConn, 
7540: 69 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 6d 75 6c  int lock){.  mul
7550: 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20  tiplexConn *p = 
7560: 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29  (multiplexConn*)
7570: 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63 3b  pConn;.  int rc;
7580: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
7590: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74  *pSubOpen = mult
75a0: 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d 3e  iplexSubOpen(p->
75b0: 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20  pGroup, 0, &rc, 
75c0: 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20  NULL, 0);.  if( 
75d0: 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20  pSubOpen ){.    
75e0: 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d  return pSubOpen-
75f0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 4c 6f 63 6b  >pMethods->xLock
7600: 28 70 53 75 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29  (pSubOpen, lock)
7610: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
7620: 51 4c 49 54 45 5f 42 55 53 59 3b 0a 7d 0a 0a 2f  QLITE_BUSY;.}../
7630: 2a 20 50 61 73 73 20 78 55 6e 6c 6f 63 6b 20 72  * Pass xUnlock r
7640: 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20  equests through 
7650: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
7660: 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a  VFS unchanged..*
7670: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c  /.static int mul
7680: 74 69 70 6c 65 78 55 6e 6c 6f 63 6b 28 73 71 6c  tiplexUnlock(sql
7690: 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e  ite3_file *pConn
76a0: 2c 20 69 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 6d  , int lock){.  m
76b0: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20  ultiplexConn *p 
76c0: 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e  = (multiplexConn
76d0: 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72  *)pConn;.  int r
76e0: 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  c;.  sqlite3_fil
76f0: 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75  e *pSubOpen = mu
7700: 6c 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70  ltiplexSubOpen(p
7710: 2d 3e 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63  ->pGroup, 0, &rc
7720: 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 69 66  , NULL, 0);.  if
7730: 28 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20  ( pSubOpen ){.  
7740: 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65    return pSubOpe
7750: 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 55 6e  n->pMethods->xUn
7760: 6c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6c  lock(pSubOpen, l
7770: 6f 63 6b 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ock);.  }.  retu
7780: 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f  rn SQLITE_IOERR_
7790: 55 4e 4c 4f 43 4b 3b 0a 7d 0a 0a 2f 2a 20 50 61  UNLOCK;.}../* Pa
77a0: 73 73 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  ss xCheckReserve
77b0: 64 4c 6f 63 6b 20 72 65 71 75 65 73 74 73 20 74  dLock requests t
77c0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
77d0: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
77e0: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
77f0: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 43 68 65  int multiplexChe
7800: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 73  ckReservedLock(s
7810: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
7820: 6e 6e 2c 20 69 6e 74 20 2a 70 52 65 73 4f 75 74  nn, int *pResOut
7830: 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f  ){.  multiplexCo
7840: 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c  nn *p = (multipl
7850: 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  exConn*)pConn;. 
7860: 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74   int rc;.  sqlit
7870: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
7880: 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62  n = multiplexSub
7890: 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75 70 2c 20  Open(p->pGroup, 
78a0: 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29  0, &rc, NULL, 0)
78b0: 3b 0a 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e  ;.  if( pSubOpen
78c0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
78d0: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
78e0: 73 2d 3e 78 43 68 65 63 6b 52 65 73 65 72 76 65  s->xCheckReserve
78f0: 64 4c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20  dLock(pSubOpen, 
7900: 70 52 65 73 4f 75 74 29 3b 0a 20 20 7d 0a 20 20  pResOut);.  }.  
7910: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 49 4f  return SQLITE_IO
7920: 45 52 52 5f 43 48 45 43 4b 52 45 53 45 52 56 45  ERR_CHECKRESERVE
7930: 44 4c 4f 43 4b 3b 0a 7d 0a 0a 2f 2a 20 50 61 73  DLOCK;.}../* Pas
7940: 73 20 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 72  s xFileControl r
7950: 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20  equests through 
7960: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
7970: 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2c 0a 2a  VFS unchanged,.*
7980: 2a 20 65 78 63 65 70 74 20 66 6f 72 20 61 6e 79  * except for any
7990: 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54 52 4c 5f   MULTIPLEX_CTRL_
79a0: 2a 20 72 65 71 75 65 73 74 73 20 68 65 72 65 2e  * requests here.
79b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d  .*/.static int m
79c0: 75 6c 74 69 70 6c 65 78 46 69 6c 65 43 6f 6e 74  ultiplexFileCont
79d0: 72 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  rol(sqlite3_file
79e0: 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 6f 70 2c   *pConn, int op,
79f0: 20 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20 20   void *pArg){.  
7a00: 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70  multiplexConn *p
7a10: 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e   = (multiplexCon
7a20: 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 6d 75 6c 74  n*)pConn;.  mult
7a30: 69 70 6c 65 78 47 72 6f 75 70 20 2a 70 47 72 6f  iplexGroup *pGro
7a40: 75 70 20 3d 20 70 2d 3e 70 47 72 6f 75 70 3b 0a  up = p->pGroup;.
7a50: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
7a60: 45 5f 45 52 52 4f 52 3b 0a 20 20 73 71 6c 69 74  E_ERROR;.  sqlit
7a70: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
7a80: 6e 3b 0a 0a 20 20 69 66 28 20 21 67 4d 75 6c 74  n;..  if( !gMult
7a90: 69 70 6c 65 78 2e 69 73 49 6e 69 74 69 61 6c 69  iplex.isInitiali
7aa0: 7a 65 64 20 29 20 72 65 74 75 72 6e 20 53 51 4c  zed ) return SQL
7ab0: 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 73 77  ITE_MISUSE;.  sw
7ac0: 69 74 63 68 28 20 6f 70 20 29 7b 0a 20 20 20 20  itch( op ){.    
7ad0: 63 61 73 65 20 4d 55 4c 54 49 50 4c 45 58 5f 43  case MULTIPLEX_C
7ae0: 54 52 4c 5f 45 4e 41 42 4c 45 3a 0a 20 20 20 20  TRL_ENABLE:.    
7af0: 20 20 69 66 28 20 70 41 72 67 20 29 20 7b 0a 20    if( pArg ) {. 
7b00: 20 20 20 20 20 20 20 69 6e 74 20 62 45 6e 61 62         int bEnab
7b10: 6c 65 64 20 3d 20 2a 28 69 6e 74 20 2a 29 70 41  led = *(int *)pA
7b20: 72 67 3b 0a 20 20 20 20 20 20 20 20 70 47 72 6f  rg;.        pGro
7b30: 75 70 2d 3e 62 45 6e 61 62 6c 65 64 20 3d 20 28  up->bEnabled = (
7b40: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 29 62 45  unsigned char)bE
7b50: 6e 61 62 6c 65 64 3b 0a 20 20 20 20 20 20 20 20  nabled;.        
7b60: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
7b70: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
7b80: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 4d 55  eak;.    case MU
7b90: 4c 54 49 50 4c 45 58 5f 43 54 52 4c 5f 53 45 54  LTIPLEX_CTRL_SET
7ba0: 5f 43 48 55 4e 4b 5f 53 49 5a 45 3a 0a 20 20 20  _CHUNK_SIZE:.   
7bb0: 20 20 20 69 66 28 20 70 41 72 67 20 29 20 7b 0a     if( pArg ) {.
7bc0: 20 20 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64          unsigned
7bd0: 20 69 6e 74 20 73 7a 43 68 75 6e 6b 20 3d 20 2a   int szChunk = *
7be0: 28 75 6e 73 69 67 6e 65 64 2a 29 70 41 72 67 3b  (unsigned*)pArg;
7bf0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 73 7a 43  .        if( szC
7c00: 68 75 6e 6b 3c 31 20 29 7b 0a 20 20 20 20 20 20  hunk<1 ){.      
7c10: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
7c20: 4d 49 53 55 53 45 3b 0a 20 20 20 20 20 20 20 20  MISUSE;.        
7c30: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
7c40: 20 2f 2a 20 52 6f 75 6e 64 20 75 70 20 74 6f 20   /* Round up to 
7c50: 6e 65 61 72 65 73 74 20 6d 75 6c 74 69 70 6c 65  nearest multiple
7c60: 20 6f 66 20 4d 41 58 5f 50 41 47 45 5f 53 49 5a   of MAX_PAGE_SIZ
7c70: 45 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  E. */.          
7c80: 73 7a 43 68 75 6e 6b 20 3d 20 28 73 7a 43 68 75  szChunk = (szChu
7c90: 6e 6b 20 2b 20 28 4d 41 58 5f 50 41 47 45 5f 53  nk + (MAX_PAGE_S
7ca0: 49 5a 45 2d 31 29 29 3b 0a 20 20 20 20 20 20 20  IZE-1));.       
7cb0: 20 20 20 73 7a 43 68 75 6e 6b 20 26 3d 20 7e 28     szChunk &= ~(
7cc0: 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45 2d 31 29  MAX_PAGE_SIZE-1)
7cd0: 3b 0a 20 20 20 20 20 20 20 20 20 20 70 47 72 6f  ;.          pGro
7ce0: 75 70 2d 3e 73 7a 43 68 75 6e 6b 20 3d 20 73 7a  up->szChunk = sz
7cf0: 43 68 75 6e 6b 3b 0a 20 20 20 20 20 20 20 20 20  Chunk;.         
7d00: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
7d10: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
7d20: 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a   }.      break;.
7d30: 20 20 20 20 63 61 73 65 20 4d 55 4c 54 49 50 4c      case MULTIPL
7d40: 45 58 5f 43 54 52 4c 5f 53 45 54 5f 4d 41 58 5f  EX_CTRL_SET_MAX_
7d50: 43 48 55 4e 4b 53 3a 0a 20 20 20 20 20 20 72 63  CHUNKS:.      rc
7d60: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
7d70: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63      break;.    c
7d80: 61 73 65 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c  ase SQLITE_FCNTL
7d90: 5f 53 49 5a 45 5f 48 49 4e 54 3a 0a 20 20 20 20  _SIZE_HINT:.    
7da0: 63 61 73 65 20 53 51 4c 49 54 45 5f 46 43 4e 54  case SQLITE_FCNT
7db0: 4c 5f 43 48 55 4e 4b 5f 53 49 5a 45 3a 0a 20 20  L_CHUNK_SIZE:.  
7dc0: 20 20 20 20 2f 2a 20 6e 6f 2d 6f 70 20 74 68 65      /* no-op the
7dd0: 73 65 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  se */.      rc =
7de0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
7df0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
7e00: 65 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 50  e SQLITE_FCNTL_P
7e10: 52 41 47 4d 41 3a 20 7b 0a 20 20 20 20 20 20 63  RAGMA: {.      c
7e20: 68 61 72 20 2a 2a 61 46 63 6e 74 6c 20 3d 20 28  har **aFcntl = (
7e30: 63 68 61 72 2a 2a 29 70 41 72 67 3b 0a 20 20 20  char**)pArg;.   
7e40: 20 20 20 2f 2a 0a 20 20 20 20 20 20 2a 2a 20 45     /*.      ** E
7e50: 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 32 39  VIDENCE-OF: R-29
7e60: 38 37 35 2d 33 31 36 37 38 20 54 68 65 20 61 72  875-31678 The ar
7e70: 67 75 6d 65 6e 74 20 74 6f 20 74 68 65 20 53 51  gument to the SQ
7e80: 4c 49 54 45 5f 46 43 4e 54 4c 5f 50 52 41 47 4d  LITE_FCNTL_PRAGM
7e90: 41 0a 20 20 20 20 20 20 2a 2a 20 66 69 6c 65 20  A.      ** file 
7ea0: 63 6f 6e 74 72 6f 6c 20 69 73 20 61 6e 20 61 72  control is an ar
7eb0: 72 61 79 20 6f 66 20 70 6f 69 6e 74 65 72 73 20  ray of pointers 
7ec0: 74 6f 20 73 74 72 69 6e 67 73 20 28 63 68 61 72  to strings (char
7ed0: 2a 2a 29 20 69 6e 20 77 68 69 63 68 20 74 68 65  **) in which the
7ee0: 0a 20 20 20 20 20 20 2a 2a 20 73 65 63 6f 6e 64  .      ** second
7ef0: 20 65 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65 20   element of the 
7f00: 61 72 72 61 79 20 69 73 20 74 68 65 20 6e 61 6d  array is the nam
7f10: 65 20 6f 66 20 74 68 65 20 70 72 61 67 6d 61 20  e of the pragma 
7f20: 61 6e 64 20 74 68 65 20 74 68 69 72 64 0a 20 20  and the third.  
7f30: 20 20 20 20 2a 2a 20 65 6c 65 6d 65 6e 74 20 69      ** element i
7f40: 73 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 74  s the argument t
7f50: 6f 20 74 68 65 20 70 72 61 67 6d 61 20 6f 72 20  o the pragma or 
7f60: 4e 55 4c 4c 20 69 66 20 74 68 65 20 70 72 61 67  NULL if the prag
7f70: 6d 61 20 68 61 73 20 6e 6f 0a 20 20 20 20 20 20  ma has no.      
7f80: 2a 2a 20 61 72 67 75 6d 65 6e 74 2e 0a 20 20 20  ** argument..   
7f90: 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20     */.      if( 
7fa0: 61 46 63 6e 74 6c 5b 31 5d 20 26 26 20 73 71 6c  aFcntl[1] && sql
7fb0: 69 74 65 33 5f 73 74 72 69 63 6d 70 28 61 46 63  ite3_stricmp(aFc
7fc0: 6e 74 6c 5b 31 5d 2c 22 6d 75 6c 74 69 70 6c 65  ntl[1],"multiple
7fd0: 78 5f 74 72 75 6e 63 61 74 65 22 29 3d 3d 30 20  x_truncate")==0 
7fe0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61  ){.        if( a
7ff0: 46 63 6e 74 6c 5b 32 5d 20 26 26 20 61 46 63 6e  Fcntl[2] && aFcn
8000: 74 6c 5b 32 5d 5b 30 5d 20 29 7b 0a 20 20 20 20  tl[2][0] ){.    
8010: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
8020: 33 5f 73 74 72 69 63 6d 70 28 61 46 63 6e 74 6c  3_stricmp(aFcntl
8030: 5b 32 5d 2c 20 22 6f 6e 22 29 3d 3d 30 0a 20 20  [2], "on")==0.  
8040: 20 20 20 20 20 20 20 20 20 7c 7c 20 73 71 6c 69           || sqli
8050: 74 65 33 5f 73 74 72 69 63 6d 70 28 61 46 63 6e  te3_stricmp(aFcn
8060: 74 6c 5b 32 5d 2c 20 22 31 22 29 3d 3d 30 20 29  tl[2], "1")==0 )
8070: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 47  {.            pG
8080: 72 6f 75 70 2d 3e 62 54 72 75 6e 63 61 74 65 20  roup->bTruncate 
8090: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  = 1;.          }
80a0: 65 6c 73 65 0a 20 20 20 20 20 20 20 20 20 20 69  else.          i
80b0: 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63  f( sqlite3_stric
80c0: 6d 70 28 61 46 63 6e 74 6c 5b 32 5d 2c 20 22 6f  mp(aFcntl[2], "o
80d0: 66 66 22 29 3d 3d 30 0a 20 20 20 20 20 20 20 20  ff")==0.        
80e0: 20 20 20 7c 7c 20 73 71 6c 69 74 65 33 5f 73 74     || sqlite3_st
80f0: 72 69 63 6d 70 28 61 46 63 6e 74 6c 5b 32 5d 2c  ricmp(aFcntl[2],
8100: 20 22 30 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20   "0")==0 ){.    
8110: 20 20 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e          pGroup->
8120: 62 54 72 75 6e 63 61 74 65 20 3d 20 30 3b 0a 20  bTruncate = 0;. 
8130: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
8140: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 2f 2a 20     }.        /* 
8150: 45 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 32  EVIDENCE-OF: R-2
8160: 37 38 30 36 2d 32 36 30 37 36 20 54 68 65 20 68  7806-26076 The h
8170: 61 6e 64 6c 65 72 20 66 6f 72 20 61 6e 20 53 51  andler for an SQ
8180: 4c 49 54 45 5f 46 43 4e 54 4c 5f 50 52 41 47 4d  LITE_FCNTL_PRAGM
8190: 41 0a 20 20 20 20 20 20 20 20 2a 2a 20 66 69 6c  A.        ** fil
81a0: 65 20 63 6f 6e 74 72 6f 6c 20 63 61 6e 20 6f 70  e control can op
81b0: 74 69 6f 6e 61 6c 6c 79 20 6d 61 6b 65 20 74 68  tionally make th
81c0: 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20  e first element 
81d0: 6f 66 20 74 68 65 20 63 68 61 72 2a 2a 0a 20 20  of the char**.  
81e0: 20 20 20 20 20 20 2a 2a 20 61 72 67 75 6d 65 6e        ** argumen
81f0: 74 20 70 6f 69 6e 74 20 74 6f 20 61 20 73 74 72  t point to a str
8200: 69 6e 67 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  ing obtained fro
8210: 6d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  m sqlite3_mprint
8220: 66 28 29 20 6f 72 20 74 68 65 0a 20 20 20 20 20  f() or the.     
8230: 20 20 20 2a 2a 20 65 71 75 69 76 61 6c 65 6e 74     ** equivalent
8240: 20 61 6e 64 20 74 68 61 74 20 73 74 72 69 6e 67   and that string
8250: 20 77 69 6c 6c 20 62 65 63 6f 6d 65 20 74 68 65   will become the
8260: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 65 20 70   result of the p
8270: 72 61 67 6d 61 0a 20 20 20 20 20 20 20 20 2a 2a  ragma.        **
8280: 20 6f 72 20 74 68 65 20 65 72 72 6f 72 20 6d 65   or the error me
8290: 73 73 61 67 65 20 69 66 20 74 68 65 20 70 72 61  ssage if the pra
82a0: 67 6d 61 20 66 61 69 6c 73 2e 0a 20 20 20 20 20  gma fails..     
82b0: 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 61 46     */.        aF
82c0: 63 6e 74 6c 5b 30 5d 20 3d 20 73 71 6c 69 74 65  cntl[0] = sqlite
82d0: 33 5f 6d 70 72 69 6e 74 66 28 70 47 72 6f 75 70  3_mprintf(pGroup
82e0: 2d 3e 62 54 72 75 6e 63 61 74 65 20 3f 20 22 6f  ->bTruncate ? "o
82f0: 6e 22 20 3a 20 22 6f 66 66 22 29 3b 0a 20 20 20  n" : "off");.   
8300: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
8310: 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 20 62 72 65  _OK;.        bre
8320: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
8330: 20 20 2f 2a 20 49 66 20 74 68 65 20 6d 75 6c 74    /* If the mult
8340: 69 70 6c 65 78 6f 72 20 64 6f 65 73 20 6e 6f 74  iplexor does not
8350: 20 68 61 6e 64 6c 65 20 74 68 65 20 70 72 61 67   handle the prag
8360: 6d 61 2c 20 70 61 73 73 20 69 74 20 74 68 72 6f  ma, pass it thro
8370: 75 67 68 0a 20 20 20 20 20 20 2a 2a 20 69 6e 74  ugh.      ** int
8380: 6f 20 74 68 65 20 64 65 66 61 75 6c 74 20 63 61  o the default ca
8390: 73 65 2e 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 20  se. */.    }.   
83a0: 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20   default:.      
83b0: 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69  pSubOpen = multi
83c0: 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 47 72 6f  plexSubOpen(pGro
83d0: 75 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c  up, 0, &rc, NULL
83e0: 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 0);.      if( 
83f0: 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20  pSubOpen ){.    
8400: 20 20 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65      rc = pSubOpe
8410: 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69  n->pMethods->xFi
8420: 6c 65 43 6f 6e 74 72 6f 6c 28 70 53 75 62 4f 70  leControl(pSubOp
8430: 65 6e 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 20  en, op, pArg);. 
8440: 20 20 20 20 20 20 20 69 66 28 20 6f 70 3d 3d 53         if( op==S
8450: 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 56 46 53 4e  QLITE_FCNTL_VFSN
8460: 41 4d 45 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  AME && rc==SQLIT
8470: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
8480: 20 2a 28 63 68 61 72 2a 2a 29 70 41 72 67 20 3d   *(char**)pArg =
8490: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
84a0: 28 22 6d 75 6c 74 69 70 6c 65 78 2f 25 7a 22 2c  ("multiplex/%z",
84b0: 20 2a 28 63 68 61 72 2a 2a 29 70 41 72 67 29 3b   *(char**)pArg);
84c0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
84d0: 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a   }.      break;.
84e0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
84f0: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 65 63  .}../* Pass xSec
8500: 74 6f 72 53 69 7a 65 20 72 65 71 75 65 73 74 73  torSize requests
8510: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20   through to the 
8520: 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63  original VFS unc
8530: 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  hanged..*/.stati
8540: 63 20 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53  c int multiplexS
8550: 65 63 74 6f 72 53 69 7a 65 28 73 71 6c 69 74 65  ectorSize(sqlite
8560: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a  3_file *pConn){.
8570: 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 20    multiplexConn 
8580: 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78 43  *p = (multiplexC
8590: 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69 6e  onn*)pConn;.  in
85a0: 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f  t rc;.  sqlite3_
85b0: 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d  file *pSubOpen =
85c0: 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70 65   multiplexSubOpe
85d0: 6e 28 70 2d 3e 70 47 72 6f 75 70 2c 20 30 2c 20  n(p->pGroup, 0, 
85e0: 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20  &rc, NULL, 0);. 
85f0: 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20 26 26   if( pSubOpen &&
8600: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
8610: 6f 64 73 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65  ods->xSectorSize
8620: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
8630: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
8640: 73 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65 28 70  s->xSectorSize(p
8650: 53 75 62 4f 70 65 6e 29 3b 0a 20 20 7d 0a 20 20  SubOpen);.  }.  
8660: 72 65 74 75 72 6e 20 44 45 46 41 55 4c 54 5f 53  return DEFAULT_S
8670: 45 43 54 4f 52 5f 53 49 5a 45 3b 0a 7d 0a 0a 2f  ECTOR_SIZE;.}../
8680: 2a 20 50 61 73 73 20 78 44 65 76 69 63 65 43 68  * Pass xDeviceCh
8690: 61 72 61 63 74 65 72 69 73 74 69 63 73 20 72 65  aracteristics re
86a0: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
86b0: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
86c0: 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f  FS unchanged..*/
86d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 75 6c 74  .static int mult
86e0: 69 70 6c 65 78 44 65 76 69 63 65 43 68 61 72 61  iplexDeviceChara
86f0: 63 74 65 72 69 73 74 69 63 73 28 73 71 6c 69 74  cteristics(sqlit
8700: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b  e3_file *pConn){
8710: 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e  .  multiplexConn
8720: 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70 6c 65 78   *p = (multiplex
8730: 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 69  Conn*)pConn;.  i
8740: 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33  nt rc;.  sqlite3
8750: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
8760: 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75 62 4f 70  = multiplexSubOp
8770: 65 6e 28 70 2d 3e 70 47 72 6f 75 70 2c 20 30 2c  en(p->pGroup, 0,
8780: 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a   &rc, NULL, 0);.
8790: 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 20 29    if( pSubOpen )
87a0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 53 75  {.    return pSu
87b0: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
87c0: 3e 78 44 65 76 69 63 65 43 68 61 72 61 63 74 65  >xDeviceCharacte
87d0: 72 69 73 74 69 63 73 28 70 53 75 62 4f 70 65 6e  ristics(pSubOpen
87e0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
87f0: 30 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53  0;.}../* Pass xS
8800: 68 6d 4d 61 70 20 72 65 71 75 65 73 74 73 20 74  hmMap requests t
8810: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
8820: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
8830: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
8840: 69 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53 68 6d  int multiplexShm
8850: 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33 5f 66  Map(.  sqlite3_f
8860: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20 20  ile *pConn,     
8870: 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64 6c 65         /* Handle
8880: 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62 61 73   open on databas
8890: 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  e file */.  int 
88a0: 69 52 65 67 69 6f 6e 2c 20 20 20 20 20 20 20 20  iRegion,        
88b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
88c0: 65 67 69 6f 6e 20 74 6f 20 72 65 74 72 69 65 76  egion to retriev
88d0: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 52 65 67  e */.  int szReg
88e0: 69 6f 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  ion,            
88f0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
8900: 66 20 72 65 67 69 6f 6e 73 20 2a 2f 0a 20 20 69  f regions */.  i
8910: 6e 74 20 62 45 78 74 65 6e 64 2c 20 20 20 20 20  nt bExtend,     
8920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8930: 2a 20 54 72 75 65 20 74 6f 20 65 78 74 65 6e 64  * True to extend
8940: 20 66 69 6c 65 20 69 66 20 6e 65 63 65 73 73 61   file if necessa
8950: 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f 6c  ry */.  void vol
8960: 61 74 69 6c 65 20 2a 2a 70 70 20 20 20 20 20 20  atile **pp      
8970: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
8980: 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a 2f  Mapped memory */
8990: 0a 29 7b 0a 20 20 6d 75 6c 74 69 70 6c 65 78 43  .){.  multiplexC
89a0: 6f 6e 6e 20 2a 70 20 3d 20 28 6d 75 6c 74 69 70  onn *p = (multip
89b0: 6c 65 78 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a  lexConn*)pConn;.
89c0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c 69    int rc;.  sqli
89d0: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
89e0: 65 6e 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53 75  en = multiplexSu
89f0: 62 4f 70 65 6e 28 70 2d 3e 70 47 72 6f 75 70 2c  bOpen(p->pGroup,
8a00: 20 30 2c 20 26 72 63 2c 20 4e 55 4c 4c 2c 20 30   0, &rc, NULL, 0
8a10: 29 3b 0a 20 20 69 66 28 20 70 53 75 62 4f 70 65  );.  if( pSubOpe
8a20: 6e 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  n ){.    return 
8a30: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
8a40: 64 73 2d 3e 78 53 68 6d 4d 61 70 28 70 53 75 62  ds->xShmMap(pSub
8a50: 4f 70 65 6e 2c 20 69 52 65 67 69 6f 6e 2c 20 73  Open, iRegion, s
8a60: 7a 52 65 67 69 6f 6e 2c 20 62 45 78 74 65 6e 64  zRegion, bExtend
8a70: 2c 70 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ,pp);.  }.  retu
8a80: 72 6e 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 3b  rn SQLITE_IOERR;
8a90: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d  .}../* Pass xShm
8aa0: 4c 6f 63 6b 20 72 65 71 75 65 73 74 73 20 74 68  Lock requests th
8ab0: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69  rough to the ori
8ac0: 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e  ginal VFS unchan
8ad0: 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ged..*/.static i
8ae0: 6e 74 20 6d 75 6c 74 69 70 6c 65 78 53 68 6d 4c  nt multiplexShmL
8af0: 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 66  ock(.  sqlite3_f
8b00: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20 20  ile *pConn,     
8b10: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 66 69    /* Database fi
8b20: 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 73  le holding the s
8b30: 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a  hared memory */.
8b40: 20 20 69 6e 74 20 6f 66 73 74 2c 20 20 20 20 20    int ofst,     
8b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8b60: 46 69 72 73 74 20 6c 6f 63 6b 20 74 6f 20 61 63  First lock to ac
8b70: 71 75 69 72 65 20 6f 72 20 72 65 6c 65 61 73 65  quire or release
8b80: 20 2a 2f 0a 20 20 69 6e 74 20 6e 2c 20 20 20 20   */.  int n,    
8b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ba0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6c 6f   /* Number of lo
8bb0: 63 6b 73 20 74 6f 20 61 63 71 75 69 72 65 20 6f  cks to acquire o
8bc0: 72 20 72 65 6c 65 61 73 65 20 2a 2f 0a 20 20 69  r release */.  i
8bd0: 6e 74 20 66 6c 61 67 73 20 20 20 20 20 20 20 20  nt flags        
8be0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 68 61            /* Wha
8bf0: 74 20 74 6f 20 64 6f 20 77 69 74 68 20 74 68 65  t to do with the
8c00: 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20 6d 75   lock */.){.  mu
8c10: 6c 74 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d  ltiplexConn *p =
8c20: 20 28 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a   (multiplexConn*
8c30: 29 70 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63  )pConn;.  int rc
8c40: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  ;.  sqlite3_file
8c50: 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c   *pSubOpen = mul
8c60: 74 69 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d  tiplexSubOpen(p-
8c70: 3e 70 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c  >pGroup, 0, &rc,
8c80: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28   NULL, 0);.  if(
8c90: 20 70 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20   pSubOpen ){.   
8ca0: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
8cb0: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d  ->pMethods->xShm
8cc0: 4c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6f  Lock(pSubOpen, o
8cd0: 66 73 74 2c 20 6e 2c 20 66 6c 61 67 73 29 3b 0a  fst, n, flags);.
8ce0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
8cf0: 49 54 45 5f 42 55 53 59 3b 0a 7d 0a 0a 2f 2a 20  ITE_BUSY;.}../* 
8d00: 50 61 73 73 20 78 53 68 6d 42 61 72 72 69 65 72  Pass xShmBarrier
8d10: 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67   requests throug
8d20: 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61  h to the origina
8d30: 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e  l VFS unchanged.
8d40: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
8d50: 6d 75 6c 74 69 70 6c 65 78 53 68 6d 42 61 72 72  multiplexShmBarr
8d60: 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ier(sqlite3_file
8d70: 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 6d 75 6c 74   *pConn){.  mult
8d80: 69 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20 28  iplexConn *p = (
8d90: 6d 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29 70  multiplexConn*)p
8da0: 43 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  Conn;.  int rc;.
8db0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
8dc0: 70 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69  pSubOpen = multi
8dd0: 70 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d 3e 70  plexSubOpen(p->p
8de0: 47 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20 4e  Group, 0, &rc, N
8df0: 55 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20 70  ULL, 0);.  if( p
8e00: 53 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20 70  SubOpen ){.    p
8e10: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
8e20: 73 2d 3e 78 53 68 6d 42 61 72 72 69 65 72 28 70  s->xShmBarrier(p
8e30: 53 75 62 4f 70 65 6e 29 3b 0a 20 20 7d 0a 7d 0a  SubOpen);.  }.}.
8e40: 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 55 6e 6d  ./* Pass xShmUnm
8e50: 61 70 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  ap requests thro
8e60: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
8e70: 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65  nal VFS unchange
8e80: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
8e90: 20 6d 75 6c 74 69 70 6c 65 78 53 68 6d 55 6e 6d   multiplexShmUnm
8ea0: 61 70 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ap(sqlite3_file 
8eb0: 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 64 65 6c 65  *pConn, int dele
8ec0: 74 65 46 6c 61 67 29 7b 0a 20 20 6d 75 6c 74 69  teFlag){.  multi
8ed0: 70 6c 65 78 43 6f 6e 6e 20 2a 70 20 3d 20 28 6d  plexConn *p = (m
8ee0: 75 6c 74 69 70 6c 65 78 43 6f 6e 6e 2a 29 70 43  ultiplexConn*)pC
8ef0: 6f 6e 6e 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  onn;.  int rc;. 
8f00: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
8f10: 53 75 62 4f 70 65 6e 20 3d 20 6d 75 6c 74 69 70  SubOpen = multip
8f20: 6c 65 78 53 75 62 4f 70 65 6e 28 70 2d 3e 70 47  lexSubOpen(p->pG
8f30: 72 6f 75 70 2c 20 30 2c 20 26 72 63 2c 20 4e 55  roup, 0, &rc, NU
8f40: 4c 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 53  LL, 0);.  if( pS
8f50: 75 62 4f 70 65 6e 20 29 7b 0a 20 20 20 20 72 65  ubOpen ){.    re
8f60: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
8f70: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e 6d  Methods->xShmUnm
8f80: 61 70 28 70 53 75 62 4f 70 65 6e 2c 20 64 65 6c  ap(pSubOpen, del
8f90: 65 74 65 46 6c 61 67 29 3b 0a 20 20 7d 0a 20 20  eteFlag);.  }.  
8fa0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
8fb0: 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ;.}../**********
8fc0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
8fd0: 20 50 75 62 6c 69 63 20 49 6e 74 65 72 66 61 63   Public Interfac
8fe0: 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  es *************
8ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9000: 2f 0a 2f 2a 0a 2a 2a 20 43 41 50 49 3a 20 49 6e  /./*.** CAPI: In
9010: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 6d 75 6c  itialize the mul
9020: 74 69 70 6c 65 78 20 56 46 53 20 73 68 69 6d 20  tiplex VFS shim 
9030: 2d 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70  - sqlite3_multip
9040: 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  lex_initialize()
9050: 0a 2a 2a 0a 2a 2a 20 55 73 65 20 74 68 65 20 56  .**.** Use the V
9060: 46 53 20 6e 61 6d 65 64 20 7a 4f 72 69 67 56 66  FS named zOrigVf
9070: 73 4e 61 6d 65 20 61 73 20 74 68 65 20 56 46 53  sName as the VFS
9080: 20 74 68 61 74 20 64 6f 65 73 20 74 68 65 20 61   that does the a
9090: 63 74 75 61 6c 20 77 6f 72 6b 2e 20 20 0a 2a 2a  ctual work.  .**
90a0: 20 55 73 65 20 74 68 65 20 64 65 66 61 75 6c 74   Use the default
90b0: 20 69 66 20 7a 4f 72 69 67 56 66 73 4e 61 6d 65   if zOrigVfsName
90c0: 3d 3d 4e 55 4c 4c 2e 20 20 0a 2a 2a 0a 2a 2a 20  ==NULL.  .**.** 
90d0: 54 68 65 20 6d 75 6c 74 69 70 6c 65 78 20 56 46  The multiplex VF
90e0: 53 20 73 68 69 6d 20 69 73 20 6e 61 6d 65 64 20  S shim is named 
90f0: 22 6d 75 6c 74 69 70 6c 65 78 22 2e 20 20 49 74  "multiplex".  It
9100: 20 77 69 6c 6c 20 62 65 63 6f 6d 65 20 74 68 65   will become the
9110: 20 64 65 66 61 75 6c 74 0a 2a 2a 20 56 46 53 20   default.** VFS 
9120: 69 66 20 6d 61 6b 65 44 65 66 61 75 6c 74 20 69  if makeDefault i
9130: 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a  s non-zero..**.*
9140: 2a 20 54 48 49 53 20 52 4f 55 54 49 4e 45 20 49  * THIS ROUTINE I
9150: 53 20 4e 4f 54 20 54 48 52 45 41 44 53 41 46 45  S NOT THREADSAFE
9160: 2e 20 20 43 61 6c 6c 20 74 68 69 73 20 72 6f 75  .  Call this rou
9170: 74 69 6e 65 20 65 78 61 63 74 6c 79 20 6f 6e 63  tine exactly onc
9180: 65 0a 2a 2a 20 64 75 72 69 6e 67 20 73 74 61 72  e.** during star
9190: 74 2d 75 70 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  t-up..*/.int sql
91a0: 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 69  ite3_multiplex_i
91b0: 6e 69 74 69 61 6c 69 7a 65 28 63 6f 6e 73 74 20  nitialize(const 
91c0: 63 68 61 72 20 2a 7a 4f 72 69 67 56 66 73 4e 61  char *zOrigVfsNa
91d0: 6d 65 2c 20 69 6e 74 20 6d 61 6b 65 44 65 66 61  me, int makeDefa
91e0: 75 6c 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ult){.  sqlite3_
91f0: 76 66 73 20 2a 70 4f 72 69 67 56 66 73 3b 0a 20  vfs *pOrigVfs;. 
9200: 20 69 66 28 20 67 4d 75 6c 74 69 70 6c 65 78 2e   if( gMultiplex.
9210: 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 20 29 20  isInitialized ) 
9220: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49  return SQLITE_MI
9230: 53 55 53 45 3b 0a 20 20 70 4f 72 69 67 56 66 73  SUSE;.  pOrigVfs
9240: 20 3d 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 66   = sqlite3_vfs_f
9250: 69 6e 64 28 7a 4f 72 69 67 56 66 73 4e 61 6d 65  ind(zOrigVfsName
9260: 29 3b 0a 20 20 69 66 28 20 70 4f 72 69 67 56 66  );.  if( pOrigVf
9270: 73 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  s==0 ) return SQ
9280: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 61 73  LITE_ERROR;.  as
9290: 73 65 72 74 28 20 70 4f 72 69 67 56 66 73 21 3d  sert( pOrigVfs!=
92a0: 26 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69  &gMultiplex.sThi
92b0: 73 56 66 73 20 29 3b 0a 20 20 67 4d 75 6c 74 69  sVfs );.  gMulti
92c0: 70 6c 65 78 2e 69 73 49 6e 69 74 69 61 6c 69 7a  plex.isInitializ
92d0: 65 64 20 3d 20 31 3b 0a 20 20 67 4d 75 6c 74 69  ed = 1;.  gMulti
92e0: 70 6c 65 78 2e 70 4f 72 69 67 56 66 73 20 3d 20  plex.pOrigVfs = 
92f0: 70 4f 72 69 67 56 66 73 3b 0a 20 20 67 4d 75 6c  pOrigVfs;.  gMul
9300: 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 20  tiplex.sThisVfs 
9310: 3d 20 2a 70 4f 72 69 67 56 66 73 3b 0a 20 20 67  = *pOrigVfs;.  g
9320: 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56  Multiplex.sThisV
9330: 66 73 2e 73 7a 4f 73 46 69 6c 65 20 2b 3d 20 73  fs.szOsFile += s
9340: 69 7a 65 6f 66 28 6d 75 6c 74 69 70 6c 65 78 43  izeof(multiplexC
9350: 6f 6e 6e 29 3b 0a 20 20 67 4d 75 6c 74 69 70 6c  onn);.  gMultipl
9360: 65 78 2e 73 54 68 69 73 56 66 73 2e 7a 4e 61 6d  ex.sThisVfs.zNam
9370: 65 20 3d 20 53 51 4c 49 54 45 5f 4d 55 4c 54 49  e = SQLITE_MULTI
9380: 50 4c 45 58 5f 56 46 53 5f 4e 41 4d 45 3b 0a 20  PLEX_VFS_NAME;. 
9390: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69   gMultiplex.sThi
93a0: 73 56 66 73 2e 78 4f 70 65 6e 20 3d 20 6d 75 6c  sVfs.xOpen = mul
93b0: 74 69 70 6c 65 78 4f 70 65 6e 3b 0a 20 20 67 4d  tiplexOpen;.  gM
93c0: 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66  ultiplex.sThisVf
93d0: 73 2e 78 44 65 6c 65 74 65 20 3d 20 6d 75 6c 74  s.xDelete = mult
93e0: 69 70 6c 65 78 44 65 6c 65 74 65 3b 0a 20 20 67  iplexDelete;.  g
93f0: 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56  Multiplex.sThisV
9400: 66 73 2e 78 41 63 63 65 73 73 20 3d 20 6d 75 6c  fs.xAccess = mul
9410: 74 69 70 6c 65 78 41 63 63 65 73 73 3b 0a 20 20  tiplexAccess;.  
9420: 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73  gMultiplex.sThis
9430: 56 66 73 2e 78 46 75 6c 6c 50 61 74 68 6e 61 6d  Vfs.xFullPathnam
9440: 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78 46 75 6c  e = multiplexFul
9450: 6c 50 61 74 68 6e 61 6d 65 3b 0a 20 20 67 4d 75  lPathname;.  gMu
9460: 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73  ltiplex.sThisVfs
9470: 2e 78 44 6c 4f 70 65 6e 20 3d 20 6d 75 6c 74 69  .xDlOpen = multi
9480: 70 6c 65 78 44 6c 4f 70 65 6e 3b 0a 20 20 67 4d  plexDlOpen;.  gM
9490: 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66  ultiplex.sThisVf
94a0: 73 2e 78 44 6c 45 72 72 6f 72 20 3d 20 6d 75 6c  s.xDlError = mul
94b0: 74 69 70 6c 65 78 44 6c 45 72 72 6f 72 3b 0a 20  tiplexDlError;. 
94c0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69   gMultiplex.sThi
94d0: 73 56 66 73 2e 78 44 6c 53 79 6d 20 3d 20 6d 75  sVfs.xDlSym = mu
94e0: 6c 74 69 70 6c 65 78 44 6c 53 79 6d 3b 0a 20 20  ltiplexDlSym;.  
94f0: 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54 68 69 73  gMultiplex.sThis
9500: 56 66 73 2e 78 44 6c 43 6c 6f 73 65 20 3d 20 6d  Vfs.xDlClose = m
9510: 75 6c 74 69 70 6c 65 78 44 6c 43 6c 6f 73 65 3b  ultiplexDlClose;
9520: 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54  .  gMultiplex.sT
9530: 68 69 73 56 66 73 2e 78 52 61 6e 64 6f 6d 6e 65  hisVfs.xRandomne
9540: 73 73 20 3d 20 6d 75 6c 74 69 70 6c 65 78 52 61  ss = multiplexRa
9550: 6e 64 6f 6d 6e 65 73 73 3b 0a 20 20 67 4d 75 6c  ndomness;.  gMul
9560: 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e  tiplex.sThisVfs.
9570: 78 53 6c 65 65 70 20 3d 20 6d 75 6c 74 69 70 6c  xSleep = multipl
9580: 65 78 53 6c 65 65 70 3b 0a 20 20 67 4d 75 6c 74  exSleep;.  gMult
9590: 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2e 78  iplex.sThisVfs.x
95a0: 43 75 72 72 65 6e 74 54 69 6d 65 20 3d 20 6d 75  CurrentTime = mu
95b0: 6c 74 69 70 6c 65 78 43 75 72 72 65 6e 74 54 69  ltiplexCurrentTi
95c0: 6d 65 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78  me;.  gMultiplex
95d0: 2e 73 54 68 69 73 56 66 73 2e 78 47 65 74 4c 61  .sThisVfs.xGetLa
95e0: 73 74 45 72 72 6f 72 20 3d 20 6d 75 6c 74 69 70  stError = multip
95f0: 6c 65 78 47 65 74 4c 61 73 74 45 72 72 6f 72 3b  lexGetLastError;
9600: 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 54  .  gMultiplex.sT
9610: 68 69 73 56 66 73 2e 78 43 75 72 72 65 6e 74 54  hisVfs.xCurrentT
9620: 69 6d 65 49 6e 74 36 34 20 3d 20 6d 75 6c 74 69  imeInt64 = multi
9630: 70 6c 65 78 43 75 72 72 65 6e 74 54 69 6d 65 49  plexCurrentTimeI
9640: 6e 74 36 34 3b 0a 0a 20 20 67 4d 75 6c 74 69 70  nt64;..  gMultip
9650: 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31  lex.sIoMethodsV1
9660: 2e 69 56 65 72 73 69 6f 6e 20 3d 20 31 3b 0a 20  .iVersion = 1;. 
9670: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9680: 65 74 68 6f 64 73 56 31 2e 78 43 6c 6f 73 65 20  ethodsV1.xClose 
9690: 3d 20 6d 75 6c 74 69 70 6c 65 78 43 6c 6f 73 65  = multiplexClose
96a0: 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73  ;.  gMultiplex.s
96b0: 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 52 65 61  IoMethodsV1.xRea
96c0: 64 20 3d 20 6d 75 6c 74 69 70 6c 65 78 52 65 61  d = multiplexRea
96d0: 64 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e  d;.  gMultiplex.
96e0: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 57 72  sIoMethodsV1.xWr
96f0: 69 74 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78 57  ite = multiplexW
9700: 72 69 74 65 3b 0a 20 20 67 4d 75 6c 74 69 70 6c  rite;.  gMultipl
9710: 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e  ex.sIoMethodsV1.
9720: 78 54 72 75 6e 63 61 74 65 20 3d 20 6d 75 6c 74  xTruncate = mult
9730: 69 70 6c 65 78 54 72 75 6e 63 61 74 65 3b 0a 20  iplexTruncate;. 
9740: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9750: 65 74 68 6f 64 73 56 31 2e 78 53 79 6e 63 20 3d  ethodsV1.xSync =
9760: 20 6d 75 6c 74 69 70 6c 65 78 53 79 6e 63 3b 0a   multiplexSync;.
9770: 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f    gMultiplex.sIo
9780: 4d 65 74 68 6f 64 73 56 31 2e 78 46 69 6c 65 53  MethodsV1.xFileS
9790: 69 7a 65 20 3d 20 6d 75 6c 74 69 70 6c 65 78 46  ize = multiplexF
97a0: 69 6c 65 53 69 7a 65 3b 0a 20 20 67 4d 75 6c 74  ileSize;.  gMult
97b0: 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73  iplex.sIoMethods
97c0: 56 31 2e 78 4c 6f 63 6b 20 3d 20 6d 75 6c 74 69  V1.xLock = multi
97d0: 70 6c 65 78 4c 6f 63 6b 3b 0a 20 20 67 4d 75 6c  plexLock;.  gMul
97e0: 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64  tiplex.sIoMethod
97f0: 73 56 31 2e 78 55 6e 6c 6f 63 6b 20 3d 20 6d 75  sV1.xUnlock = mu
9800: 6c 74 69 70 6c 65 78 55 6e 6c 6f 63 6b 3b 0a 20  ltiplexUnlock;. 
9810: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9820: 65 74 68 6f 64 73 56 31 2e 78 43 68 65 63 6b 52  ethodsV1.xCheckR
9830: 65 73 65 72 76 65 64 4c 6f 63 6b 20 3d 20 6d 75  eservedLock = mu
9840: 6c 74 69 70 6c 65 78 43 68 65 63 6b 52 65 73 65  ltiplexCheckRese
9850: 72 76 65 64 4c 6f 63 6b 3b 0a 20 20 67 4d 75 6c  rvedLock;.  gMul
9860: 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64  tiplex.sIoMethod
9870: 73 56 31 2e 78 46 69 6c 65 43 6f 6e 74 72 6f 6c  sV1.xFileControl
9880: 20 3d 20 6d 75 6c 74 69 70 6c 65 78 46 69 6c 65   = multiplexFile
9890: 43 6f 6e 74 72 6f 6c 3b 0a 20 20 67 4d 75 6c 74  Control;.  gMult
98a0: 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73  iplex.sIoMethods
98b0: 56 31 2e 78 53 65 63 74 6f 72 53 69 7a 65 20 3d  V1.xSectorSize =
98c0: 20 6d 75 6c 74 69 70 6c 65 78 53 65 63 74 6f 72   multiplexSector
98d0: 53 69 7a 65 3b 0a 20 20 67 4d 75 6c 74 69 70 6c  Size;.  gMultipl
98e0: 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e  ex.sIoMethodsV1.
98f0: 78 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72  xDeviceCharacter
9900: 69 73 74 69 63 73 20 3d 0a 20 20 20 20 20 20 20  istics =.       
9910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9930: 20 20 20 20 20 6d 75 6c 74 69 70 6c 65 78 44 65       multiplexDe
9940: 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74  viceCharacterist
9950: 69 63 73 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65  ics;.  gMultiple
9960: 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 20 3d  x.sIoMethodsV2 =
9970: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d   gMultiplex.sIoM
9980: 65 74 68 6f 64 73 56 31 3b 0a 20 20 67 4d 75 6c  ethodsV1;.  gMul
9990: 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64  tiplex.sIoMethod
99a0: 73 56 32 2e 69 56 65 72 73 69 6f 6e 20 3d 20 32  sV2.iVersion = 2
99b0: 3b 0a 20 20 67 4d 75 6c 74 69 70 6c 65 78 2e 73  ;.  gMultiplex.s
99c0: 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d  IoMethodsV2.xShm
99d0: 4d 61 70 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  Map = multiplexS
99e0: 68 6d 4d 61 70 3b 0a 20 20 67 4d 75 6c 74 69 70  hmMap;.  gMultip
99f0: 6c 65 78 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32  lex.sIoMethodsV2
9a00: 2e 78 53 68 6d 4c 6f 63 6b 20 3d 20 6d 75 6c 74  .xShmLock = mult
9a10: 69 70 6c 65 78 53 68 6d 4c 6f 63 6b 3b 0a 20 20  iplexShmLock;.  
9a20: 67 4d 75 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65  gMultiplex.sIoMe
9a30: 74 68 6f 64 73 56 32 2e 78 53 68 6d 42 61 72 72  thodsV2.xShmBarr
9a40: 69 65 72 20 3d 20 6d 75 6c 74 69 70 6c 65 78 53  ier = multiplexS
9a50: 68 6d 42 61 72 72 69 65 72 3b 0a 20 20 67 4d 75  hmBarrier;.  gMu
9a60: 6c 74 69 70 6c 65 78 2e 73 49 6f 4d 65 74 68 6f  ltiplex.sIoMetho
9a70: 64 73 56 32 2e 78 53 68 6d 55 6e 6d 61 70 20 3d  dsV2.xShmUnmap =
9a80: 20 6d 75 6c 74 69 70 6c 65 78 53 68 6d 55 6e 6d   multiplexShmUnm
9a90: 61 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  ap;.  sqlite3_vf
9aa0: 73 5f 72 65 67 69 73 74 65 72 28 26 67 4d 75 6c  s_register(&gMul
9ab0: 74 69 70 6c 65 78 2e 73 54 68 69 73 56 66 73 2c  tiplex.sThisVfs,
9ac0: 20 6d 61 6b 65 44 65 66 61 75 6c 74 29 3b 0a 0a   makeDefault);..
9ad0: 20 20 73 71 6c 69 74 65 33 5f 61 75 74 6f 5f 65    sqlite3_auto_e
9ae0: 78 74 65 6e 73 69 6f 6e 28 28 76 6f 69 64 28 2a  xtension((void(*
9af0: 29 28 76 6f 69 64 29 29 6d 75 6c 74 69 70 6c 65  )(void))multiple
9b00: 78 46 75 6e 63 49 6e 69 74 29 3b 0a 0a 20 20 72  xFuncInit);..  r
9b10: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
9b20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 41 50 49 3a 20  .}../*.** CAPI: 
9b30: 53 68 75 74 64 6f 77 6e 20 74 68 65 20 6d 75 6c  Shutdown the mul
9b40: 74 69 70 6c 65 78 20 73 79 73 74 65 6d 20 2d 20  tiplex system - 
9b50: 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65  sqlite3_multiple
9b60: 78 5f 73 68 75 74 64 6f 77 6e 28 29 0a 2a 2a 0a  x_shutdown().**.
9b70: 2a 2a 20 41 6c 6c 20 53 51 4c 69 74 65 20 64 61  ** All SQLite da
9b80: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
9b90: 6e 73 20 6d 75 73 74 20 62 65 20 63 6c 6f 73 65  ns must be close
9ba0: 64 20 62 65 66 6f 72 65 20 63 61 6c 6c 69 6e 67  d before calling
9bb0: 20 74 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65   this.** routine
9bc0: 2e 0a 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55  ..**.** THIS ROU
9bd0: 54 49 4e 45 20 49 53 20 4e 4f 54 20 54 48 52 45  TINE IS NOT THRE
9be0: 41 44 53 41 46 45 2e 20 20 43 61 6c 6c 20 74 68  ADSAFE.  Call th
9bf0: 69 73 20 72 6f 75 74 69 6e 65 20 65 78 61 63 74  is routine exact
9c00: 6c 79 20 6f 6e 63 65 20 77 68 69 6c 65 0a 2a 2a  ly once while.**
9c10: 20 73 68 75 74 74 69 6e 67 20 64 6f 77 6e 20 69   shutting down i
9c20: 6e 20 6f 72 64 65 72 20 74 6f 20 66 72 65 65 20  n order to free 
9c30: 61 6c 6c 20 72 65 6d 61 69 6e 69 6e 67 20 6d 75  all remaining mu
9c40: 6c 74 69 70 6c 65 78 20 67 72 6f 75 70 73 2e 0a  ltiplex groups..
9c50: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 6d  */.int sqlite3_m
9c60: 75 6c 74 69 70 6c 65 78 5f 73 68 75 74 64 6f 77  ultiplex_shutdow
9c70: 6e 28 69 6e 74 20 65 46 6f 72 63 65 29 7b 0a 20  n(int eForce){. 
9c80: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
9c90: 5f 4f 4b 3b 0a 20 20 69 66 28 20 67 4d 75 6c 74  _OK;.  if( gMult
9ca0: 69 70 6c 65 78 2e 69 73 49 6e 69 74 69 61 6c 69  iplex.isInitiali
9cb0: 7a 65 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  zed==0 ) return 
9cc0: 53 51 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20  SQLITE_MISUSE;. 
9cd0: 20 67 4d 75 6c 74 69 70 6c 65 78 2e 69 73 49 6e   gMultiplex.isIn
9ce0: 69 74 69 61 6c 69 7a 65 64 20 3d 20 30 3b 0a 20  itialized = 0;. 
9cf0: 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e 72   sqlite3_vfs_unr
9d00: 65 67 69 73 74 65 72 28 26 67 4d 75 6c 74 69 70  egister(&gMultip
9d10: 6c 65 78 2e 73 54 68 69 73 56 66 73 29 3b 0a 20  lex.sThisVfs);. 
9d20: 20 6d 65 6d 73 65 74 28 26 67 4d 75 6c 74 69 70   memset(&gMultip
9d30: 6c 65 78 2c 20 30 2c 20 73 69 7a 65 6f 66 28 67  lex, 0, sizeof(g
9d40: 4d 75 6c 74 69 70 6c 65 78 29 29 3b 0a 20 20 72  Multiplex));.  r
9d50: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a  eturn rc;.}../**
9d60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9d70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 54 65 73 74  *********** Test
9d80: 20 43 6f 64 65 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   Code **********
9d90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9da0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 69 66 64 65  *********/.#ifde
9db0: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 23 69  f SQLITE_TEST.#i
9dc0: 66 20 64 65 66 69 6e 65 64 28 49 4e 43 4c 55 44  f defined(INCLUD
9dd0: 45 5f 53 51 4c 49 54 45 5f 54 43 4c 5f 48 29 0a  E_SQLITE_TCL_H).
9de0: 23 20 20 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  #  include "sqli
9df0: 74 65 5f 74 63 6c 2e 68 22 0a 23 65 6c 73 65 0a  te_tcl.h".#else.
9e00: 23 20 20 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e  #  include "tcl.
9e10: 68 22 0a 23 20 20 69 66 6e 64 65 66 20 53 51 4c  h".#  ifndef SQL
9e20: 49 54 45 5f 54 43 4c 41 50 49 0a 23 20 20 20 20  ITE_TCLAPI.#    
9e30: 64 65 66 69 6e 65 20 53 51 4c 49 54 45 5f 54 43  define SQLITE_TC
9e40: 4c 41 50 49 0a 23 20 20 65 6e 64 69 66 0a 23 65  LAPI.#  endif.#e
9e50: 6e 64 69 66 0a 65 78 74 65 72 6e 20 63 6f 6e 73  ndif.extern cons
9e60: 74 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33 45  t char *sqlite3E
9e70: 72 72 4e 61 6d 65 28 69 6e 74 29 3b 0a 0a 0a 2f  rrName(int);.../
9e80: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
9e90: 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 69  ite3_multiplex_i
9ea0: 6e 69 74 69 61 6c 69 7a 65 20 4e 41 4d 45 20 4d  nitialize NAME M
9eb0: 41 4b 45 44 45 46 41 55 4c 54 0a 2a 2f 0a 73 74  AKEDEFAULT.*/.st
9ec0: 61 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f  atic int SQLITE_
9ed0: 54 43 4c 41 50 49 20 74 65 73 74 5f 6d 75 6c 74  TCLAPI test_mult
9ee0: 69 70 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65  iplex_initialize
9ef0: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
9f00: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
9f10: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
9f20: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
9f30: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
9f40: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
9f50: 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20   *zName;        
9f60: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
9f70: 20 6e 65 77 20 6d 75 6c 74 69 70 6c 65 78 20 56   new multiplex V
9f80: 46 53 20 2a 2f 0a 20 20 69 6e 74 20 6d 61 6b 65  FS */.  int make
9f90: 44 65 66 61 75 6c 74 3b 20 20 20 20 20 20 20 20  Default;        
9fa0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
9fb0: 74 6f 20 6d 61 6b 65 20 74 68 65 20 6e 65 77 20  to make the new 
9fc0: 56 46 53 20 74 68 65 20 64 65 66 61 75 6c 74 20  VFS the default 
9fd0: 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  */.  int rc;    
9fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ff0: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 72 65       /* Value re
a000: 74 75 72 6e 65 64 20 62 79 20 6d 75 6c 74 69 70  turned by multip
a010: 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29  lex_initialize()
a020: 20 2a 2f 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41   */..  UNUSED_PA
a030: 52 41 4d 45 54 45 52 28 63 6c 69 65 6e 74 44 61  RAMETER(clientDa
a040: 74 61 29 3b 0a 0a 20 20 2f 2a 20 50 72 6f 63 65  ta);..  /* Proce
a050: 73 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  ss arguments */.
a060: 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b    if( objc!=3 ){
a070: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
a080: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
a090: 20 6f 62 6a 76 2c 20 22 4e 41 4d 45 20 4d 41 4b   objv, "NAME MAK
a0a0: 45 44 45 46 41 55 4c 54 22 29 3b 0a 20 20 20 20  EDEFAULT");.    
a0b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
a0c0: 3b 0a 20 20 7d 0a 20 20 7a 4e 61 6d 65 20 3d 20  ;.  }.  zName = 
a0d0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
a0e0: 6a 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 54 63  jv[1]);.  if( Tc
a0f0: 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d  l_GetBooleanFrom
a100: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
a110: 5b 32 5d 2c 20 26 6d 61 6b 65 44 65 66 61 75 6c  [2], &makeDefaul
a120: 74 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  t) ) return TCL_
a130: 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 7a 4e 61  ERROR;.  if( zNa
a140: 6d 65 5b 30 5d 3d 3d 27 5c 30 27 20 29 20 7a 4e  me[0]=='\0' ) zN
a150: 61 6d 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 43  ame = 0;..  /* C
a160: 61 6c 6c 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74  all sqlite3_mult
a170: 69 70 6c 65 78 5f 69 6e 69 74 69 61 6c 69 7a 65  iplex_initialize
a180: 28 29 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  () */.  rc = sql
a190: 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 69  ite3_multiplex_i
a1a0: 6e 69 74 69 61 6c 69 7a 65 28 7a 4e 61 6d 65 2c  nitialize(zName,
a1b0: 20 6d 61 6b 65 44 65 66 61 75 6c 74 29 3b 0a 20   makeDefault);. 
a1c0: 20 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69   Tcl_SetResult(i
a1d0: 6e 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73  nterp, (char *)s
a1e0: 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 72 63  qlite3ErrName(rc
a1f0: 29 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a  ), TCL_STATIC);.
a200: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
a210: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d  ;.}../*.** tclcm
a220: 64 3a 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69  d: sqlite3_multi
a230: 70 6c 65 78 5f 73 68 75 74 64 6f 77 6e 0a 2a 2f  plex_shutdown.*/
a240: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
a250: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 6d  TE_TCLAPI test_m
a260: 75 6c 74 69 70 6c 65 78 5f 73 68 75 74 64 6f 77  ultiplex_shutdow
a270: 6e 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  n(.  void * clie
a280: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
a290: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
a2a0: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
a2b0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a2c0: 5d 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  ].){.  int rc;  
a2d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a2e0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
a2f0: 72 65 74 75 72 6e 65 64 20 62 79 20 6d 75 6c 74  returned by mult
a300: 69 70 6c 65 78 5f 73 68 75 74 64 6f 77 6e 28 29  iplex_shutdown()
a310: 20 2a 2f 0a 0a 20 20 55 4e 55 53 45 44 5f 50 41   */..  UNUSED_PA
a320: 52 41 4d 45 54 45 52 28 63 6c 69 65 6e 74 44 61  RAMETER(clientDa
a330: 74 61 29 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63  ta);..  if( objc
a340: 3d 3d 32 20 26 26 20 73 74 72 63 6d 70 28 54 63  ==2 && strcmp(Tc
a350: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
a360: 5b 31 5d 29 2c 22 2d 66 6f 72 63 65 22 29 21 3d  [1]),"-force")!=
a370: 30 20 29 7b 0a 20 20 20 20 6f 62 6a 63 20 3d 20  0 ){.    objc = 
a380: 33 3b 0a 20 20 7d 0a 20 20 69 66 28 20 28 6f 62  3;.  }.  if( (ob
a390: 6a 63 21 3d 31 20 26 26 20 6f 62 6a 63 21 3d 32  jc!=1 && objc!=2
a3a0: 29 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  ) ){.    Tcl_Wro
a3b0: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
a3c0: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 2d 66 6f  , 1, objv, "?-fo
a3d0: 72 63 65 3f 22 29 3b 0a 20 20 20 20 72 65 74 75  rce?");.    retu
a3e0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
a3f0: 7d 0a 0a 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c  }..  /* Call sql
a400: 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f 73  ite3_multiplex_s
a410: 68 75 74 64 6f 77 6e 28 29 20 2a 2f 0a 20 20 72  hutdown() */.  r
a420: 63 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 6c 74  c = sqlite3_mult
a430: 69 70 6c 65 78 5f 73 68 75 74 64 6f 77 6e 28 6f  iplex_shutdown(o
a440: 62 6a 63 3d 3d 32 29 3b 0a 20 20 54 63 6c 5f 53  bjc==2);.  Tcl_S
a450: 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  etResult(interp,
a460: 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33   (char *)sqlite3
a470: 45 72 72 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c  ErrName(rc), TCL
a480: 5f 53 54 41 54 49 43 29 3b 0a 0a 20 20 72 65 74  _STATIC);..  ret
a490: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
a4a0: 2a 0a 2a 2a 20 54 63 6c 63 6d 64 3a 20 74 65 73  *.** Tclcmd: tes
a4b0: 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74  t_multiplex_cont
a4c0: 72 6f 6c 20 48 41 4e 44 4c 45 20 44 42 4e 41 4d  rol HANDLE DBNAM
a4d0: 45 20 53 55 42 2d 43 4f 4d 4d 41 4e 44 20 3f 49  E SUB-COMMAND ?I
a4e0: 4e 54 2d 56 41 4c 55 45 3f 0a 2a 2f 0a 73 74 61  NT-VALUE?.*/.sta
a4f0: 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54  tic int SQLITE_T
a500: 43 4c 41 50 49 20 74 65 73 74 5f 6d 75 6c 74 69  CLAPI test_multi
a510: 70 6c 65 78 5f 63 6f 6e 74 72 6f 6c 28 0a 20 20  plex_control(.  
a520: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 0a 20  ClientData cd,. 
a530: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
a540: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
a550: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
a560: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e  T objv[].){.  in
a570: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
a580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a590: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 72 6f   Return code fro
a5a0: 6d 20 66 69 6c 65 5f 63 6f 6e 74 72 6f 6c 28 29  m file_control()
a5b0: 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 3b 20 20   */.  int idx;  
a5c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a5d0: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 69        /* Index i
a5e0: 6e 20 61 53 75 62 5b 5d 20 2a 2f 0a 20 20 54 63  n aSub[] */.  Tc
a5f0: 6c 5f 43 6d 64 49 6e 66 6f 20 63 6d 64 49 6e 66  l_CmdInfo cmdInf
a600: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  o;            /*
a610: 20 43 6f 6d 6d 61 6e 64 20 69 6e 66 6f 20 73 74   Command info st
a620: 72 75 63 74 75 72 65 20 66 6f 72 20 48 41 4e 44  ructure for HAND
a630: 4c 45 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20  LE */.  sqlite3 
a640: 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  *db;            
a650: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 64 65 72          /* Under
a660: 6c 79 69 6e 67 20 64 62 20 68 61 6e 64 6c 65 20  lying db handle 
a670: 66 6f 72 20 48 41 4e 44 4c 45 20 2a 2f 0a 20 20  for HANDLE */.  
a680: 69 6e 74 20 69 56 61 6c 75 65 20 3d 20 30 3b 0a  int iValue = 0;.
a690: 20 20 76 6f 69 64 20 2a 70 41 72 67 20 3d 20 30    void *pArg = 0
a6a0: 3b 0a 0a 20 20 73 74 72 75 63 74 20 53 75 62 43  ;..  struct SubC
a6b0: 6f 6d 6d 61 6e 64 20 7b 0a 20 20 20 20 63 6f 6e  ommand {.    con
a6c0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a  st char *zName;.
a6d0: 20 20 20 20 69 6e 74 20 6f 70 3b 0a 20 20 20 20      int op;.    
a6e0: 69 6e 74 20 61 72 67 74 79 70 65 3b 0a 20 20 7d  int argtype;.  }
a6f0: 20 61 53 75 62 5b 5d 20 3d 20 7b 0a 20 20 20 20   aSub[] = {.    
a700: 7b 20 22 65 6e 61 62 6c 65 22 2c 20 20 20 20 20  { "enable",     
a710: 20 20 4d 55 4c 54 49 50 4c 45 58 5f 43 54 52 4c    MULTIPLEX_CTRL
a720: 5f 45 4e 41 42 4c 45 2c 20 20 20 20 20 20 20 20  _ENABLE,        
a730: 20 20 20 31 20 7d 2c 0a 20 20 20 20 7b 20 22 63     1 },.    { "c
a740: 68 75 6e 6b 5f 73 69 7a 65 22 2c 20 20 20 4d 55  hunk_size",   MU
a750: 4c 54 49 50 4c 45 58 5f 43 54 52 4c 5f 53 45 54  LTIPLEX_CTRL_SET
a760: 5f 43 48 55 4e 4b 5f 53 49 5a 45 2c 20 20 20 31  _CHUNK_SIZE,   1
a770: 20 7d 2c 0a 20 20 20 20 7b 20 22 6d 61 78 5f 63   },.    { "max_c
a780: 68 75 6e 6b 73 22 2c 20 20 20 4d 55 4c 54 49 50  hunks",   MULTIP
a790: 4c 45 58 5f 43 54 52 4c 5f 53 45 54 5f 4d 41 58  LEX_CTRL_SET_MAX
a7a0: 5f 43 48 55 4e 4b 53 2c 20 20 20 31 20 7d 2c 0a  _CHUNKS,   1 },.
a7b0: 20 20 20 20 7b 20 30 2c 20 30 2c 20 30 20 7d 0a      { 0, 0, 0 }.
a7c0: 20 20 7d 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63    };..  if( objc
a7d0: 21 3d 35 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=5 ){.    Tcl_W
a7e0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
a7f0: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 48 41  rp, 1, objv, "HA
a800: 4e 44 4c 45 20 44 42 4e 41 4d 45 20 53 55 42 2d  NDLE DBNAME SUB-
a810: 43 4f 4d 4d 41 4e 44 20 49 4e 54 2d 56 41 4c 55  COMMAND INT-VALU
a820: 45 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  E");.    return 
a830: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  TCL_ERROR;.  }..
a840: 20 20 69 66 28 20 30 3d 3d 54 63 6c 5f 47 65 74    if( 0==Tcl_Get
a850: 43 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74 65  CommandInfo(inte
a860: 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  rp, Tcl_GetStrin
a870: 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 63 6d 64  g(objv[1]), &cmd
a880: 49 6e 66 6f 29 20 29 7b 0a 20 20 20 20 54 63 6c  Info) ){.    Tcl
a890: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
a8a0: 74 65 72 70 2c 20 22 65 78 70 65 63 74 65 64 20  terp, "expected 
a8b0: 64 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 2c  database handle,
a8c0: 20 67 6f 74 20 5c 22 22 2c 20 30 29 3b 0a 20 20   got \"", 0);.  
a8d0: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
a8e0: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  lt(interp, Tcl_G
a8f0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
a900: 29 2c 20 22 5c 22 22 2c 20 30 29 3b 0a 20 20 20  ), "\"", 0);.   
a910: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
a920: 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  R;.  }else{.    
a930: 64 62 20 3d 20 2a 28 73 71 6c 69 74 65 33 20 2a  db = *(sqlite3 *
a940: 2a 29 63 6d 64 49 6e 66 6f 2e 6f 62 6a 43 6c 69  *)cmdInfo.objCli
a950: 65 6e 74 44 61 74 61 3b 0a 20 20 7d 0a 0a 20 20  entData;.  }..  
a960: 72 63 20 3d 20 54 63 6c 5f 47 65 74 49 6e 64 65  rc = Tcl_GetInde
a970: 78 46 72 6f 6d 4f 62 6a 53 74 72 75 63 74 28 0a  xFromObjStruct(.
a980: 20 20 20 20 20 20 69 6e 74 65 72 70 2c 20 6f 62        interp, ob
a990: 6a 76 5b 33 5d 2c 20 61 53 75 62 2c 20 73 69 7a  jv[3], aSub, siz
a9a0: 65 6f 66 28 61 53 75 62 5b 30 5d 29 2c 20 22 73  eof(aSub[0]), "s
a9b0: 75 62 2d 63 6f 6d 6d 61 6e 64 22 2c 20 30 2c 20  ub-command", 0, 
a9c0: 26 69 64 78 0a 20 20 29 3b 0a 20 20 69 66 28 20  &idx.  );.  if( 
a9d0: 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 72 65 74  rc!=TCL_OK ) ret
a9e0: 75 72 6e 20 72 63 3b 0a 0a 20 20 73 77 69 74 63  urn rc;..  switc
a9f0: 68 28 20 61 53 75 62 5b 69 64 78 5d 2e 61 72 67  h( aSub[idx].arg
aa00: 74 79 70 65 20 29 7b 0a 20 20 20 20 63 61 73 65  type ){.    case
aa10: 20 31 3a 0a 20 20 20 20 20 20 69 66 28 20 54 63   1:.      if( Tc
aa20: 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28  l_GetIntFromObj(
aa30: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 34 5d 2c  interp, objv[4],
aa40: 20 26 69 56 61 6c 75 65 29 20 29 7b 0a 20 20 20   &iValue) ){.   
aa50: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
aa60: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
aa70: 20 20 20 20 20 70 41 72 67 20 3d 20 28 76 6f 69       pArg = (voi
aa80: 64 20 2a 29 26 69 56 61 6c 75 65 3b 0a 20 20 20  d *)&iValue;.   
aa90: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65     break;.    de
aaa0: 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 54 63 6c  fault:.      Tcl
aab0: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
aac0: 74 65 72 70 2c 20 34 2c 20 6f 62 6a 76 2c 20 22  terp, 4, objv, "
aad0: 53 55 42 2d 43 4f 4d 4d 41 4e 44 22 29 3b 0a 20  SUB-COMMAND");. 
aae0: 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f       return TCL_
aaf0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63  ERROR;.  }..  rc
ab00: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 5f   = sqlite3_file_
ab10: 63 6f 6e 74 72 6f 6c 28 64 62 2c 20 54 63 6c 5f  control(db, Tcl_
ab20: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32  GetString(objv[2
ab30: 5d 29 2c 20 61 53 75 62 5b 69 64 78 5d 2e 6f 70  ]), aSub[idx].op
ab40: 2c 20 70 41 72 67 29 3b 0a 20 20 54 63 6c 5f 53  , pArg);.  Tcl_S
ab50: 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  etResult(interp,
ab60: 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33   (char *)sqlite3
ab70: 45 72 72 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c  ErrName(rc), TCL
ab80: 5f 53 54 41 54 49 43 29 3b 0a 20 20 72 65 74 75  _STATIC);.  retu
ab90: 72 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  rn (rc==SQLITE_O
aba0: 4b 29 20 3f 20 54 43 4c 5f 4f 4b 20 3a 20 54 43  K) ? TCL_OK : TC
abb0: 4c 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 0a 2a  L_ERROR;.}../*.*
abc0: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72  * This routine r
abd0: 65 67 69 73 74 65 72 73 20 74 68 65 20 63 75 73  egisters the cus
abe0: 74 6f 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 73  tom TCL commands
abf0: 20 64 65 66 69 6e 65 64 20 69 6e 20 74 68 69 73   defined in this
ac00: 0a 2a 2a 20 6d 6f 64 75 6c 65 2e 20 20 54 68 69  .** module.  Thi
ac10: 73 20 73 68 6f 75 6c 64 20 62 65 20 74 68 65 20  s should be the 
ac20: 6f 6e 6c 79 20 70 72 6f 63 65 64 75 72 65 20 76  only procedure v
ac30: 69 73 69 62 6c 65 20 66 72 6f 6d 20 6f 75 74 73  isible from outs
ac40: 69 64 65 0a 2a 2a 20 6f 66 20 74 68 69 73 20 6d  ide.** of this m
ac50: 6f 64 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 53 71  odule..*/.int Sq
ac60: 6c 69 74 65 6d 75 6c 74 69 70 6c 65 78 5f 49 6e  litemultiplex_In
ac70: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
ac80: 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74 69 63  nterp){.  static
ac90: 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20 63   struct {.     c
aca0: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
acb0: 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20   Tcl_ObjCmdProc 
acc0: 2a 78 50 72 6f 63 3b 0a 20 20 7d 20 61 43 6d 64  *xProc;.  } aCmd
acd0: 5b 5d 20 3d 20 7b 0a 20 20 20 20 7b 20 22 73 71  [] = {.    { "sq
ace0: 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65 78 5f  lite3_multiplex_
acf0: 69 6e 69 74 69 61 6c 69 7a 65 22 2c 20 74 65 73  initialize", tes
ad00: 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 69 6e 69 74  t_multiplex_init
ad10: 69 61 6c 69 7a 65 20 7d 2c 0a 20 20 20 20 7b 20  ialize },.    { 
ad20: 22 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c  "sqlite3_multipl
ad30: 65 78 5f 73 68 75 74 64 6f 77 6e 22 2c 20 74 65  ex_shutdown", te
ad40: 73 74 5f 6d 75 6c 74 69 70 6c 65 78 5f 73 68 75  st_multiplex_shu
ad50: 74 64 6f 77 6e 20 7d 2c 0a 20 20 20 20 7b 20 22  tdown },.    { "
ad60: 73 71 6c 69 74 65 33 5f 6d 75 6c 74 69 70 6c 65  sqlite3_multiple
ad70: 78 5f 63 6f 6e 74 72 6f 6c 22 2c 20 74 65 73 74  x_control", test
ad80: 5f 6d 75 6c 74 69 70 6c 65 78 5f 63 6f 6e 74 72  _multiplex_contr
ad90: 6f 6c 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74  ol },.  };.  int
ada0: 20 69 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20   i;..  for(i=0; 
adb0: 69 3c 73 69 7a 65 6f 66 28 61 43 6d 64 29 2f 73  i<sizeof(aCmd)/s
adc0: 69 7a 65 6f 66 28 61 43 6d 64 5b 30 5d 29 3b 20  izeof(aCmd[0]); 
add0: 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43 72  i++){.    Tcl_Cr
ade0: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
adf0: 6e 74 65 72 70 2c 20 61 43 6d 64 5b 69 5d 2e 7a  nterp, aCmd[i].z
ae00: 4e 61 6d 65 2c 20 61 43 6d 64 5b 69 5d 2e 78 50  Name, aCmd[i].xP
ae10: 72 6f 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a  roc, 0, 0);.  }.
ae20: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
ae30: 3b 0a 7d 0a 23 65 6e 64 69 66 0a                 ;.}.#endif.