]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Split up os.c into separate files, one for each platform. (CVS 1441)
authordrh <drh@noemail.net>
Sat, 22 May 2004 17:41:58 +0000 (17:41 +0000)
committerdrh <drh@noemail.net>
Sat, 22 May 2004 17:41:58 +0000 (17:41 +0000)
FossilOrigin-Name: 5c61be1c47ac960fba2a642e69a98436ce1cd725

14 files changed:
main.mk
manifest
manifest.uuid
src/main.c
src/os.h
src/os_common.h [new file with mode: 0644]
src/os_mac.c [new file with mode: 0644]
src/os_mac.h [new file with mode: 0644]
src/os_unix.c [moved from src/os.c with 50% similarity]
src/os_unix.h [new file with mode: 0644]
src/os_win.c [new file with mode: 0644]
src/os_win.h [new file with mode: 0644]
src/sqliteInt.h
src/utf.c

diff --git a/main.mk b/main.mk
index 3581eee7f2f2c2ba32b3739e24fa2389cae48a85..b346d3f1992445bf857e9250b8c5c97e4fea3f87 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -54,13 +54,10 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
 
 # Object files for the SQLite library.
 #
-# LIBOBJ = btree.o hash.o os.o pager.o random.o \
-#         util.o tclsqlite.o utf.o
-
-
 LIBOBJ = attach.o auth.o btree.o build.o copy.o date.o delete.o \
          expr.o func.o hash.o insert.o \
-         main.o opcodes.o os.o pager.o parse.o pragma.o printf.o random.o \
+         main.o opcodes.o os_mac.o os_unix.o os_win.o \
+         pager.o parse.o pragma.o printf.o random.o \
          select.o table.o tokenize.o trigger.o update.o util.o \
          vacuum.o vdbe.o vdbeaux.o where.o tclsqlite.o utf.o
 
@@ -82,7 +79,9 @@ SRC = \
   $(TOP)/src/hash.h \
   $(TOP)/src/insert.c \
   $(TOP)/src/main.c \
-  $(TOP)/src/os.c \
+  $(TOP)/src/os_mac.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
   $(TOP)/src/pager.c \
   $(TOP)/src/pager.h \
   $(TOP)/src/parse.y \
@@ -109,19 +108,12 @@ SRC = \
 
 # Source code to the test files.
 #
-TESTSRC_SUBSET = \
-   $(TOP)/src/os.c \
-   $(TOP)/src/pager.c \
-   $(TOP)/src/test1.c \
-   $(TOP)/src/test2.c \
-   $(TOP)/src/test3.c \
-   $(TOP)/src/test5.c \
-   $(TOP)/src/md5.c
-
 TESTSRC = \
   $(TOP)/src/btree.c \
   $(TOP)/src/func.c \
-  $(TOP)/src/os.c \
+  $(TOP)/src/os_mac.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
   $(TOP)/src/pager.c \
   $(TOP)/src/test1.c \
   $(TOP)/src/test2.c \
@@ -140,6 +132,9 @@ HDR = \
    $(TOP)/src/hash.h \
    opcodes.h \
    $(TOP)/src/os.h \
+   $(TOP)/src/os_mac.h \
+   $(TOP)/src/os_unix.h \
+   $(TOP)/src/os_win.h \
    $(TOP)/src/sqliteInt.h  \
    $(TOP)/src/vdbe.h \
    parse.h
@@ -191,15 +186,61 @@ lemon:    $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
        $(BCC) -o lemon $(TOP)/tool/lemon.c
        cp $(TOP)/tool/lempar.c .
 
+# Rules to build individual files
+#
+attach.o:      $(TOP)/src/attach.c $(HDR)
+       $(TCCX) -c $(TOP)/src/attach.c
+
+auth.o:        $(TOP)/src/auth.c $(HDR)
+       $(TCCX) -c $(TOP)/src/auth.c
+
 btree.o:       $(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h
        $(TCCX) -c $(TOP)/src/btree.c
 
-btree_rb.o:    $(TOP)/src/btree_rb.c $(HDR)
-       $(TCCX) -c $(TOP)/src/btree_rb.c
-
 build.o:       $(TOP)/src/build.c $(HDR)
        $(TCCX) -c $(TOP)/src/build.c
 
+# The config.h file will contain a single #define that tells us how
+# many bytes are in a pointer.  This only works if a pointer is the
+# same size on the host as it is on the target.  If you are cross-compiling
+# to a target with a different pointer size, you'll need to manually
+# configure the config.h file.
+#
+config.h:      
+       echo '#include <stdio.h>' >temp.c
+       echo 'int main(){printf(' >>temp.c
+       echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c
+       echo 'exit(0);}' >>temp.c
+       $(BCC) -o temp temp.c
+       ./temp >config.h
+       echo >>config.h
+       rm -f temp.c temp
+
+copy.o:        $(TOP)/src/copy.c $(HDR)
+       $(TCCX) -c $(TOP)/src/copy.c
+
+date.o:        $(TOP)/src/date.c $(HDR)
+       $(TCCX) -c $(TOP)/src/date.c
+
+delete.o:      $(TOP)/src/delete.c $(HDR)
+       $(TCCX) -c $(TOP)/src/delete.c
+
+encode.o:      $(TOP)/src/encode.c
+       $(TCCX) -c $(TOP)/src/encode.c
+
+expr.o:        $(TOP)/src/expr.c $(HDR)
+       $(TCCX) -c $(TOP)/src/expr.c
+
+func.o:        $(TOP)/src/func.c $(HDR)
+       $(TCCX) -c $(TOP)/src/func.c
+
+hash.o:        $(TOP)/src/hash.c $(HDR)
+       $(TCCX) -c $(TOP)/src/hash.c
+
+insert.o:      $(TOP)/src/insert.c $(HDR)
+       $(TCCX) -c $(TOP)/src/insert.c
+
+
 main.o:        $(TOP)/src/main.c $(HDR)
        $(TCCX) -c $(TOP)/src/main.c
 
@@ -222,8 +263,14 @@ opcodes.h: $(TOP)/src/vdbe.h
          sed -e 's/://' | \
          awk '{printf "#define %-30s %3d\n", $$2, ++cnt}' >>opcodes.h
 
-os.o:  $(TOP)/src/os.c $(HDR)
-       $(TCCX) -c $(TOP)/src/os.c
+os_mac.o:      $(TOP)/src/os_mac.c $(HDR)
+       $(TCCX) -c $(TOP)/src/os_mac.c
+
+os_unix.o:     $(TOP)/src/os_unix.c $(HDR)
+       $(TCCX) -c $(TOP)/src/os_unix.c
+
+os_win.o:      $(TOP)/src/os_win.c $(HDR)
+       $(TCCX) -c $(TOP)/src/os_win.c
 
 parse.o:       parse.c $(HDR)
        $(TCCX) -c parse.c
@@ -234,33 +281,38 @@ parse.c:  $(TOP)/src/parse.y lemon
        cp $(TOP)/src/parse.y .
        ./lemon parse.y
 
-# The config.h file will contain a single #define that tells us how
-# many bytes are in a pointer.  This only works if a pointer is the
-# same size on the host as it is on the target.  If you are cross-compiling
-# to a target with a different pointer size, you'll need to manually
-# configure the config.h file.
-#
-config.h:      
-       echo '#include <stdio.h>' >temp.c
-       echo 'int main(){printf(' >>temp.c
-       echo '"#define SQLITE_PTR_SZ %d",sizeof(char*));' >>temp.c
-       echo 'exit(0);}' >>temp.c
-       $(BCC) -o temp temp.c
-       ./temp >config.h
-       echo >>config.h
-       rm -f temp.c temp
+pragma.o:      $(TOP)/src/pragma.c $(HDR)
+       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/pragma.c
+
+printf.o:      $(TOP)/src/printf.c $(HDR)
+       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/printf.c
+
+random.o:      $(TOP)/src/random.c $(HDR)
+       $(TCCX) -c $(TOP)/src/random.c
+
+select.o:      $(TOP)/src/select.c $(HDR)
+       $(TCCX) -c $(TOP)/src/select.c
 
 sqlite.h:      $(TOP)/src/sqlite.h.in 
        sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
             -e s/--ENCODING--/$(ENCODING)/ \
                  $(TOP)/src/sqlite.h.in >sqlite.h
 
+table.o:       $(TOP)/src/table.c $(HDR)
+       $(TCCX) -c $(TOP)/src/table.c
+
+tclsqlite.o:   $(TOP)/src/tclsqlite.c $(HDR)
+       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
+
 tokenize.o:    $(TOP)/src/tokenize.c $(HDR)
        $(TCCX) -c $(TOP)/src/tokenize.c
 
 trigger.o:     $(TOP)/src/trigger.c $(HDR)
        $(TCCX) -c $(TOP)/src/trigger.c
 
+update.o:      $(TOP)/src/update.c $(HDR)
+       $(TCCX) -c $(TOP)/src/update.c
+
 utf.o: $(TOP)/src/utf.c $(HDR)
        $(TCCX) -c $(TOP)/src/utf.c
 
@@ -279,57 +331,8 @@ vdbeaux.o: $(TOP)/src/vdbeaux.c $(VDBEHDR)
 where.o:       $(TOP)/src/where.c $(HDR)
        $(TCCX) -c $(TOP)/src/where.c
 
-copy.o:        $(TOP)/src/copy.c $(HDR)
-       $(TCCX) -c $(TOP)/src/copy.c
-
-date.o:        $(TOP)/src/date.c $(HDR)
-       $(TCCX) -c $(TOP)/src/date.c
-
-delete.o:      $(TOP)/src/delete.c $(HDR)
-       $(TCCX) -c $(TOP)/src/delete.c
-
-encode.o:      $(TOP)/src/encode.c
-       $(TCCX) -c $(TOP)/src/encode.c
-
-expr.o:        $(TOP)/src/expr.c $(HDR)
-       $(TCCX) -c $(TOP)/src/expr.c
-
-func.o:        $(TOP)/src/func.c $(HDR)
-       $(TCCX) -c $(TOP)/src/func.c
-
-hash.o:        $(TOP)/src/hash.c $(HDR)
-       $(TCCX) -c $(TOP)/src/hash.c
-
-insert.o:      $(TOP)/src/insert.c $(HDR)
-       $(TCCX) -c $(TOP)/src/insert.c
-
-random.o:      $(TOP)/src/random.c $(HDR)
-       $(TCCX) -c $(TOP)/src/random.c
-
-select.o:      $(TOP)/src/select.c $(HDR)
-       $(TCCX) -c $(TOP)/src/select.c
-
-table.o:       $(TOP)/src/table.c $(HDR)
-       $(TCCX) -c $(TOP)/src/table.c
-
-update.o:      $(TOP)/src/update.c $(HDR)
-       $(TCCX) -c $(TOP)/src/update.c
-
-tclsqlite.o:   $(TOP)/src/tclsqlite.c $(HDR)
-       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
-
-pragma.o:      $(TOP)/src/pragma.c $(HDR)
-       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/pragma.c
-
-printf.o:      $(TOP)/src/printf.c $(HDR)
-       $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/printf.c
-
-attach.o:      $(TOP)/src/attach.c $(HDR)
-       $(TCCX) -c $(TOP)/src/attach.c
-
-auth.o:        $(TOP)/src/auth.c $(HDR)
-       $(TCCX) -c $(TOP)/src/auth.c
-
+# Rules for building test programs and for running tests
+#
 tclsqlite:     $(TOP)/src/tclsqlite.c libsqlite.a
        $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite \
                $(TOP)/src/tclsqlite.c libsqlite.a $(LIBTCL)
@@ -345,11 +348,13 @@ fulltest: testfixture$(EXE) sqlite$(EXE)
 test:  testfixture$(EXE) sqlite$(EXE)
        ./testfixture$(EXE) $(TOP)/test/quick.test
 
-index.html:    $(TOP)/www/index.tcl last_change
-       tclsh $(TOP)/www/index.tcl `cat $(TOP)/VERSION` >index.html
+# Rules used to build documentation
+#
+arch.html:     $(TOP)/www/arch.tcl
+       tclsh $(TOP)/www/arch.tcl >arch.html
 
-sqlite.html:   $(TOP)/www/sqlite.tcl
-       tclsh $(TOP)/www/sqlite.tcl >sqlite.html
+arch.png:      $(TOP)/www/arch.png
+       cp $(TOP)/www/arch.png .
 
 c_interface.html:      $(TOP)/www/c_interface.tcl
        tclsh $(TOP)/www/c_interface.tcl >c_interface.html
@@ -357,87 +362,89 @@ c_interface.html: $(TOP)/www/c_interface.tcl
 changes.html:  $(TOP)/www/changes.tcl
        tclsh $(TOP)/www/changes.tcl >changes.html
 
-lang.html:     $(TOP)/www/lang.tcl
-       tclsh $(TOP)/www/lang.tcl >lang.html
-
-vdbe.html:     $(TOP)/www/vdbe.tcl
-       tclsh $(TOP)/www/vdbe.tcl >vdbe.html
-
-arch.html:     $(TOP)/www/arch.tcl
-       tclsh $(TOP)/www/arch.tcl >arch.html
-
-arch.png:      $(TOP)/www/arch.png
-       cp $(TOP)/www/arch.png .
-
-opcode.html:   $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c
-       tclsh $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c >opcode.html
-
-mingw.html:    $(TOP)/www/mingw.tcl
-       tclsh $(TOP)/www/mingw.tcl >mingw.html
+conflict.html: $(TOP)/www/conflict.tcl
+       tclsh $(TOP)/www/conflict.tcl >conflict.html
 
-tclsqlite.html:        $(TOP)/www/tclsqlite.tcl
-       tclsh $(TOP)/www/tclsqlite.tcl >tclsqlite.html
+datatypes.html:        $(TOP)/www/datatypes.tcl
+       tclsh $(TOP)/www/datatypes.tcl >datatypes.html
 
-speed.html:    $(TOP)/www/speed.tcl
-       tclsh $(TOP)/www/speed.tcl >speed.html
+download.html: $(TOP)/www/download.tcl
+       tclsh $(TOP)/www/download.tcl >download.html
 
 faq.html:      $(TOP)/www/faq.tcl
        tclsh $(TOP)/www/faq.tcl >faq.html
 
+fileformat.html:       $(TOP)/www/fileformat.tcl
+       tclsh $(TOP)/www/fileformat.tcl >fileformat.html
+
 formatchng.html:       $(TOP)/www/formatchng.tcl
        tclsh $(TOP)/www/formatchng.tcl >formatchng.html
 
-conflict.html: $(TOP)/www/conflict.tcl
-       tclsh $(TOP)/www/conflict.tcl >conflict.html
+index.html:    $(TOP)/www/index.tcl last_change
+       tclsh $(TOP)/www/index.tcl `cat $(TOP)/VERSION` >index.html
 
-download.html: $(TOP)/www/download.tcl
-       tclsh $(TOP)/www/download.tcl >download.html
+lang.html:     $(TOP)/www/lang.tcl
+       tclsh $(TOP)/www/lang.tcl >lang.html
 
 omitted.html:  $(TOP)/www/omitted.tcl
        tclsh $(TOP)/www/omitted.tcl >omitted.html
 
-datatypes.html:        $(TOP)/www/datatypes.tcl
-       tclsh $(TOP)/www/datatypes.tcl >datatypes.html
+opcode.html:   $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c
+       tclsh $(TOP)/www/opcode.tcl $(TOP)/src/vdbe.c >opcode.html
+
+mingw.html:    $(TOP)/www/mingw.tcl
+       tclsh $(TOP)/www/mingw.tcl >mingw.html
+
+nulls.html:    $(TOP)/www/nulls.tcl
+       tclsh $(TOP)/www/nulls.tcl >nulls.html
 
 quickstart.html:       $(TOP)/www/quickstart.tcl
        tclsh $(TOP)/www/quickstart.tcl >quickstart.html
 
-fileformat.html:       $(TOP)/www/fileformat.tcl
-       tclsh $(TOP)/www/fileformat.tcl >fileformat.html
+speed.html:    $(TOP)/www/speed.tcl
+       tclsh $(TOP)/www/speed.tcl >speed.html
 
-nulls.html:    $(TOP)/www/nulls.tcl
-       tclsh $(TOP)/www/nulls.tcl >nulls.html
+sqlite.html:   $(TOP)/www/sqlite.tcl
+       tclsh $(TOP)/www/sqlite.tcl >sqlite.html
+
+tclsqlite.html:        $(TOP)/www/tclsqlite.tcl
+       tclsh $(TOP)/www/tclsqlite.tcl >tclsqlite.html
+
+vdbe.html:     $(TOP)/www/vdbe.tcl
+       tclsh $(TOP)/www/vdbe.tcl >vdbe.html
 
 
 # Files to be published on the website.
 #
 DOC = \
-  index.html \
-  sqlite.html \
-  changes.html \
-  lang.html \
-  opcode.html \
   arch.html \
   arch.png \
-  vdbe.html \
+  changes.html \
   c_interface.html \
-  mingw.html \
-  tclsqlite.html \
+  conflict.html \
+  datatypes.html \
   download.html \
-  speed.html \
   faq.html \
+  fileformat.html \
   formatchng.html \
-  conflict.html \
+  index.html \
+  lang.html \
+  mingw.html \
+  nulls.html \
   omitted.html \
-  datatypes.html \
+  opcode.html \
   quickstart.html \
-  fileformat.html \
-  nulls.html
+  speed.html \
+  sqlite.html \
+  tclsqlite.html \
+  vdbe.html 
 
 doc:   $(DOC)
        mkdir -p doc
        mv $(DOC) doc
 
+# Standard install and cleanup targets
+#
 install:       sqlite libsqlite.a sqlite.h
        mv sqlite /usr/bin
        mv libsqlite.a /usr/lib
index ca7d034a9be3f222a3820d9bf8fd5a9160c3b37e..ac021341e276dc70c6693882c45ed1f6f1ee6161 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bug\sfix\sin\svdbe.c\s-\svariable\sdeclarations\smust\scome\sbefore\scode\sin\sANSI\sC.\s(CVS\s1440)
-D 2004-05-22T11:09:30
+C Split\sup\sos.c\sinto\sseparate\sfiles,\sone\sfor\seach\splatform.\s(CVS\s1441)
+D 2004-05-22T17:41:59
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
-F main.mk fbc906044c1b891be4bd9e48a74a9fd5bcd5fc81
+F main.mk a56ffbc29258e373614da28baa568f173d80d0d7
 F publish.sh 1cd5c982388560fa91eedf6a338e210f713b35c8
 F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
@@ -37,10 +37,16 @@ F src/func.c cfbb7096efb58e2857e3b312a8958a12774b625a
 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c e510d62d23b4de4d901e7ccbbe7833b7fb3b9570
-F src/main.c 6b59eda1481376df6c8e2b5fa2f24b4c101ffd72
+F src/main.c 289e05cf20d74c0b393055745591e6ea8568faee
 F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c
-F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e
-F src/os.h 6e446a17cbeb6c2ce470683a0bb8d9c63abe8607
+F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
+F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
+F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0
+F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4
+F src/os_unix.c e93a6858b4ab880ce91cbc95af14975ef53b6369
+F src/os_unix.h 426e1480f0847a7f8ba22aa9ac5115520875610b
+F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
+F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
 F src/pager.c 6ff6b906427d4824099140776cb8768f922f3dc5
 F src/pager.h 78a00ac280899bcba1a89dc51585dcae6b7b3253
 F src/parse.y 567718866b94d58a6c7681cc45ba7987771d583a
@@ -50,7 +56,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 7d77a8bed7eeac23216d42fc1be006fb4352fcdc
 F src/shell.c 657623c2a3df126538d41842c2146cadbd52b154
 F src/sqlite.h.in 9a4c374f4030cde181593166d71bf376274ca45c
-F src/sqliteInt.h 4b45892cb082f4883efb58c5e13328c42cbc7642
+F src/sqliteInt.h 2d7b2c7e734f95c4e21513224cb7815adea86e2a
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c f241854328ee2b06006efded270d84799159f760
 F src/test1.c b5f2f9f9d866c8a586b8d47c5999d2cbefaac686
@@ -61,7 +67,7 @@ F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
 F src/update.c 1a5e9182596f3ea8c7a141e308a3d2a7e5689fee
-F src/utf.c 537e1c98cddc623628d44497ec02c2246cf66dea
+F src/utf.c a4640c6a1530b43b651495246349ee0a6eca3038
 F src/util.c 5cbeb452da09cfc7248de9948c15b14d840723f7
 F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
 F src/vdbe.c c1846f4b2938d11250f532b068d7856fd8decd6c
@@ -197,7 +203,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 891be63a92097384e1b00993d35f002048c4b42e
-R 543ddb60688125b3fffe05e3e9ef31d2
+P c36203de22f673691783529e06ce5a58bcebeedc
+R 2c92275d417e436955c48e131db4f92e
 U drh
-Z 735268b125ff8e5769b42e78ffc4dd1e
+Z f6cdae699efac8ed1a9148f3d6e06cad
index f1acd5ce18584e54e0f876cdcf434fc847190d06..0681ac5d9481c4a51663a234ea3722482f622e6c 100644 (file)
@@ -1 +1 @@
-c36203de22f673691783529e06ce5a58bcebeedc
\ No newline at end of file
+5c61be1c47ac960fba2a642e69a98436ce1cd725
\ No newline at end of file
index fefb1f43e2a0abb35227ab72fa86a9e8d7704ee2..09883aa044f75047c846d0ebdcd46038cdc14dd4 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.184 2004/05/22 09:21:21 danielk1977 Exp $
+** $Id: main.c,v 1.185 2004/05/22 17:41:59 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -29,6 +29,12 @@ typedef struct {
   char **pzErrMsg;    /* Error message stored here */
 } InitData;
 
+/*
+** The following constant value is used by the SQLITE3_BIGENDIAN and
+** SQLITE3_LITTLEENDIAN macros.
+*/
+const int sqlite3one = 1;
+
 /*
 ** Fill the InitData structure with an error message that indicates
 ** that the database is corrupt.
@@ -1335,4 +1341,3 @@ int sqlite3_reset_new(sqlite3_stmt *pStmt){
   sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0);
   return rc;
 }
-
index a88756f8c1ddcb1a4bd0064c7a083117ae25a8ab..93fa5352c89a9de12384258603222aef3ae0f4c6 100644 (file)
--- a/src/os.h
+++ b/src/os.h
 #ifndef _SQLITE_OS_H_
 #define _SQLITE_OS_H_
 
-/*
-** Helpful hint:  To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
-** to the compiler command line.
-*/
-
-/*
-** These #defines should enable >2GB file support on Posix if the
-** underlying operating system supports it.  If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line.  This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
-** without this option, LFS is enable.  But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE       1
-# ifndef _FILE_OFFSET_BITS
-#   define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** Temporary files are named starting with this prefix followed by 16 random
-** alphanumeric characters, and no file extension. They are stored in the
-** OS's standard temporary file directory, and are deleted prior to exit.
-** If sqlite is being embedded in another program, you may wish to change the
-** prefix to reflect your program's name, so that if your program exits
-** prematurely, old temporary files can be easily identified. This can be done
-** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
-*/
-#ifndef TEMP_FILE_PREFIX
-# define TEMP_FILE_PREFIX "sqlite_"
-#endif
-
 /*
 ** Figure out if we are dealing with Unix, Windows or MacOS.
 **
 #endif
 
 /*
-** A handle for an open file is stored in an OsFile object.
+** Invoke the appropriate operating-system specific header file.
 */
 #if OS_UNIX
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# include <unistd.h>
-  typedef struct OsFile OsFile;
-  struct OsFile {
-    struct openCnt *pOpen;    /* Info about all open fd's on this inode */
-    struct lockInfo *pLock;   /* Info about locks on this inode */
-    int fd;                   /* The file descriptor */
-    int locked;               /* True if this instance holds the lock */
-    int dirfd;                /* File descriptor for the directory */
-  };
-# define SQLITE_TEMPNAME_SIZE 200
-# if defined(HAVE_USLEEP) && HAVE_USLEEP
-#  define SQLITE_MIN_SLEEP_MS 1
-# else
-#  define SQLITE_MIN_SLEEP_MS 1000
-# endif
+# include "os_unix.h"
 #endif
-
 #if OS_WIN
-#include <windows.h>
-#include <winbase.h>
-  typedef struct OsFile OsFile;
-  struct OsFile {
-    HANDLE h;               /* Handle for accessing the file */
-    int locked;             /* 0: unlocked, <0: write lock, >0: read lock */
-  };
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-    typedef __int64 off_t;
-# else
-#  if !defined(_CYGWIN_TYPES_H)
-     typedef long long off_t;
-#    if defined(__MINGW32__)
-#      define  _OFF_T_
-#    endif
-#  endif
-# endif
-# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
-# define SQLITE_MIN_SLEEP_MS 1
+# include "os_win.h"
 #endif
-
 #if OS_MAC
-# include <unistd.h>
-# include <Files.h>
-  typedef struct OsFile OsFile;
-  struct OsFile {
-    SInt16 refNum;           /* Data fork/file reference number */
-    SInt16 refNumRF;         /* Resource fork reference number (for locking) */
-    int locked;              /* 0: unlocked, <0: write lock, >0: read lock */
-    int delOnClose;          /* True if file is to be deleted on close */
-    char *pathToDel;         /* Name of file to delete on close */
-  };
-# ifdef _LARGE_FILE
-    typedef SInt64 off_t;
-# else
-    typedef SInt32 off_t;
-# endif
-# define SQLITE_TEMPNAME_SIZE _MAX_PATH
-# define SQLITE_MIN_SLEEP_MS 17
+# include "os_mac.h"
 #endif
 
 /*
-** Macros to determine whether the machine is big or little endian,
-** evaluated at runtime.
+** Temporary files are named starting with this prefix followed by 16 random
+** alphanumeric characters, and no file extension. They are stored in the
+** OS's standard temporary file directory, and are deleted prior to exit.
+** If sqlite is being embedded in another program, you may wish to change the
+** prefix to reflect your program's name, so that if your program exits
+** prematurely, old temporary files can be easily identified. This can be done
+** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
 */
-static const int sqlite3_one = 1;
-#define SQLITE3_BIGENDIAN (*(char *)(&sqlite3_one)==0)
-#define SQLITE3_LITTLEENDIAN (*(char *)(&sqlite3_one)==1)
+#ifndef TEMP_FILE_PREFIX
+# define TEMP_FILE_PREFIX "sqlite_"
+#endif
+
 
 int sqlite3OsDelete(const char*);
 int sqlite3OsFileExists(const char*);
@@ -194,9 +106,4 @@ void sqlite3OsEnterMutex(void);
 void sqlite3OsLeaveMutex(void);
 char *sqlite3OsFullPathname(const char*);
 
-
-
 #endif /* _SQLITE_OS_H_ */
-
-
-
diff --git a/src/os_common.h b/src/os_common.h
new file mode 100644 (file)
index 0000000..70d0dd9
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains macros and a little bit of code that is common to
+** all of the platform-specific files (os_*.c) and is #included into those
+** files.
+**
+** This file should be #included by the os_*.c files only.  It is not a
+** general purpose header file.
+*/
+
+
+/*
+** Macros for performance tracing.  Normally turned off.  Only works
+** on i486 hardware.
+*/
+#if 0
+static int last_page = 0;
+__inline__ unsigned long long int hwtime(void){
+  unsigned long long int x;
+  __asm__("rdtsc\n\t"
+          "mov %%edx, %%ecx\n\t"
+          :"=A" (x));
+  return x;
+}
+static unsigned long long int g_start;
+static unsigned int elapse;
+#define TIMER_START       g_start=hwtime()
+#define TIMER_END         elapse=hwtime()-g_start
+#define SEEK(X)           last_page=(X)
+#define TRACE1(X)         fprintf(stderr,X)
+#define TRACE2(X,Y)       fprintf(stderr,X,Y)
+#define TRACE3(X,Y,Z)     fprintf(stderr,X,Y,Z)
+#define TRACE4(X,Y,Z,A)   fprintf(stderr,X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
+#else
+#define TIMER_START
+#define TIMER_END
+#define SEEK(X)
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#define TRACE3(X,Y,Z)
+#define TRACE4(X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B)
+#endif
+
+
+/*
+** If we compile with the SQLITE_TEST macro set, then the following block
+** of code will give us the ability to simulate a disk I/O error.  This
+** is used for testing the I/O recovery logic.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_io_error_pending = 0;
+#define SimulateIOError(A)  \
+   if( sqlite3_io_error_pending ) \
+     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
+static void local_ioerr(){
+  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
+}
+#else
+#define SimulateIOError(A)
+#endif
+
+/*
+** When testing, keep a count of the number of open files.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_open_file_count = 0;
+#define OpenCounter(X)  sqlite3_open_file_count+=(X)
+#else
+#define OpenCounter(X)
+#endif
diff --git a/src/os_mac.c b/src/os_mac.c
new file mode 100644 (file)
index 0000000..cd88d56
--- /dev/null
@@ -0,0 +1,729 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains code that is specific classic mac.  Mac OS X
+** uses the os_unix.c file, not this one.
+*/
+#include "os.h"          /* Must be first to enable large file support */
+#if OS_MAC               /* This file used on classic mac only */
+#include "sqliteInt.h"
+
+#include <extras.h>
+#include <path2fss.h>
+#include <TextUtils.h>
+#include <FinderRegistry.h>
+#include <Folders.h>
+#include <Timer.h>
+#include <OSUtils.h>
+
+/*
+** Macros used to determine whether or not to use threads.
+*/
+#if defined(THREADSAFE) && THREADSAFE
+# include <Multiprocessing.h>
+# define SQLITE_MACOS_MULTITASKING 1
+#endif
+
+/*
+** Include code that is common to all os_*.c files
+*/
+#include "os_common.h"
+
+/*
+** Delete the named file
+*/
+int sqlite3OsDelete(const char *zFilename){
+  unlink(zFilename);
+  return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqlite3OsFileExists(const char *zFilename){
+  return access(zFilename, 0)==0;
+}
+
+/*
+** Attempt to open a file for both reading and writing.  If that
+** fails, try opening it read-only.  If the file does not exist,
+** try to create it.
+**
+** On success, a handle for the open file is written to *id
+** and *pReadonly is set to 0 if the file was opened for reading and
+** writing or 1 if the file was opened read-only.  The function returns
+** SQLITE_OK.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id and *pReadonly unchanged.
+*/
+int sqlite3OsOpenReadWrite(
+  const char *zFilename,
+  OsFile *id,
+  int *pReadonly
+){
+  FSSpec fsSpec;
+# ifdef _LARGE_FILE
+  HFSUniStr255 dfName;
+  FSRef fsRef;
+  if( __path2fss(zFilename, &fsSpec) != noErr ){
+    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
+      return SQLITE_CANTOPEN;
+  }
+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+    return SQLITE_CANTOPEN;
+  FSGetDataForkName(&dfName);
+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
+                 fsRdWrShPerm, &(id->refNum)) != noErr ){
+    if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
+                   fsRdWrPerm, &(id->refNum)) != noErr ){
+      if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
+                   fsRdPerm, &(id->refNum)) != noErr )
+        return SQLITE_CANTOPEN;
+      else
+        *pReadonly = 1;
+    } else
+      *pReadonly = 0;
+  } else
+    *pReadonly = 0;
+# else
+  __path2fss(zFilename, &fsSpec);
+  if( !sqlite3OsFileExists(zFilename) ){
+    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
+      return SQLITE_CANTOPEN;
+  }
+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
+    if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
+      if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
+        return SQLITE_CANTOPEN;
+      else
+        *pReadonly = 1;
+    } else
+      *pReadonly = 0;
+  } else
+    *pReadonly = 0;
+# endif
+  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
+    id->refNumRF = -1;
+  }
+  id->locked = 0;
+  id->delOnClose = 0;
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+
+/*
+** Attempt to open a new file for exclusive access by this process.
+** The file will be opened for both reading and writing.  To avoid
+** a potential security problem, we do not allow the file to have
+** previously existed.  Nor do we allow the file to be a symbolic
+** link.
+**
+** If delFlag is true, then make arrangements to automatically delete
+** the file when it is closed.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+  FSSpec fsSpec;
+# ifdef _LARGE_FILE
+  HFSUniStr255 dfName;
+  FSRef fsRef;
+  __path2fss(zFilename, &fsSpec);
+  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
+    return SQLITE_CANTOPEN;
+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+    return SQLITE_CANTOPEN;
+  FSGetDataForkName(&dfName);
+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
+                 fsRdWrPerm, &(id->refNum)) != noErr )
+    return SQLITE_CANTOPEN;
+# else
+  __path2fss(zFilename, &fsSpec);
+  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
+    return SQLITE_CANTOPEN;
+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
+    return SQLITE_CANTOPEN;
+# endif
+  id->refNumRF = -1;
+  id->locked = 0;
+  id->delOnClose = delFlag;
+  if (delFlag)
+    id->pathToDel = sqlite3OsFullPathname(zFilename);
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+/*
+** Attempt to open a new file for read-only access.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+  FSSpec fsSpec;
+# ifdef _LARGE_FILE
+  HFSUniStr255 dfName;
+  FSRef fsRef;
+  if( __path2fss(zFilename, &fsSpec) != noErr )
+    return SQLITE_CANTOPEN;
+  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+    return SQLITE_CANTOPEN;
+  FSGetDataForkName(&dfName);
+  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
+                 fsRdPerm, &(id->refNum)) != noErr )
+    return SQLITE_CANTOPEN;
+# else
+  __path2fss(zFilename, &fsSpec);
+  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
+    return SQLITE_CANTOPEN;
+# endif
+  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
+    id->refNumRF = -1;
+  }
+  id->locked = 0;
+  id->delOnClose = 0;
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+/*
+** Attempt to open a file descriptor for the directory that contains a
+** file.  This file descriptor can be used to fsync() the directory
+** in order to make sure the creation of a new file is actually written
+** to disk.
+**
+** This routine is only meaningful for Unix.  It is a no-op under
+** windows since windows does not support hard links.
+**
+** On success, a handle for a previously open file is at *id is
+** updated with the new directory file descriptor and SQLITE_OK is
+** returned.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id unchanged.
+*/
+int sqlite3OsOpenDirectory(
+  const char *zDirname,
+  OsFile *id
+){
+  return SQLITE_OK;
+}
+
+/*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at least SQLITE_TEMPNAME_SIZE characters.
+*/
+int sqlite3OsTempFileName(char *zBuf){
+  static char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  char zTempPath[SQLITE_TEMPNAME_SIZE];
+  char zdirName[32];
+  CInfoPBRec infoRec;
+  Str31 dirName;
+  memset(&infoRec, 0, sizeof(infoRec));
+  memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
+  if( FindFolder(kOnSystemDisk, kTemporaryFolderType,  kCreateFolder,
+       &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
+    infoRec.dirInfo.ioNamePtr = dirName;
+    do{
+      infoRec.dirInfo.ioFDirIndex = -1;
+      infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
+      if( PBGetCatInfoSync(&infoRec) == noErr ){
+        CopyPascalStringToC(dirName, zdirName);
+        i = strlen(zdirName);
+        memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
+        strcpy(zTempPath, zdirName);
+        zTempPath[i] = ':';
+      }else{
+        *zTempPath = 0;
+        break;
+      }
+    } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
+  }
+  if( *zTempPath == 0 )
+    getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
+  for(;;){
+    sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
+    j = strlen(zBuf);
+    sqlite3Randomness(15, &zBuf[j]);
+    for(i=0; i<15; i++, j++){
+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+    }
+    zBuf[j] = 0;
+    if( !sqlite3OsFileExists(zBuf) ) break;
+  }
+  return SQLITE_OK; 
+}
+
+/*
+** Close a file.
+*/
+int sqlite3OsClose(OsFile *id){
+  if( id->refNumRF!=-1 )
+    FSClose(id->refNumRF);
+# ifdef _LARGE_FILE
+  FSCloseFork(id->refNum);
+# else
+  FSClose(id->refNum);
+# endif
+  if( id->delOnClose ){
+    unlink(id->pathToDel);
+    sqliteFree(id->pathToDel);
+  }
+  OpenCounter(-1);
+  return SQLITE_OK;
+}
+
+/*
+** Read data from a file into a buffer.  Return SQLITE_OK if all
+** bytes were read successfully and SQLITE_IOERR if anything goes
+** wrong.
+*/
+int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+  int got;
+  SimulateIOError(SQLITE_IOERR);
+  TRACE2("READ %d\n", last_page);
+# ifdef _LARGE_FILE
+  FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
+# else
+  got = amt;
+  FSRead(id->refNum, &got, pBuf);
+# endif
+  if( got==amt ){
+    return SQLITE_OK;
+  }else{
+    return SQLITE_IOERR;
+  }
+}
+
+/*
+** Write data from a buffer into a file.  Return SQLITE_OK on success
+** or some other error code on failure.
+*/
+int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+  OSErr oserr;
+  int wrote = 0;
+  SimulateIOError(SQLITE_IOERR);
+  TRACE2("WRITE %d\n", last_page);
+  while( amt>0 ){
+# ifdef _LARGE_FILE
+    oserr = FSWriteFork(id->refNum, fsAtMark, 0,
+                        (ByteCount)amt, pBuf, (ByteCount*)&wrote);
+# else
+    wrote = amt;
+    oserr = FSWrite(id->refNum, &wrote, pBuf);
+# endif
+    if( wrote == 0 || oserr != noErr)
+      break;
+    amt -= wrote;
+    pBuf = &((char*)pBuf)[wrote];
+  }
+  if( oserr != noErr || amt>wrote ){
+    return SQLITE_FULL;
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Move the read/write pointer in a file.
+*/
+int sqlite3OsSeek(OsFile *id, off_t offset){
+  off_t curSize;
+  SEEK(offset/1024 + 1);
+  if( sqlite3OsFileSize(id, &curSize) != SQLITE_OK ){
+    return SQLITE_IOERR;
+  }
+  if( offset >= curSize ){
+    if( sqlite3OsTruncate(id, offset+1) != SQLITE_OK ){
+      return SQLITE_IOERR;
+    }
+  }
+# ifdef _LARGE_FILE
+  if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
+# else
+  if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
+# endif
+    return SQLITE_IOERR;
+  }else{
+    return SQLITE_OK;
+  }
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+**
+** Under Unix, also make sure that the directory entry for the file
+** has been created by fsync-ing the directory that contains the file.
+** If we do not do this and we encounter a power failure, the directory
+** entry for the journal might not exist after we reboot.  The next
+** SQLite to access the file will not know that the journal exists (because
+** the directory entry for the journal was never created) and the transaction
+** will not roll back - possibly leading to database corruption.
+*/
+int sqlite3OsSync(OsFile *id){
+# ifdef _LARGE_FILE
+  if( FSFlushFork(id->refNum) != noErr ){
+# else
+  ParamBlockRec params;
+  memset(&params, 0, sizeof(ParamBlockRec));
+  params.ioParam.ioRefNum = id->refNum;
+  if( PBFlushFileSync(&params) != noErr ){
+# endif
+    return SQLITE_IOERR;
+  }else{
+    return SQLITE_OK;
+  }
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+int sqlite3OsTruncate(OsFile *id, off_t nByte){
+  SimulateIOError(SQLITE_IOERR);
+# ifdef _LARGE_FILE
+  if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
+# else
+  if( SetEOF(id->refNum, nByte) != noErr ){
+# endif
+    return SQLITE_IOERR;
+  }else{
+    return SQLITE_OK;
+  }
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+int sqlite3OsFileSize(OsFile *id, off_t *pSize){
+# ifdef _LARGE_FILE
+  if( FSGetForkSize(id->refNum, pSize) != noErr){
+# else
+  if( GetEOF(id->refNum, pSize) != noErr ){
+# endif
+    return SQLITE_IOERR;
+  }else{
+    return SQLITE_OK;
+  }
+}
+
+/*
+** Windows file locking notes:  [similar issues apply to MacOS]
+**
+** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
+** those functions are not available.  So we use only LockFile() and
+** UnlockFile().
+**
+** LockFile() prevents not just writing but also reading by other processes.
+** (This is a design error on the part of Windows, but there is nothing
+** we can do about that.)  So the region used for locking is at the
+** end of the file where it is unlikely to ever interfere with an
+** actual read attempt.
+**
+** A database read lock is obtained by locking a single randomly-chosen 
+** byte out of a specific range of bytes. The lock byte is obtained at 
+** random so two separate readers can probably access the file at the 
+** same time, unless they are unlucky and choose the same lock byte.
+** A database write lock is obtained by locking all bytes in the range.
+** There can only be one writer.
+**
+** A lock is obtained on the first byte of the lock range before acquiring
+** either a read lock or a write lock.  This prevents two processes from
+** attempting to get a lock at a same time.  The semantics of 
+** sqlite3OsReadLock() require that if there is already a write lock, that
+** lock is converted into a read lock atomically.  The lock on the first
+** byte allows us to drop the old write lock and get the read lock without
+** another process jumping into the middle and messing us up.  The same
+** argument applies to sqlite3OsWriteLock().
+**
+** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
+** which means we can use reader/writer locks.  When reader writer locks
+** are used, the lock is placed on the same range of bytes that is used
+** for probabilistic locking in Win95/98/ME.  Hence, the locking scheme
+** will support two or more Win95 readers or two or more WinNT readers.
+** But a single Win95 reader will lock out all WinNT readers and a single
+** WinNT reader will lock out all other Win95 readers.
+**
+** Note: On MacOS we use the resource fork for locking.
+**
+** The following #defines specify the range of bytes used for locking.
+** N_LOCKBYTE is the number of bytes available for doing the locking.
+** The first byte used to hold the lock while the lock is changing does
+** not count toward this number.  FIRST_LOCKBYTE is the address of
+** the first byte in the range of bytes used for locking.
+*/
+#define N_LOCKBYTE       10239
+#define FIRST_LOCKBYTE   (0x000fffff - N_LOCKBYTE)
+
+/*
+** Change the status of the lock on the file "id" to be a readlock.
+** If the file was write locked, then this reduces the lock to a read.
+** If the file was read locked, then this acquires a new read lock.
+**
+** Return SQLITE_OK on success and SQLITE_BUSY on failure.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsReadLock(OsFile *id){
+  int rc;
+  if( id->locked>0 || id->refNumRF == -1 ){
+    rc = SQLITE_OK;
+  }else{
+    int lk;
+    OSErr res;
+    int cnt = 5;
+    ParamBlockRec params;
+    sqlite3Randomness(sizeof(lk), &lk);
+    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
+    memset(&params, 0, sizeof(params));
+    params.ioParam.ioRefNum = id->refNumRF;
+    params.ioParam.ioPosMode = fsFromStart;
+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+    params.ioParam.ioReqCount = 1;
+    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
+      UInt32 finalTicks;
+      Delay(1, &finalTicks); /* 1/60 sec */
+    }
+    if( res == noErr ){
+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+      params.ioParam.ioReqCount = N_LOCKBYTE;
+      PBUnlockRangeSync(&params);
+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
+      params.ioParam.ioReqCount = 1;
+      res = PBLockRangeSync(&params);
+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+      params.ioParam.ioReqCount = 1;
+      PBUnlockRangeSync(&params);
+    }
+    if( res == noErr ){
+      id->locked = lk;
+      rc = SQLITE_OK;
+    }else{
+      rc = SQLITE_BUSY;
+    }
+  }
+  return rc;
+}
+
+/*
+** Change the lock status to be an exclusive or write lock.  Return
+** SQLITE_OK on success and SQLITE_BUSY on a failure.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsWriteLock(OsFile *id){
+  int rc;
+  if( id->locked<0 || id->refNumRF == -1 ){
+    rc = SQLITE_OK;
+  }else{
+    OSErr res;
+    int cnt = 5;
+    ParamBlockRec params;
+    memset(&params, 0, sizeof(params));
+    params.ioParam.ioRefNum = id->refNumRF;
+    params.ioParam.ioPosMode = fsFromStart;
+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+    params.ioParam.ioReqCount = 1;
+    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
+      UInt32 finalTicks;
+      Delay(1, &finalTicks); /* 1/60 sec */
+    }
+    if( res == noErr ){
+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
+      params.ioParam.ioReqCount = 1;
+      if( id->locked==0 
+            || PBUnlockRangeSync(&params)==noErr ){
+        params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+        params.ioParam.ioReqCount = N_LOCKBYTE;
+        res = PBLockRangeSync(&params);
+      }else{
+        res = afpRangeNotLocked;
+      }
+      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+      params.ioParam.ioReqCount = 1;
+      PBUnlockRangeSync(&params);
+    }
+    if( res == noErr ){
+      id->locked = -1;
+      rc = SQLITE_OK;
+    }else{
+      rc = SQLITE_BUSY;
+    }
+  }
+  return rc;
+}
+
+/*
+** Unlock the given file descriptor.  If the file descriptor was
+** not previously locked, then this routine is a no-op.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsUnlock(OsFile *id){
+  int rc;
+  ParamBlockRec params;
+  memset(&params, 0, sizeof(params));
+  params.ioParam.ioRefNum = id->refNumRF;
+  params.ioParam.ioPosMode = fsFromStart;
+  if( id->locked==0 || id->refNumRF == -1 ){
+    rc = SQLITE_OK;
+  }else if( id->locked<0 ){
+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+    params.ioParam.ioReqCount = N_LOCKBYTE;
+    PBUnlockRangeSync(&params);
+    rc = SQLITE_OK;
+    id->locked = 0;
+  }else{
+    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
+    params.ioParam.ioReqCount = 1;
+    PBUnlockRangeSync(&params);
+    rc = SQLITE_OK;
+    id->locked = 0;
+  }
+  return rc;
+}
+
+/*
+** Get information to seed the random number generator.  The seed
+** is written into the buffer zBuf[256].  The calling function must
+** supply a sufficiently large buffer.
+*/
+int sqlite3OsRandomSeed(char *zBuf){
+  /* We have to initialize zBuf to prevent valgrind from reporting
+  ** errors.  The reports issued by valgrind are incorrect - we would
+  ** prefer that the randomness be increased by making use of the
+  ** uninitialized space in zBuf - but valgrind errors tend to worry
+  ** some users.  Rather than argue, it seems easier just to initialize
+  ** the whole array and silence valgrind, even if that means less randomness
+  ** in the random seed.
+  **
+  ** When testing, initializing zBuf[] to zero is all we do.  That means
+  ** that we always use the same random number sequence.* This makes the
+  ** tests repeatable.
+  */
+  memset(zBuf, 0, 256);
+#if !defined(SQLITE_TEST)
+  {
+    int pid;
+    Microseconds((UnsignedWide*)zBuf);
+    pid = getpid();
+    memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
+  }
+#endif
+  return SQLITE_OK;
+}
+
+/*
+** Sleep for a little while.  Return the amount of time slept.
+*/
+int sqlite3OsSleep(int ms){
+  UInt32 finalTicks;
+  UInt32 ticks = (((UInt32)ms+16)*3)/50;  /* 1/60 sec per tick */
+  Delay(ticks, &finalTicks);
+  return (int)((ticks*50)/3);
+}
+
+/*
+** Static variables used for thread synchronization
+*/
+static int inMutex = 0;
+#ifdef SQLITE_MACOS_MULTITASKING
+  static MPCriticalRegionID criticalRegion;
+#endif
+
+/*
+** The following pair of routine implement mutual exclusion for
+** multi-threaded processes.  Only a single thread is allowed to
+** executed code that is surrounded by EnterMutex() and LeaveMutex().
+**
+** SQLite uses only a single Mutex.  There is not much critical
+** code and what little there is executes quickly and without blocking.
+*/
+void sqlite3OsEnterMutex(){
+#ifdef SQLITE_MACOS_MULTITASKING
+  static volatile int notInit = 1;
+  if( notInit ){
+    if( notInit == 2 ) /* as close as you can get to thread safe init */
+      MPYield();
+    else{
+      notInit = 2;
+      MPCreateCriticalRegion(&criticalRegion);
+      notInit = 0;
+    }
+  }
+  MPEnterCriticalRegion(criticalRegion, kDurationForever);
+#endif
+  assert( !inMutex );
+  inMutex = 1;
+}
+void sqlite3OsLeaveMutex(){
+  assert( inMutex );
+  inMutex = 0;
+#ifdef SQLITE_MACOS_MULTITASKING
+  MPExitCriticalRegion(criticalRegion);
+#endif
+}
+
+/*
+** Turn a relative pathname into a full pathname.  Return a pointer
+** to the full pathname stored in space obtained from sqliteMalloc().
+** The calling function is responsible for freeing this space once it
+** is no longer needed.
+*/
+char *sqlite3OsFullPathname(const char *zRelative){
+  char *zFull = 0;
+  if( zRelative[0]==':' ){
+    char zBuf[_MAX_PATH+1];
+    sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
+                    (char*)0);
+  }else{
+    if( strchr(zRelative, ':') ){
+      sqlite3SetString(&zFull, zRelative, (char*)0);
+    }else{
+    char zBuf[_MAX_PATH+1];
+      sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
+    }
+  }
+  return zFull;
+}
+
+/*
+** The following variable, if set to a non-zero value, becomes the result
+** returned from sqlite3OsCurrentTime().  This is used for testing.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_current_time = 0;
+#endif
+
+/*
+** Find the current time (in Universal Coordinated Time).  Write the
+** current time and date as a Julian Day number into *prNow and
+** return 0.  Return 1 if the time and date cannot be found.
+*/
+int sqlite3OsCurrentTime(double *prNow){
+  *prNow = 0.0;   /**** FIX ME *****/
+#ifdef SQLITE_TEST
+  if( sqlite3_current_time ){
+    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+  }
+#endif
+  return 0;
+}
+
+#endif /* OS_MAC */
diff --git a/src/os_mac.h b/src/os_mac.h
new file mode 100644 (file)
index 0000000..a5f5138
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This header file defines OS-specific features of classic Mac.
+** OS X uses the os_unix.h file, not this one.
+*/
+#ifndef _SQLITE_OS_MAC_H_
+#define _SQLITE_OS_MAC_H_
+
+
+#include <unistd.h>
+#include <Files.h>
+#ifdef _LARGE_FILE
+    typedef SInt64 off_t;
+#else
+    typedef SInt32 off_t;
+#endif
+#define SQLITE_TEMPNAME_SIZE _MAX_PATH
+#define SQLITE_MIN_SLEEP_MS 17
+
+/*
+** The OsFile structure is a operating-system independing representation
+** of an open file handle.  It is defined differently for each architecture.
+**
+** This is the definition for class Mac.
+*/
+typedef struct OsFile OsFile;
+struct OsFile {
+  SInt16 refNum;           /* Data fork/file reference number */
+  SInt16 refNumRF;         /* Resource fork reference number (for locking) */
+  int locked;              /* 0: unlocked, <0: write lock, >0: read lock */
+  int delOnClose;          /* True if file is to be deleted on close */
+  char *pathToDel;         /* Name of file to delete on close */
+};
+
+
+#endif /* _SQLITE_OS_MAC_H_ */
similarity index 50%
rename from src/os.c
rename to src/os_unix.c
index 157b4cff9b8ae9f581196947ae897ece461c85c4..e6c6f31595325240067efe398d6fe606c68f33d2 100644 (file)
--- a/src/os.c
@@ -1,5 +1,5 @@
 /*
-** 2001 September 16
+** 2004 May 22
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
 **
 ******************************************************************************
 **
-** This file contains code that is specific to particular operating
-** systems.  The purpose of this file is to provide a uniform abstraction
-** on which the rest of SQLite can operate.
+** This file contains code that is specific to Unix systems.
 */
 #include "os.h"          /* Must be first to enable large file support */
+#if OS_UNIX              /* This file is used on unix only */
 #include "sqliteInt.h"
 
-#if OS_UNIX
-# include <time.h>
-# include <errno.h>
-# include <unistd.h>
-# ifndef O_LARGEFILE
-#  define O_LARGEFILE 0
-# endif
-# ifdef SQLITE_DISABLE_LFS
-#  undef O_LARGEFILE
-#  define O_LARGEFILE 0
-# endif
-# ifndef O_NOFOLLOW
-#  define O_NOFOLLOW 0
-# endif
-# ifndef O_BINARY
-#  define O_BINARY 0
-# endif
-#endif
-
 
-#if OS_WIN
-# include <winbase.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#ifndef O_LARGEFILE
+# define O_LARGEFILE 0
 #endif
-
-#if OS_MAC
-# include <extras.h>
-# include <path2fss.h>
-# include <TextUtils.h>
-# include <FinderRegistry.h>
-# include <Folders.h>
-# include <Timer.h>
-# include <OSUtils.h>
+#ifdef SQLITE_DISABLE_LFS
+# undef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+#ifndef O_BINARY
+# define O_BINARY 0
 #endif
 
 /*
 ** Posix threads and SQLITE_W32_THREADS is defined if we are
 ** synchronizing using Win32 threads.
 */
-#if OS_UNIX && defined(THREADSAFE) && THREADSAFE
+#if defined(THREADSAFE) && THREADSAFE
 # include <pthread.h>
 # define SQLITE_UNIX_THREADS 1
 #endif
-#if OS_WIN && defined(THREADSAFE) && THREADSAFE
-# define SQLITE_W32_THREADS 1
-#endif
-#if OS_MAC && defined(THREADSAFE) && THREADSAFE
-# include <Multiprocessing.h>
-# define SQLITE_MACOS_MULTITASKING 1
-#endif
+
 
 /*
-** Macros for performance tracing.  Normally turned off
+** Include code that is common to all os_*.c files
 */
-#if 0
-static int last_page = 0;
-__inline__ unsigned long long int hwtime(void){
-  unsigned long long int x;
-  __asm__("rdtsc\n\t"
-          "mov %%edx, %%ecx\n\t"
-          :"=A" (x));
-  return x;
-}
-static unsigned long long int g_start;
-static unsigned int elapse;
-#define TIMER_START       g_start=hwtime()
-#define TIMER_END         elapse=hwtime()-g_start
-#define SEEK(X)           last_page=(X)
-#define TRACE1(X)         fprintf(stderr,X)
-#define TRACE2(X,Y)       fprintf(stderr,X,Y)
-#define TRACE3(X,Y,Z)     fprintf(stderr,X,Y,Z)
-#define TRACE4(X,Y,Z,A)   fprintf(stderr,X,Y,Z,A)
-#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
-#else
-#define TIMER_START
-#define TIMER_END
-#define SEEK(X)
-#define TRACE1(X)
-#define TRACE2(X,Y)
-#define TRACE3(X,Y,Z)
-#define TRACE4(X,Y,Z,A)
-#define TRACE5(X,Y,Z,A,B)
-#endif
+#include "os_common.h"
 
 
-#if OS_UNIX
 /*
 ** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
 ** section 6.5.2.2 lines 483 through 490 specify that when a process
@@ -354,49 +302,11 @@ int findLockInfo(
   return 0;
 }
 
-#endif  /** POSIX advisory lock work-around **/
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error.  This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-int sqlite3_io_error_pending = 0;
-#define SimulateIOError(A)  \
-   if( sqlite3_io_error_pending ) \
-     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
-static void local_ioerr(){
-  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
-}
-#else
-#define SimulateIOError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-int sqlite3_open_file_count = 0;
-#define OpenCounter(X)  sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-
 /*
 ** Delete the named file
 */
 int sqlite3OsDelete(const char *zFilename){
-#if OS_UNIX
   unlink(zFilename);
-#endif
-#if OS_WIN
-  DeleteFile(zFilename);
-#endif
-#if OS_MAC
-  unlink(zFilename);
-#endif
   return SQLITE_OK;
 }
 
@@ -404,43 +314,9 @@ int sqlite3OsDelete(const char *zFilename){
 ** Return TRUE if the named file exists.
 */
 int sqlite3OsFileExists(const char *zFilename){
-#if OS_UNIX
-  return access(zFilename, 0)==0;
-#endif
-#if OS_WIN
-  return GetFileAttributes(zFilename) != 0xffffffff;
-#endif
-#if OS_MAC
   return access(zFilename, 0)==0;
-#endif
 }
 
-
-#if 0 /* NOT USED */
-/*
-** Change the name of an existing file.
-*/
-int sqliteOsFileRename(const char *zOldName, const char *zNewName){
-#if OS_UNIX
-  if( link(zOldName, zNewName) ){
-    return SQLITE_ERROR;
-  }
-  unlink(zOldName);
-  return SQLITE_OK;
-#endif
-#if OS_WIN
-  if( !MoveFile(zOldName, zNewName) ){
-    return SQLITE_ERROR;
-  }
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  /**** FIX ME ***/
-  return SQLITE_ERROR;
-#endif
-}
-#endif /* NOT USED */
-
 /*
 ** Attempt to open a file for both reading and writing.  If that
 ** fails, try opening it read-only.  If the file does not exist,
@@ -459,7 +335,6 @@ int sqlite3OsOpenReadWrite(
   OsFile *id,
   int *pReadonly
 ){
-#if OS_UNIX
   int rc;
   id->dirfd = -1;
   id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
@@ -483,87 +358,6 @@ int sqlite3OsOpenReadWrite(
   TRACE3("OPEN    %-3d %s\n", id->fd, zFilename);
   OpenCounter(+1);
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  HANDLE h = CreateFile(zFilename,
-     GENERIC_READ | GENERIC_WRITE,
-     FILE_SHARE_READ | FILE_SHARE_WRITE,
-     NULL,
-     OPEN_ALWAYS,
-     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-     NULL
-  );
-  if( h==INVALID_HANDLE_VALUE ){
-    h = CreateFile(zFilename,
-       GENERIC_READ,
-       FILE_SHARE_READ,
-       NULL,
-       OPEN_ALWAYS,
-       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-       NULL
-    );
-    if( h==INVALID_HANDLE_VALUE ){
-      return SQLITE_CANTOPEN;
-    }
-    *pReadonly = 1;
-  }else{
-    *pReadonly = 0;
-  }
-  id->h = h;
-  id->locked = 0;
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  FSSpec fsSpec;
-# ifdef _LARGE_FILE
-  HFSUniStr255 dfName;
-  FSRef fsRef;
-  if( __path2fss(zFilename, &fsSpec) != noErr ){
-    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-      return SQLITE_CANTOPEN;
-  }
-  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-    return SQLITE_CANTOPEN;
-  FSGetDataForkName(&dfName);
-  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-                 fsRdWrShPerm, &(id->refNum)) != noErr ){
-    if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-                   fsRdWrPerm, &(id->refNum)) != noErr ){
-      if (FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-                   fsRdPerm, &(id->refNum)) != noErr )
-        return SQLITE_CANTOPEN;
-      else
-        *pReadonly = 1;
-    } else
-      *pReadonly = 0;
-  } else
-    *pReadonly = 0;
-# else
-  __path2fss(zFilename, &fsSpec);
-  if( !sqlite3OsFileExists(zFilename) ){
-    if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-      return SQLITE_CANTOPEN;
-  }
-  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
-    if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
-      if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
-        return SQLITE_CANTOPEN;
-      else
-        *pReadonly = 1;
-    } else
-      *pReadonly = 0;
-  } else
-    *pReadonly = 0;
-# endif
-  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
-    id->refNumRF = -1;
-  }
-  id->locked = 0;
-  id->delOnClose = 0;
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
 }
 
 
@@ -582,7 +376,6 @@ int sqlite3OsOpenReadWrite(
 ** On failure, return SQLITE_CANTOPEN.
 */
 int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
-#if OS_UNIX
   int rc;
   if( access(zFilename, 0)==0 ){
     return SQLITE_CANTOPEN;
@@ -608,61 +401,6 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
   TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
   OpenCounter(+1);
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  HANDLE h;
-  int fileflags;
-  if( delFlag ){
-    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
-                     | FILE_FLAG_DELETE_ON_CLOSE;
-  }else{
-    fileflags = FILE_FLAG_RANDOM_ACCESS;
-  }
-  h = CreateFile(zFilename,
-     GENERIC_READ | GENERIC_WRITE,
-     0,
-     NULL,
-     CREATE_ALWAYS,
-     fileflags,
-     NULL
-  );
-  if( h==INVALID_HANDLE_VALUE ){
-    return SQLITE_CANTOPEN;
-  }
-  id->h = h;
-  id->locked = 0;
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  FSSpec fsSpec;
-# ifdef _LARGE_FILE
-  HFSUniStr255 dfName;
-  FSRef fsRef;
-  __path2fss(zFilename, &fsSpec);
-  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-    return SQLITE_CANTOPEN;
-  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-    return SQLITE_CANTOPEN;
-  FSGetDataForkName(&dfName);
-  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-                 fsRdWrPerm, &(id->refNum)) != noErr )
-    return SQLITE_CANTOPEN;
-# else
-  __path2fss(zFilename, &fsSpec);
-  if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
-    return SQLITE_CANTOPEN;
-  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
-    return SQLITE_CANTOPEN;
-# endif
-  id->refNumRF = -1;
-  id->locked = 0;
-  id->delOnClose = delFlag;
-  if (delFlag)
-    id->pathToDel = sqlite3OsFullPathname(zFilename);
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
 }
 
 /*
@@ -673,7 +411,6 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
 ** On failure, return SQLITE_CANTOPEN.
 */
 int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
-#if OS_UNIX
   int rc;
   id->dirfd = -1;
   id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
@@ -691,50 +428,6 @@ int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
   TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
   OpenCounter(+1);
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  HANDLE h = CreateFile(zFilename,
-     GENERIC_READ,
-     0,
-     NULL,
-     OPEN_EXISTING,
-     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-     NULL
-  );
-  if( h==INVALID_HANDLE_VALUE ){
-    return SQLITE_CANTOPEN;
-  }
-  id->h = h;
-  id->locked = 0;
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  FSSpec fsSpec;
-# ifdef _LARGE_FILE
-  HFSUniStr255 dfName;
-  FSRef fsRef;
-  if( __path2fss(zFilename, &fsSpec) != noErr )
-    return SQLITE_CANTOPEN;
-  if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
-    return SQLITE_CANTOPEN;
-  FSGetDataForkName(&dfName);
-  if( FSOpenFork(&fsRef, dfName.length, dfName.unicode,
-                 fsRdPerm, &(id->refNum)) != noErr )
-    return SQLITE_CANTOPEN;
-# else
-  __path2fss(zFilename, &fsSpec);
-  if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
-    return SQLITE_CANTOPEN;
-# endif
-  if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
-    id->refNumRF = -1;
-  }
-  id->locked = 0;
-  id->delOnClose = 0;
-  OpenCounter(+1);
-  return SQLITE_OK;
-#endif
 }
 
 /*
@@ -757,7 +450,6 @@ int sqlite3OsOpenDirectory(
   const char *zDirname,
   OsFile *id
 ){
-#if OS_UNIX
   if( id->fd<0 ){
     /* Do not open the directory if the corresponding file is not already
     ** open. */
@@ -769,7 +461,6 @@ int sqlite3OsOpenDirectory(
     return SQLITE_CANTOPEN; 
   }
   TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
-#endif
   return SQLITE_OK;
 }
 
@@ -778,7 +469,6 @@ int sqlite3OsOpenDirectory(
 ** hold at least SQLITE_TEMPNAME_SIZE characters.
 */
 int sqlite3OsTempFileName(char *zBuf){
-#if OS_UNIX
   static const char *azDirs[] = {
      "/var/tmp",
      "/usr/tmp",
@@ -808,71 +498,6 @@ int sqlite3OsTempFileName(char *zBuf){
     }
     zBuf[j] = 0;
   }while( access(zBuf,0)==0 );
-#endif
-#if OS_WIN
-  static char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  char zTempPath[SQLITE_TEMPNAME_SIZE];
-  GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
-  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
-  zTempPath[i] = 0;
-  for(;;){
-    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
-    j = strlen(zBuf);
-    sqlite3Randomness(15, &zBuf[j]);
-    for(i=0; i<15; i++, j++){
-      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-    }
-    zBuf[j] = 0;
-    if( !sqlite3OsFileExists(zBuf) ) break;
-  }
-#endif
-#if OS_MAC
-  static char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  char zTempPath[SQLITE_TEMPNAME_SIZE];
-  char zdirName[32];
-  CInfoPBRec infoRec;
-  Str31 dirName;
-  memset(&infoRec, 0, sizeof(infoRec));
-  memset(zTempPath, 0, SQLITE_TEMPNAME_SIZE);
-  if( FindFolder(kOnSystemDisk, kTemporaryFolderType,  kCreateFolder,
-       &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
-    infoRec.dirInfo.ioNamePtr = dirName;
-    do{
-      infoRec.dirInfo.ioFDirIndex = -1;
-      infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
-      if( PBGetCatInfoSync(&infoRec) == noErr ){
-        CopyPascalStringToC(dirName, zdirName);
-        i = strlen(zdirName);
-        memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
-        strcpy(zTempPath, zdirName);
-        zTempPath[i] = ':';
-      }else{
-        *zTempPath = 0;
-        break;
-      }
-    } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
-  }
-  if( *zTempPath == 0 )
-    getcwd(zTempPath, SQLITE_TEMPNAME_SIZE-24);
-  for(;;){
-    sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
-    j = strlen(zBuf);
-    sqlite3Randomness(15, &zBuf[j]);
-    for(i=0; i<15; i++, j++){
-      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-    }
-    zBuf[j] = 0;
-    if( !sqlite3OsFileExists(zBuf) ) break;
-  }
-#endif
   return SQLITE_OK; 
 }
 
@@ -880,7 +505,6 @@ int sqlite3OsTempFileName(char *zBuf){
 ** Close a file.
 */
 int sqlite3OsClose(OsFile *id){
-#if OS_UNIX
   sqlite3OsUnlock(id);
   if( id->dirfd>=0 ) close(id->dirfd);
   id->dirfd = -1;
@@ -911,27 +535,6 @@ int sqlite3OsClose(OsFile *id){
   TRACE2("CLOSE   %-3d\n", id->fd);
   OpenCounter(-1);
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  CloseHandle(id->h);
-  OpenCounter(-1);
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  if( id->refNumRF!=-1 )
-    FSClose(id->refNumRF);
-# ifdef _LARGE_FILE
-  FSCloseFork(id->refNum);
-# else
-  FSClose(id->refNum);
-# endif
-  if( id->delOnClose ){
-    unlink(id->pathToDel);
-    sqliteFree(id->pathToDel);
-  }
-  OpenCounter(-1);
-  return SQLITE_OK;
-#endif
 }
 
 /*
@@ -940,7 +543,6 @@ int sqlite3OsClose(OsFile *id){
 ** wrong.
 */
 int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
-#if OS_UNIX
   int got;
   SimulateIOError(SQLITE_IOERR);
   TIMER_START;
@@ -954,36 +556,6 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
   }else{
     return SQLITE_IOERR;
   }
-#endif
-#if OS_WIN
-  DWORD got;
-  SimulateIOError(SQLITE_IOERR);
-  TRACE2("READ %d\n", last_page);
-  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
-    got = 0;
-  }
-  if( got==(DWORD)amt ){
-    return SQLITE_OK;
-  }else{
-    return SQLITE_IOERR;
-  }
-#endif
-#if OS_MAC
-  int got;
-  SimulateIOError(SQLITE_IOERR);
-  TRACE2("READ %d\n", last_page);
-# ifdef _LARGE_FILE
-  FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
-# else
-  got = amt;
-  FSRead(id->refNum, &got, pBuf);
-# endif
-  if( got==amt ){
-    return SQLITE_OK;
-  }else{
-    return SQLITE_IOERR;
-  }
-#endif
 }
 
 /*
@@ -991,7 +563,6 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
 ** or some other error code on failure.
 */
 int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
-#if OS_UNIX
   int wrote = 0;
   SimulateIOError(SQLITE_IOERR);
   TIMER_START;
@@ -1006,44 +577,6 @@ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
     return SQLITE_FULL;
   }
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  int rc;
-  DWORD wrote;
-  SimulateIOError(SQLITE_IOERR);
-  TRACE2("WRITE %d\n", last_page);
-  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
-    amt -= wrote;
-    pBuf = &((char*)pBuf)[wrote];
-  }
-  if( !rc || amt>(int)wrote ){
-    return SQLITE_FULL;
-  }
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  OSErr oserr;
-  int wrote = 0;
-  SimulateIOError(SQLITE_IOERR);
-  TRACE2("WRITE %d\n", last_page);
-  while( amt>0 ){
-# ifdef _LARGE_FILE
-    oserr = FSWriteFork(id->refNum, fsAtMark, 0,
-                        (ByteCount)amt, pBuf, (ByteCount*)&wrote);
-# else
-    wrote = amt;
-    oserr = FSWrite(id->refNum, &wrote, pBuf);
-# endif
-    if( wrote == 0 || oserr != noErr)
-      break;
-    amt -= wrote;
-    pBuf = &((char*)pBuf)[wrote];
-  }
-  if( oserr != noErr || amt>wrote ){
-    return SQLITE_FULL;
-  }
-  return SQLITE_OK;
-#endif
 }
 
 /*
@@ -1051,42 +584,8 @@ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
 */
 int sqlite3OsSeek(OsFile *id, off_t offset){
   SEEK(offset/1024 + 1);
-#if OS_UNIX
   lseek(id->fd, offset, SEEK_SET);
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  {
-    LONG upperBits = offset>>32;
-    LONG lowerBits = offset & 0xffffffff;
-    DWORD rc;
-    rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
-    /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
-  }
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-  {
-    off_t curSize;
-    if( sqlite3OsFileSize(id, &curSize) != SQLITE_OK ){
-      return SQLITE_IOERR;
-    }
-    if( offset >= curSize ){
-      if( sqlite3OsTruncate(id, offset+1) != SQLITE_OK ){
-        return SQLITE_IOERR;
-      }
-    }
-# ifdef _LARGE_FILE
-    if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
-# else
-    if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
-# endif
-      return SQLITE_IOERR;
-    }else{
-      return SQLITE_OK;
-    }
-  }
-#endif
 }
 
 /*
@@ -1101,7 +600,6 @@ int sqlite3OsSeek(OsFile *id, off_t offset){
 ** will not roll back - possibly leading to database corruption.
 */
 int sqlite3OsSync(OsFile *id){
-#if OS_UNIX
   SimulateIOError(SQLITE_IOERR);
   TRACE2("SYNC    %-3d\n", id->fd);
   if( fsync(id->fd) ){
@@ -1115,28 +613,6 @@ int sqlite3OsSync(OsFile *id){
     }
     return SQLITE_OK;
   }
-#endif
-#if OS_WIN
-  if( FlushFileBuffers(id->h) ){
-    return SQLITE_OK;
-  }else{
-    return SQLITE_IOERR;
-  }
-#endif
-#if OS_MAC
-# ifdef _LARGE_FILE
-  if( FSFlushFork(id->refNum) != noErr ){
-# else
-  ParamBlockRec params;
-  memset(&params, 0, sizeof(ParamBlockRec));
-  params.ioParam.ioRefNum = id->refNum;
-  if( PBFlushFileSync(&params) != noErr ){
-# endif
-    return SQLITE_IOERR;
-  }else{
-    return SQLITE_OK;
-  }
-#endif
 }
 
 /*
@@ -1144,35 +620,13 @@ int sqlite3OsSync(OsFile *id){
 */
 int sqlite3OsTruncate(OsFile *id, off_t nByte){
   SimulateIOError(SQLITE_IOERR);
-#if OS_UNIX
   return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
-#endif
-#if OS_WIN
-  {
-    LONG upperBits = nByte>>32;
-    SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
-    SetEndOfFile(id->h);
-  }
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-# ifdef _LARGE_FILE
-  if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
-# else
-  if( SetEOF(id->refNum, nByte) != noErr ){
-# endif
-    return SQLITE_IOERR;
-  }else{
-    return SQLITE_OK;
-  }
-#endif
 }
 
 /*
 ** Determine the current size of a file in bytes
 */
 int sqlite3OsFileSize(OsFile *id, off_t *pSize){
-#if OS_UNIX
   struct stat buf;
   SimulateIOError(SQLITE_IOERR);
   if( fstat(id->fd, &buf)!=0 ){
@@ -1180,102 +634,8 @@ int sqlite3OsFileSize(OsFile *id, off_t *pSize){
   }
   *pSize = buf.st_size;
   return SQLITE_OK;
-#endif
-#if OS_WIN
-  DWORD upperBits, lowerBits;
-  SimulateIOError(SQLITE_IOERR);
-  lowerBits = GetFileSize(id->h, &upperBits);
-  *pSize = (((off_t)upperBits)<<32) + lowerBits;
-  return SQLITE_OK;
-#endif
-#if OS_MAC
-# ifdef _LARGE_FILE
-  if( FSGetForkSize(id->refNum, pSize) != noErr){
-# else
-  if( GetEOF(id->refNum, pSize) != noErr ){
-# endif
-    return SQLITE_IOERR;
-  }else{
-    return SQLITE_OK;
-  }
-#endif
 }
 
-#if OS_WIN
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
-** Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation:  Win95, Win98, and WinME lack
-** the LockFileEx() API.  But we can still statically link against that
-** API as long as we don't call it win running Win95/98/ME.  A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-*/
-int isNT(void){
-  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
-  if( osType==0 ){
-    OSVERSIONINFO sInfo;
-    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-    GetVersionEx(&sInfo);
-    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
-  }
-  return osType==2;
-}
-#endif
-
-/*
-** Windows file locking notes:  [similar issues apply to MacOS]
-**
-** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
-** those functions are not available.  So we use only LockFile() and
-** UnlockFile().
-**
-** LockFile() prevents not just writing but also reading by other processes.
-** (This is a design error on the part of Windows, but there is nothing
-** we can do about that.)  So the region used for locking is at the
-** end of the file where it is unlikely to ever interfere with an
-** actual read attempt.
-**
-** A database read lock is obtained by locking a single randomly-chosen 
-** byte out of a specific range of bytes. The lock byte is obtained at 
-** random so two separate readers can probably access the file at the 
-** same time, unless they are unlucky and choose the same lock byte.
-** A database write lock is obtained by locking all bytes in the range.
-** There can only be one writer.
-**
-** A lock is obtained on the first byte of the lock range before acquiring
-** either a read lock or a write lock.  This prevents two processes from
-** attempting to get a lock at a same time.  The semantics of 
-** sqlite3OsReadLock() require that if there is already a write lock, that
-** lock is converted into a read lock atomically.  The lock on the first
-** byte allows us to drop the old write lock and get the read lock without
-** another process jumping into the middle and messing us up.  The same
-** argument applies to sqlite3OsWriteLock().
-**
-** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
-** which means we can use reader/writer locks.  When reader writer locks
-** are used, the lock is placed on the same range of bytes that is used
-** for probabilistic locking in Win95/98/ME.  Hence, the locking scheme
-** will support two or more Win95 readers or two or more WinNT readers.
-** But a single Win95 reader will lock out all WinNT readers and a single
-** WinNT reader will lock out all other Win95 readers.
-**
-** Note: On MacOS we use the resource fork for locking.
-**
-** The following #defines specify the range of bytes used for locking.
-** N_LOCKBYTE is the number of bytes available for doing the locking.
-** The first byte used to hold the lock while the lock is changing does
-** not count toward this number.  FIRST_LOCKBYTE is the address of
-** the first byte in the range of bytes used for locking.
-*/
-#define N_LOCKBYTE       10239
-#if OS_MAC
-# define FIRST_LOCKBYTE   (0x000fffff - N_LOCKBYTE)
-#else
-# define FIRST_LOCKBYTE   (0xffffffff - N_LOCKBYTE)
-#endif
 
 /*
 ** Change the status of the lock on the file "id" to be a readlock.
@@ -1287,7 +647,6 @@ int isNT(void){
 ** available on the host, then an SQLITE_NOLFS is returned.
 */
 int sqlite3OsReadLock(OsFile *id){
-#if OS_UNIX
   int rc;
   sqlite3OsEnterMutex();
   if( id->pLock->cnt>0 ){
@@ -1319,83 +678,6 @@ int sqlite3OsReadLock(OsFile *id){
   }
   sqlite3OsLeaveMutex();
   return rc;
-#endif
-#if OS_WIN
-  int rc;
-  if( id->locked>0 ){
-    rc = SQLITE_OK;
-  }else{
-    int lk;
-    int res;
-    int cnt = 100;
-    sqlite3Randomness(sizeof(lk), &lk);
-    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
-    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
-      Sleep(1);
-    }
-    if( res ){
-      UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-      if( isNT() ){
-        OVERLAPPED ovlp;
-        ovlp.Offset = FIRST_LOCKBYTE+1;
-        ovlp.OffsetHigh = 0;
-        ovlp.hEvent = 0;
-        res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 
-                          0, N_LOCKBYTE, 0, &ovlp);
-      }else{
-        res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
-      }
-      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
-    }
-    if( res ){
-      id->locked = lk;
-      rc = SQLITE_OK;
-    }else{
-      rc = SQLITE_BUSY;
-    }
-  }
-  return rc;
-#endif
-#if OS_MAC
-  int rc;
-  if( id->locked>0 || id->refNumRF == -1 ){
-    rc = SQLITE_OK;
-  }else{
-    int lk;
-    OSErr res;
-    int cnt = 5;
-    ParamBlockRec params;
-    sqlite3Randomness(sizeof(lk), &lk);
-    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
-    memset(&params, 0, sizeof(params));
-    params.ioParam.ioRefNum = id->refNumRF;
-    params.ioParam.ioPosMode = fsFromStart;
-    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-    params.ioParam.ioReqCount = 1;
-    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
-      UInt32 finalTicks;
-      Delay(1, &finalTicks); /* 1/60 sec */
-    }
-    if( res == noErr ){
-      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-      params.ioParam.ioReqCount = N_LOCKBYTE;
-      PBUnlockRangeSync(&params);
-      params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
-      params.ioParam.ioReqCount = 1;
-      res = PBLockRangeSync(&params);
-      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-      params.ioParam.ioReqCount = 1;
-      PBUnlockRangeSync(&params);
-    }
-    if( res == noErr ){
-      id->locked = lk;
-      rc = SQLITE_OK;
-    }else{
-      rc = SQLITE_BUSY;
-    }
-  }
-  return rc;
-#endif
 }
 
 /*
@@ -1405,7 +687,6 @@ int sqlite3OsReadLock(OsFile *id){
 ** available on the host, then an SQLITE_NOLFS is returned.
 */
 int sqlite3OsWriteLock(OsFile *id){
-#if OS_UNIX
   int rc;
   sqlite3OsEnterMutex();
   if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
@@ -1430,82 +711,6 @@ int sqlite3OsWriteLock(OsFile *id){
   }
   sqlite3OsLeaveMutex();
   return rc;
-#endif
-#if OS_WIN
-  int rc;
-  if( id->locked<0 ){
-    rc = SQLITE_OK;
-  }else{
-    int res;
-    int cnt = 100;
-    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
-      Sleep(1);
-    }
-    if( res ){
-      if( id->locked>0 ){
-        if( isNT() ){
-          UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-        }else{
-          res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
-        }
-      }
-      if( res ){
-        res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-      }else{
-        res = 0;
-      }
-      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
-    }
-    if( res ){
-      id->locked = -1;
-      rc = SQLITE_OK;
-    }else{
-      rc = SQLITE_BUSY;
-    }
-  }
-  return rc;
-#endif
-#if OS_MAC
-  int rc;
-  if( id->locked<0 || id->refNumRF == -1 ){
-    rc = SQLITE_OK;
-  }else{
-    OSErr res;
-    int cnt = 5;
-    ParamBlockRec params;
-    memset(&params, 0, sizeof(params));
-    params.ioParam.ioRefNum = id->refNumRF;
-    params.ioParam.ioPosMode = fsFromStart;
-    params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-    params.ioParam.ioReqCount = 1;
-    while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
-      UInt32 finalTicks;
-      Delay(1, &finalTicks); /* 1/60 sec */
-    }
-    if( res == noErr ){
-      params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
-      params.ioParam.ioReqCount = 1;
-      if( id->locked==0 
-            || PBUnlockRangeSync(&params)==noErr ){
-        params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-        params.ioParam.ioReqCount = N_LOCKBYTE;
-        res = PBLockRangeSync(&params);
-      }else{
-        res = afpRangeNotLocked;
-      }
-      params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
-      params.ioParam.ioReqCount = 1;
-      PBUnlockRangeSync(&params);
-    }
-    if( res == noErr ){
-      id->locked = -1;
-      rc = SQLITE_OK;
-    }else{
-      rc = SQLITE_BUSY;
-    }
-  }
-  return rc;
-#endif
 }
 
 /*
@@ -1515,7 +720,6 @@ int sqlite3OsWriteLock(OsFile *id){
 ** available on the host, then an SQLITE_NOLFS is returned.
 */
 int sqlite3OsUnlock(OsFile *id){
-#if OS_UNIX
   int rc;
   if( !id->locked ) return SQLITE_OK;
   sqlite3OsEnterMutex();
@@ -1558,45 +762,6 @@ int sqlite3OsUnlock(OsFile *id){
   sqlite3OsLeaveMutex();
   id->locked = 0;
   return rc;
-#endif
-#if OS_WIN
-  int rc;
-  if( id->locked==0 ){
-    rc = SQLITE_OK;
-  }else if( isNT() || id->locked<0 ){
-    UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
-    rc = SQLITE_OK;
-    id->locked = 0;
-  }else{
-    UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
-    rc = SQLITE_OK;
-    id->locked = 0;
-  }
-  return rc;
-#endif
-#if OS_MAC
-  int rc;
-  ParamBlockRec params;
-  memset(&params, 0, sizeof(params));
-  params.ioParam.ioRefNum = id->refNumRF;
-  params.ioParam.ioPosMode = fsFromStart;
-  if( id->locked==0 || id->refNumRF == -1 ){
-    rc = SQLITE_OK;
-  }else if( id->locked<0 ){
-    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
-    params.ioParam.ioReqCount = N_LOCKBYTE;
-    PBUnlockRangeSync(&params);
-    rc = SQLITE_OK;
-    id->locked = 0;
-  }else{
-    params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
-    params.ioParam.ioReqCount = 1;
-    PBUnlockRangeSync(&params);
-    rc = SQLITE_OK;
-    id->locked = 0;
-  }
-  return rc;
-#endif
 }
 
 /*
@@ -1618,24 +783,13 @@ int sqlite3OsRandomSeed(char *zBuf){
   ** tests repeatable.
   */
   memset(zBuf, 0, 256);
-#if OS_UNIX && !defined(SQLITE_TEST)
+#if !defined(SQLITE_TEST)
   {
     int pid;
     time((time_t*)zBuf);
     pid = getpid();
     memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
   }
-#endif
-#if OS_WIN && !defined(SQLITE_TEST)
-  GetSystemTime((LPSYSTEMTIME)zBuf);
-#endif
-#if OS_MAC
-  {
-    int pid;
-    Microseconds((UnsignedWide*)zBuf);
-    pid = getpid();
-    memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
-  }
 #endif
   return SQLITE_OK;
 }
@@ -1644,7 +798,6 @@ int sqlite3OsRandomSeed(char *zBuf){
 ** Sleep for a little while.  Return the amount of time slept.
 */
 int sqlite3OsSleep(int ms){
-#if OS_UNIX
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
   usleep(ms*1000);
   return ms;
@@ -1652,32 +805,13 @@ int sqlite3OsSleep(int ms){
   sleep((ms+999)/1000);
   return 1000*((ms+999)/1000);
 #endif
-#endif
-#if OS_WIN
-  Sleep(ms);
-  return ms;
-#endif
-#if OS_MAC
-  UInt32 finalTicks;
-  UInt32 ticks = (((UInt32)ms+16)*3)/50;  /* 1/60 sec per tick */
-  Delay(ticks, &finalTicks);
-  return (int)((ticks*50)/3);
-#endif
 }
 
 /*
 ** Static variables used for thread synchronization
 */
 static int inMutex = 0;
-#ifdef SQLITE_UNIX_THREADS
-  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-#ifdef SQLITE_W32_THREADS
-  static CRITICAL_SECTION cs;
-#endif
-#ifdef SQLITE_MACOS_MULTITASKING
-  static MPCriticalRegionID criticalRegion;
-#endif
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*
 ** The following pair of routine implement mutual exclusion for
@@ -1690,32 +824,6 @@ static int inMutex = 0;
 void sqlite3OsEnterMutex(){
 #ifdef SQLITE_UNIX_THREADS
   pthread_mutex_lock(&mutex);
-#endif
-#ifdef SQLITE_W32_THREADS
-  static int isInit = 0;
-  while( !isInit ){
-    static long lock = 0;
-    if( InterlockedIncrement(&lock)==1 ){
-      InitializeCriticalSection(&cs);
-      isInit = 1;
-    }else{
-      Sleep(1);
-    }
-  }
-  EnterCriticalSection(&cs);
-#endif
-#ifdef SQLITE_MACOS_MULTITASKING
-  static volatile int notInit = 1;
-  if( notInit ){
-    if( notInit == 2 ) /* as close as you can get to thread safe init */
-      MPYield();
-    else{
-      notInit = 2;
-      MPCreateCriticalRegion(&criticalRegion);
-      notInit = 0;
-    }
-  }
-  MPEnterCriticalRegion(criticalRegion, kDurationForever);
 #endif
   assert( !inMutex );
   inMutex = 1;
@@ -1726,12 +834,6 @@ void sqlite3OsLeaveMutex(){
 #ifdef SQLITE_UNIX_THREADS
   pthread_mutex_unlock(&mutex);
 #endif
-#ifdef SQLITE_W32_THREADS
-  LeaveCriticalSection(&cs);
-#endif
-#ifdef SQLITE_MACOS_MULTITASKING
-  MPExitCriticalRegion(criticalRegion);
-#endif
 }
 
 /*
@@ -1741,7 +843,6 @@ void sqlite3OsLeaveMutex(){
 ** is no longer needed.
 */
 char *sqlite3OsFullPathname(const char *zRelative){
-#if OS_UNIX
   char *zFull = 0;
   if( zRelative[0]=='/' ){
     sqlite3SetString(&zFull, zRelative, (char*)0);
@@ -1751,33 +852,6 @@ char *sqlite3OsFullPathname(const char *zRelative){
                     (char*)0);
   }
   return zFull;
-#endif
-#if OS_WIN
-  char *zNotUsed;
-  char *zFull;
-  int nByte;
-  nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
-  zFull = sqliteMalloc( nByte );
-  if( zFull==0 ) return 0;
-  GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
-  return zFull;
-#endif
-#if OS_MAC
-  char *zFull = 0;
-  if( zRelative[0]==':' ){
-    char zBuf[_MAX_PATH+1];
-    sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
-                    (char*)0);
-  }else{
-    if( strchr(zRelative, ':') ){
-      sqlite3SetString(&zFull, zRelative, (char*)0);
-    }else{
-    char zBuf[_MAX_PATH+1];
-      sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
-    }
-  }
-  return zFull;
-#endif
 }
 
 /*
@@ -1794,21 +868,9 @@ int sqlite3_current_time = 0;
 ** return 0.  Return 1 if the time and date cannot be found.
 */
 int sqlite3OsCurrentTime(double *prNow){
-#if OS_UNIX
   time_t t;
   time(&t);
   *prNow = t/86400.0 + 2440587.5;
-#endif
-#if OS_WIN
-  FILETIME ft;
-  /* FILETIME structure is a 64-bit value representing the number of 
-     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
-  */
-  double now;
-  GetSystemTimeAsFileTime( &ft );
-  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
-  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
-#endif
 #ifdef SQLITE_TEST
   if( sqlite3_current_time ){
     *prNow = sqlite3_current_time/86400.0 + 2440587.5;
@@ -1817,5 +879,4 @@ int sqlite3OsCurrentTime(double *prNow){
   return 0;
 }
 
-
-
+#endif /* OS_UNIX */
diff --git a/src/os_unix.h b/src/os_unix.h
new file mode 100644 (file)
index 0000000..9dab737
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This header file defined OS-specific features for Unix.
+*/
+#ifndef _SQLITE_OS_UNIX_H_
+#define _SQLITE_OS_UNIX_H_
+
+/*
+** Helpful hint:  To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
+** to the compiler command line.
+*/
+
+/*
+** These #defines should enable >2GB file support on Posix if the
+** underlying operating system supports it.  If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line.  This is necessary if you are compiling
+** on a recent machine (ex: RedHat 7.2) but you want your code to work
+** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
+** without this option, LFS is enable.  But LFS does not exist in the kernel
+** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE       1
+# ifndef _FILE_OFFSET_BITS
+#   define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
+** standard include files.
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/*
+** The OsFile structure is a operating-system independing representation
+** of an open file handle.  It is defined differently for each architecture.
+**
+** This is the definition for Unix.
+*/
+typedef struct OsFile OsFile;
+struct OsFile {
+  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
+  struct lockInfo *pLock;   /* Info about locks on this inode */
+  int fd;                   /* The file descriptor */
+  int locked;               /* True if this instance holds the lock */
+  int dirfd;                /* File descriptor for the directory */
+};
+
+/*
+** Maximum number of characters in a temporary file name
+*/
+#define SQLITE_TEMPNAME_SIZE 200
+
+/*
+** Minimum interval supported by sqlite3OsSleep().
+*/
+#if defined(HAVE_USLEEP) && HAVE_USLEEP
+# define SQLITE_MIN_SLEEP_MS 1
+#else
+# define SQLITE_MIN_SLEEP_MS 1000
+#endif
+
+
+#endif /* _SQLITE_OS_UNIX_H_ */
diff --git a/src/os_win.c b/src/os_win.c
new file mode 100644 (file)
index 0000000..9c21f7c
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains code that is specific to windows.
+*/
+#include "os.h"          /* Must be first to enable large file support */
+#if OS_WIN               /* This file is used for windows only */
+#include "sqliteInt.h"
+
+#include <winbase.h>
+
+/*
+** Macros used to determine whether or not to use threads.
+*/
+#if defined(THREADSAFE) && THREADSAFE
+# define SQLITE_W32_THREADS 1
+#endif
+
+/*
+** Include code that is common to all os_*.c files
+*/
+#include "os_common.h"
+
+/*
+** Delete the named file
+*/
+int sqlite3OsDelete(const char *zFilename){
+  DeleteFile(zFilename);
+  return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqlite3OsFileExists(const char *zFilename){
+  return GetFileAttributes(zFilename) != 0xffffffff;
+}
+
+/*
+** Attempt to open a file for both reading and writing.  If that
+** fails, try opening it read-only.  If the file does not exist,
+** try to create it.
+**
+** On success, a handle for the open file is written to *id
+** and *pReadonly is set to 0 if the file was opened for reading and
+** writing or 1 if the file was opened read-only.  The function returns
+** SQLITE_OK.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id and *pReadonly unchanged.
+*/
+int sqlite3OsOpenReadWrite(
+  const char *zFilename,
+  OsFile *id,
+  int *pReadonly
+){
+  HANDLE h = CreateFile(zFilename,
+     GENERIC_READ | GENERIC_WRITE,
+     FILE_SHARE_READ | FILE_SHARE_WRITE,
+     NULL,
+     OPEN_ALWAYS,
+     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+     NULL
+  );
+  if( h==INVALID_HANDLE_VALUE ){
+    h = CreateFile(zFilename,
+       GENERIC_READ,
+       FILE_SHARE_READ,
+       NULL,
+       OPEN_ALWAYS,
+       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+       NULL
+    );
+    if( h==INVALID_HANDLE_VALUE ){
+      return SQLITE_CANTOPEN;
+    }
+    *pReadonly = 1;
+  }else{
+    *pReadonly = 0;
+  }
+  id->h = h;
+  id->locked = 0;
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+
+/*
+** Attempt to open a new file for exclusive access by this process.
+** The file will be opened for both reading and writing.  To avoid
+** a potential security problem, we do not allow the file to have
+** previously existed.  Nor do we allow the file to be a symbolic
+** link.
+**
+** If delFlag is true, then make arrangements to automatically delete
+** the file when it is closed.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+  HANDLE h;
+  int fileflags;
+  if( delFlag ){
+    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 
+                     | FILE_FLAG_DELETE_ON_CLOSE;
+  }else{
+    fileflags = FILE_FLAG_RANDOM_ACCESS;
+  }
+  h = CreateFile(zFilename,
+     GENERIC_READ | GENERIC_WRITE,
+     0,
+     NULL,
+     CREATE_ALWAYS,
+     fileflags,
+     NULL
+  );
+  if( h==INVALID_HANDLE_VALUE ){
+    return SQLITE_CANTOPEN;
+  }
+  id->h = h;
+  id->locked = 0;
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+/*
+** Attempt to open a new file for read-only access.
+**
+** On success, write the file handle into *id and return SQLITE_OK.
+**
+** On failure, return SQLITE_CANTOPEN.
+*/
+int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
+  HANDLE h = CreateFile(zFilename,
+     GENERIC_READ,
+     0,
+     NULL,
+     OPEN_EXISTING,
+     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+     NULL
+  );
+  if( h==INVALID_HANDLE_VALUE ){
+    return SQLITE_CANTOPEN;
+  }
+  id->h = h;
+  id->locked = 0;
+  OpenCounter(+1);
+  return SQLITE_OK;
+}
+
+/*
+** Attempt to open a file descriptor for the directory that contains a
+** file.  This file descriptor can be used to fsync() the directory
+** in order to make sure the creation of a new file is actually written
+** to disk.
+**
+** This routine is only meaningful for Unix.  It is a no-op under
+** windows since windows does not support hard links.
+**
+** On success, a handle for a previously open file is at *id is
+** updated with the new directory file descriptor and SQLITE_OK is
+** returned.
+**
+** On failure, the function returns SQLITE_CANTOPEN and leaves
+** *id unchanged.
+*/
+int sqlite3OsOpenDirectory(
+  const char *zDirname,
+  OsFile *id
+){
+  return SQLITE_OK;
+}
+
+/*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at least SQLITE_TEMPNAME_SIZE characters.
+*/
+int sqlite3OsTempFileName(char *zBuf){
+  static char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  char zTempPath[SQLITE_TEMPNAME_SIZE];
+  GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+  zTempPath[i] = 0;
+  for(;;){
+    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
+    j = strlen(zBuf);
+    sqlite3Randomness(15, &zBuf[j]);
+    for(i=0; i<15; i++, j++){
+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+    }
+    zBuf[j] = 0;
+    if( !sqlite3OsFileExists(zBuf) ) break;
+  }
+  return SQLITE_OK; 
+}
+
+/*
+** Close a file.
+*/
+int sqlite3OsClose(OsFile *id){
+  CloseHandle(id->h);
+  OpenCounter(-1);
+  return SQLITE_OK;
+}
+
+/*
+** Read data from a file into a buffer.  Return SQLITE_OK if all
+** bytes were read successfully and SQLITE_IOERR if anything goes
+** wrong.
+*/
+int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+  DWORD got;
+  SimulateIOError(SQLITE_IOERR);
+  TRACE2("READ %d\n", last_page);
+  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
+    got = 0;
+  }
+  if( got==(DWORD)amt ){
+    return SQLITE_OK;
+  }else{
+    return SQLITE_IOERR;
+  }
+}
+
+/*
+** Write data from a buffer into a file.  Return SQLITE_OK on success
+** or some other error code on failure.
+*/
+int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+  int rc;
+  DWORD wrote;
+  SimulateIOError(SQLITE_IOERR);
+  TRACE2("WRITE %d\n", last_page);
+  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
+    amt -= wrote;
+    pBuf = &((char*)pBuf)[wrote];
+  }
+  if( !rc || amt>(int)wrote ){
+    return SQLITE_FULL;
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Move the read/write pointer in a file.
+*/
+int sqlite3OsSeek(OsFile *id, off_t offset){
+  LONG upperBits = offset>>32;
+  LONG lowerBits = offset & 0xffffffff;
+  DWORD rc;
+  SEEK(offset/1024 + 1);
+  rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
+  /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
+  return SQLITE_OK;
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+*/
+int sqlite3OsSync(OsFile *id){
+  if( FlushFileBuffers(id->h) ){
+    return SQLITE_OK;
+  }else{
+    return SQLITE_IOERR;
+  }
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+int sqlite3OsTruncate(OsFile *id, off_t nByte){
+  LONG upperBits = nByte>>32;
+  SimulateIOError(SQLITE_IOERR);
+  SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
+  SetEndOfFile(id->h);
+  return SQLITE_OK;
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+int sqlite3OsFileSize(OsFile *id, off_t *pSize){
+  DWORD upperBits, lowerBits;
+  SimulateIOError(SQLITE_IOERR);
+  lowerBits = GetFileSize(id->h, &upperBits);
+  *pSize = (((off_t)upperBits)<<32) + lowerBits;
+  return SQLITE_OK;
+}
+
+/*
+** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
+** Return false (zero) for Win95, Win98, or WinME.
+**
+** Here is an interesting observation:  Win95, Win98, and WinME lack
+** the LockFileEx() API.  But we can still statically link against that
+** API as long as we don't call it win running Win95/98/ME.  A call to
+** this routine is used to determine if the host is Win95/98/ME or
+** WinNT/2K/XP so that we will know whether or not we can safely call
+** the LockFileEx() API.
+*/
+int isNT(void){
+  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
+  if( osType==0 ){
+    OSVERSIONINFO sInfo;
+    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+    GetVersionEx(&sInfo);
+    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+  }
+  return osType==2;
+}
+
+/*
+** Windows file locking notes:
+**
+** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
+** those functions are not available.  So we use only LockFile() and
+** UnlockFile().
+**
+** LockFile() prevents not just writing but also reading by other processes.
+** (This is a design error on the part of Windows, but there is nothing
+** we can do about that.)  So the region used for locking is at the
+** end of the file where it is unlikely to ever interfere with an
+** actual read attempt.
+**
+** A database read lock is obtained by locking a single randomly-chosen 
+** byte out of a specific range of bytes. The lock byte is obtained at 
+** random so two separate readers can probably access the file at the 
+** same time, unless they are unlucky and choose the same lock byte.
+** A database write lock is obtained by locking all bytes in the range.
+** There can only be one writer.
+**
+** A lock is obtained on the first byte of the lock range before acquiring
+** either a read lock or a write lock.  This prevents two processes from
+** attempting to get a lock at a same time.  The semantics of 
+** sqlite3OsReadLock() require that if there is already a write lock, that
+** lock is converted into a read lock atomically.  The lock on the first
+** byte allows us to drop the old write lock and get the read lock without
+** another process jumping into the middle and messing us up.  The same
+** argument applies to sqlite3OsWriteLock().
+**
+** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
+** which means we can use reader/writer locks.  When reader writer locks
+** are used, the lock is placed on the same range of bytes that is used
+** for probabilistic locking in Win95/98/ME.  Hence, the locking scheme
+** will support two or more Win95 readers or two or more WinNT readers.
+** But a single Win95 reader will lock out all WinNT readers and a single
+** WinNT reader will lock out all other Win95 readers.
+**
+** The following #defines specify the range of bytes used for locking.
+** N_LOCKBYTE is the number of bytes available for doing the locking.
+** The first byte used to hold the lock while the lock is changing does
+** not count toward this number.  FIRST_LOCKBYTE is the address of
+** the first byte in the range of bytes used for locking.
+*/
+#define N_LOCKBYTE       10239
+#define FIRST_LOCKBYTE   (0xffffffff - N_LOCKBYTE)
+
+/*
+** Change the status of the lock on the file "id" to be a readlock.
+** If the file was write locked, then this reduces the lock to a read.
+** If the file was read locked, then this acquires a new read lock.
+**
+** Return SQLITE_OK on success and SQLITE_BUSY on failure.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsReadLock(OsFile *id){
+  int rc;
+  if( id->locked>0 ){
+    rc = SQLITE_OK;
+  }else{
+    int lk;
+    int res;
+    int cnt = 100;
+    sqlite3Randomness(sizeof(lk), &lk);
+    lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
+    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
+      Sleep(1);
+    }
+    if( res ){
+      UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+      if( isNT() ){
+        OVERLAPPED ovlp;
+        ovlp.Offset = FIRST_LOCKBYTE+1;
+        ovlp.OffsetHigh = 0;
+        ovlp.hEvent = 0;
+        res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 
+                          0, N_LOCKBYTE, 0, &ovlp);
+      }else{
+        res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
+      }
+      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
+    }
+    if( res ){
+      id->locked = lk;
+      rc = SQLITE_OK;
+    }else{
+      rc = SQLITE_BUSY;
+    }
+  }
+  return rc;
+}
+
+/*
+** Change the lock status to be an exclusive or write lock.  Return
+** SQLITE_OK on success and SQLITE_BUSY on a failure.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsWriteLock(OsFile *id){
+  int rc;
+  if( id->locked<0 ){
+    rc = SQLITE_OK;
+  }else{
+    int res;
+    int cnt = 100;
+    while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
+      Sleep(1);
+    }
+    if( res ){
+      if( id->locked>0 ){
+        if( isNT() ){
+          UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+        }else{
+          res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
+        }
+      }
+      if( res ){
+        res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+      }else{
+        res = 0;
+      }
+      UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
+    }
+    if( res ){
+      id->locked = -1;
+      rc = SQLITE_OK;
+    }else{
+      rc = SQLITE_BUSY;
+    }
+  }
+  return rc;
+}
+
+/*
+** Unlock the given file descriptor.  If the file descriptor was
+** not previously locked, then this routine is a no-op.  If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an SQLITE_NOLFS is returned.
+*/
+int sqlite3OsUnlock(OsFile *id){
+  int rc;
+  if( id->locked==0 ){
+    rc = SQLITE_OK;
+  }else if( isNT() || id->locked<0 ){
+    UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+    rc = SQLITE_OK;
+    id->locked = 0;
+  }else{
+    UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
+    rc = SQLITE_OK;
+    id->locked = 0;
+  }
+  return rc;
+}
+
+/*
+** Get information to seed the random number generator.  The seed
+** is written into the buffer zBuf[256].  The calling function must
+** supply a sufficiently large buffer.
+*/
+int sqlite3OsRandomSeed(char *zBuf){
+  /* We have to initialize zBuf to prevent valgrind from reporting
+  ** errors.  The reports issued by valgrind are incorrect - we would
+  ** prefer that the randomness be increased by making use of the
+  ** uninitialized space in zBuf - but valgrind errors tend to worry
+  ** some users.  Rather than argue, it seems easier just to initialize
+  ** the whole array and silence valgrind, even if that means less randomness
+  ** in the random seed.
+  **
+  ** When testing, initializing zBuf[] to zero is all we do.  That means
+  ** that we always use the same random number sequence.* This makes the
+  ** tests repeatable.
+  */
+  memset(zBuf, 0, 256);
+  GetSystemTime((LPSYSTEMTIME)zBuf);
+  return SQLITE_OK;
+}
+
+/*
+** Sleep for a little while.  Return the amount of time slept.
+*/
+int sqlite3OsSleep(int ms){
+  Sleep(ms);
+  return ms;
+}
+
+/*
+** Static variables used for thread synchronization
+*/
+static int inMutex = 0;
+#ifdef SQLITE_W32_THREADS
+  static CRITICAL_SECTION cs;
+#endif
+
+/*
+** The following pair of routine implement mutual exclusion for
+** multi-threaded processes.  Only a single thread is allowed to
+** executed code that is surrounded by EnterMutex() and LeaveMutex().
+**
+** SQLite uses only a single Mutex.  There is not much critical
+** code and what little there is executes quickly and without blocking.
+*/
+void sqlite3OsEnterMutex(){
+#ifdef SQLITE_W32_THREADS
+  static int isInit = 0;
+  while( !isInit ){
+    static long lock = 0;
+    if( InterlockedIncrement(&lock)==1 ){
+      InitializeCriticalSection(&cs);
+      isInit = 1;
+    }else{
+      Sleep(1);
+    }
+  }
+  EnterCriticalSection(&cs);
+#endif
+  assert( !inMutex );
+  inMutex = 1;
+}
+void sqlite3OsLeaveMutex(){
+  assert( inMutex );
+  inMutex = 0;
+#ifdef SQLITE_W32_THREADS
+  LeaveCriticalSection(&cs);
+#endif
+}
+
+/*
+** Turn a relative pathname into a full pathname.  Return a pointer
+** to the full pathname stored in space obtained from sqliteMalloc().
+** The calling function is responsible for freeing this space once it
+** is no longer needed.
+*/
+char *sqlite3OsFullPathname(const char *zRelative){
+  char *zNotUsed;
+  char *zFull;
+  int nByte;
+  nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
+  zFull = sqliteMalloc( nByte );
+  if( zFull==0 ) return 0;
+  GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
+  return zFull;
+}
+
+/*
+** The following variable, if set to a non-zero value, becomes the result
+** returned from sqlite3OsCurrentTime().  This is used for testing.
+*/
+#ifdef SQLITE_TEST
+int sqlite3_current_time = 0;
+#endif
+
+/*
+** Find the current time (in Universal Coordinated Time).  Write the
+** current time and date as a Julian Day number into *prNow and
+** return 0.  Return 1 if the time and date cannot be found.
+*/
+int sqlite3OsCurrentTime(double *prNow){
+  FILETIME ft;
+  /* FILETIME structure is a 64-bit value representing the number of 
+     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
+  */
+  double now;
+  GetSystemTimeAsFileTime( &ft );
+  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
+  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
+#ifdef SQLITE_TEST
+  if( sqlite3_current_time ){
+    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
+  }
+#endif
+  return 0;
+}
+
+#endif /* OS_WIN */
diff --git a/src/os_win.h b/src/os_win.h
new file mode 100644 (file)
index 0000000..35f7740
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+** 2004 May 22
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This header file defines OS-specific features for Win32
+*/
+#ifndef _SQLITE_OS_WIN_H_
+#define _SQLITE_OS_WIN_H_
+
+#include <windows.h>
+#include <winbase.h>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  typedef __int64 off_t;
+#else
+# if !defined(_CYGWIN_TYPES_H)
+  typedef long long off_t;
+#   if defined(__MINGW32__)
+#     define   _OFF_T_
+#   endif
+# endif
+#endif
+
+/*
+** The OsFile structure is a operating-system independing representation
+** of an open file handle.  It is defined differently for each architecture.
+**
+** This is the definition for Win32.
+*/
+typedef struct OsFile OsFile;
+struct OsFile {
+  HANDLE h;               /* Handle for accessing the file */
+  int locked;             /* 0: unlocked, <0: write lock, >0: read lock */
+};
+
+
+#define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
+#define SQLITE_MIN_SLEEP_MS 1
+
+
+#endif /* _SQLITE_OS_WIN_H_ */
index 5e3153bd2ae39a5f27dda31f0cbd5f5befaf5bb9..5c233e9f317b04df7df7aa104d3739553da3921a 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.245 2004/05/22 03:05:34 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.246 2004/05/22 17:41:59 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -129,6 +129,14 @@ typedef UINT8_TYPE i8;             /* 1-byte signed integer */
 typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
 typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
 
+/*
+** Macros to determine whether the machine is big or little endian,
+** evaluated at runtime.
+*/
+extern const int sqlite3one;
+#define SQLITE3_BIGENDIAN    (*(char *)(&sqlite3one)==0)
+#define SQLITE3_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
+
 /*
 ** Defer sourcing vdbe.h until after the "u8" typedef is defined.
 */
index 5e77967a618817f29ffb1de2f361ddaa4461c06c..5548de258dccf8765b862311a26b1d151a866c08 100644 (file)
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
 ** This file contains routines used to translate between UTF-8, 
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.7 2004/05/22 03:05:34 danielk1977 Exp $
+** $Id: utf.c,v 1.8 2004/05/22 17:41:59 drh Exp $
 **
 ** Notes on UTF-8:
 **
 ** replacement character U+FFFD for each pair of bytes that cannot be
 ** interpeted as part of a valid unicode character.
 */
-
 #include <assert.h>
-#include <unistd.h>
 #include "sqliteInt.h"
-#include "os.h"
 
 typedef struct UtfString UtfString;
 struct UtfString {
@@ -590,5 +587,3 @@ int sqlite3utfTranslate(
   }
   return SQLITE_OK;
 }
-