mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Added support for OS/2. Ticket #1817 (CVS 3198)
FossilOrigin-Name: 373246c2d1edaec1ce248ff875db48ce51d896f9
This commit is contained in:
@@ -125,7 +125,7 @@ TCC += -DSQLITE_OMIT_CURSOR
|
|||||||
LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \
|
LIBOBJ = alter.lo analyze.lo attach.lo auth.lo btree.lo build.lo \
|
||||||
callback.lo complete.lo date.lo \
|
callback.lo complete.lo date.lo \
|
||||||
delete.lo expr.lo func.lo hash.lo insert.lo \
|
delete.lo expr.lo func.lo hash.lo insert.lo \
|
||||||
main.lo opcodes.lo os.lo os_unix.lo os_win.lo \
|
main.lo opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
|
||||||
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
pager.lo parse.lo pragma.lo prepare.lo printf.lo random.lo \
|
||||||
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
select.lo table.lo tokenize.lo trigger.lo update.lo \
|
||||||
util.lo vacuum.lo \
|
util.lo vacuum.lo \
|
||||||
@@ -156,6 +156,7 @@ SRC = \
|
|||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
$(TOP)/src/os_win.c \
|
$(TOP)/src/os_win.c \
|
||||||
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/pager.c \
|
$(TOP)/src/pager.c \
|
||||||
$(TOP)/src/pager.h \
|
$(TOP)/src/pager.h \
|
||||||
$(TOP)/src/parse.y \
|
$(TOP)/src/parse.y \
|
||||||
@@ -193,6 +194,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
$(TOP)/src/os_win.c \
|
$(TOP)/src/os_win.c \
|
||||||
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/pager.c \
|
$(TOP)/src/pager.c \
|
||||||
$(TOP)/src/pragma.c \
|
$(TOP)/src/pragma.c \
|
||||||
$(TOP)/src/printf.c \
|
$(TOP)/src/printf.c \
|
||||||
@@ -257,7 +259,7 @@ libtclsqlite3.la: tclsqlite.lo libsqlite3.la
|
|||||||
|
|
||||||
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||||
$(LTLINK) $(READLINE_FLAGS) $(LIBPTHREAD) \
|
$(LTLINK) $(READLINE_FLAGS) $(LIBPTHREAD) \
|
||||||
-o sqlite3 $(TOP)/src/shell.c libsqlite3.la \
|
-o $@ $(TOP)/src/shell.c libsqlite3.la \
|
||||||
$(LIBREADLINE) $(TLIBS)
|
$(LIBREADLINE) $(TLIBS)
|
||||||
|
|
||||||
# This target creates a directory named "tsrc" and fills it with
|
# This target creates a directory named "tsrc" and fills it with
|
||||||
@@ -352,6 +354,9 @@ os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
|
|||||||
os_win.lo: $(TOP)/src/os_win.c $(HDR)
|
os_win.lo: $(TOP)/src/os_win.c $(HDR)
|
||||||
$(LTCOMPILE) -c $(TOP)/src/os_win.c
|
$(LTCOMPILE) -c $(TOP)/src/os_win.c
|
||||||
|
|
||||||
|
os_os2.lo: $(TOP)/src/os_os2.c $(HDR)
|
||||||
|
$(LTCOMPILE) -c $(TOP)/src/os_os2.c
|
||||||
|
|
||||||
parse.lo: parse.c $(HDR)
|
parse.lo: parse.c $(HDR)
|
||||||
$(LTCOMPILE) -c parse.c
|
$(LTCOMPILE) -c parse.c
|
||||||
|
|
||||||
|
|||||||
2
aclocal.m4
vendored
2
aclocal.m4
vendored
@@ -151,7 +151,7 @@ ltmain="$ac_aux_dir/ltmain.sh"
|
|||||||
ofile="$default_ofile"
|
ofile="$default_ofile"
|
||||||
with_gnu_ld="$lt_cv_prog_gnu_ld"
|
with_gnu_ld="$lt_cv_prog_gnu_ld"
|
||||||
|
|
||||||
AC_CHECK_TOOL(AR, ar, false)
|
AC_CHECK_TOOL(AR, ar, AC_CHECK_TOOL(AR, emxomfar, false))
|
||||||
AC_CHECK_TOOL(RANLIB, ranlib, :)
|
AC_CHECK_TOOL(RANLIB, ranlib, :)
|
||||||
AC_CHECK_TOOL(STRIP, strip, :)
|
AC_CHECK_TOOL(STRIP, strip, :)
|
||||||
|
|
||||||
|
|||||||
18
configure
vendored
18
configure
vendored
@@ -463,7 +463,7 @@ ac_includes_default="\
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif"
|
#endif"
|
||||||
|
|
||||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK program_prefix VERSION RELEASE VERSION_NUMBER BUILD_CC BUILD_CFLAGS BUILD_LIBS TARGET_CC TARGET_CFLAGS TARGET_LINK TARGET_LFLAGS TARGET_RANLIB TARGET_AR THREADSAFE TARGET_THREAD_LIB XTHREADCONNECT THREADSOVERRIDELOCKS ALLOWRELEASE TEMP_STORE BUILD_EXEEXT OS_UNIX OS_WIN TARGET_EXEEXT TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIBS TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC HAVE_TCL TARGET_READLINE_LIBS TARGET_READLINE_INC TARGET_HAVE_READLINE TARGET_DEBUG TARGET_LIBS LIBOBJS LTLIBOBJS'
|
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK program_prefix VERSION RELEASE VERSION_NUMBER BUILD_CC BUILD_CFLAGS BUILD_LIBS TARGET_CC TARGET_CFLAGS TARGET_LINK TARGET_LFLAGS TARGET_RANLIB TARGET_AR THREADSAFE TARGET_THREAD_LIB XTHREADCONNECT THREADSOVERRIDELOCKS ALLOWRELEASE TEMP_STORE BUILD_EXEEXT OS_UNIX OS_WIN OS_OS2 TARGET_EXEEXT TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIBS TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC HAVE_TCL TARGET_READLINE_LIBS TARGET_READLINE_INC TARGET_HAVE_READLINE TARGET_DEBUG TARGET_LIBS LIBOBJS LTLIBOBJS'
|
||||||
ac_subst_files=''
|
ac_subst_files=''
|
||||||
|
|
||||||
# Initialize some variables set by options.
|
# Initialize some variables set by options.
|
||||||
@@ -1502,7 +1502,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||||||
|
|
||||||
|
|
||||||
# The following RCS revision string applies to configure.in
|
# The following RCS revision string applies to configure.in
|
||||||
# $Revision: 1.39 $
|
# $Revision: 1.40 $
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# Programs needed
|
# Programs needed
|
||||||
@@ -19695,13 +19695,26 @@ else
|
|||||||
TARGET_EXEEXT=$config_TARGET_EXEEXT
|
TARGET_EXEEXT=$config_TARGET_EXEEXT
|
||||||
fi
|
fi
|
||||||
if test "$TARGET_EXEEXT" = ".exe"; then
|
if test "$TARGET_EXEEXT" = ".exe"; then
|
||||||
|
if test $OS2_SHELL ; then
|
||||||
|
OS_UNIX=0
|
||||||
|
OS_WIN=0
|
||||||
|
OS_OS2=1
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_OS2=1"
|
||||||
|
if test "$ac_compiler_gnu" == "yes" ; then
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -Zomf -Zexe -Zmap"
|
||||||
|
BUILD_CFLAGS="$BUILD_CFLAGS -Zomf -Zexe"
|
||||||
|
fi
|
||||||
|
else
|
||||||
OS_UNIX=0
|
OS_UNIX=0
|
||||||
OS_WIN=1
|
OS_WIN=1
|
||||||
|
OS_OS2=0
|
||||||
tclsubdir=win
|
tclsubdir=win
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1"
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
OS_UNIX=1
|
OS_UNIX=1
|
||||||
OS_WIN=0
|
OS_WIN=0
|
||||||
|
OS_OS2=0
|
||||||
tclsubdir=unix
|
tclsubdir=unix
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1"
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1"
|
||||||
fi
|
fi
|
||||||
@@ -21378,6 +21391,7 @@ s,@TEMP_STORE@,$TEMP_STORE,;t t
|
|||||||
s,@BUILD_EXEEXT@,$BUILD_EXEEXT,;t t
|
s,@BUILD_EXEEXT@,$BUILD_EXEEXT,;t t
|
||||||
s,@OS_UNIX@,$OS_UNIX,;t t
|
s,@OS_UNIX@,$OS_UNIX,;t t
|
||||||
s,@OS_WIN@,$OS_WIN,;t t
|
s,@OS_WIN@,$OS_WIN,;t t
|
||||||
|
s,@OS_OS2@,$OS_OS2,;t t
|
||||||
s,@TARGET_EXEEXT@,$TARGET_EXEEXT,;t t
|
s,@TARGET_EXEEXT@,$TARGET_EXEEXT,;t t
|
||||||
s,@TCL_VERSION@,$TCL_VERSION,;t t
|
s,@TCL_VERSION@,$TCL_VERSION,;t t
|
||||||
s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
|
s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
|
||||||
|
|||||||
16
configure.ac
16
configure.ac
@@ -116,7 +116,7 @@ AC_INIT(src/sqlite.h.in)
|
|||||||
dnl Put the RCS revision string after AC_INIT so that it will also
|
dnl Put the RCS revision string after AC_INIT so that it will also
|
||||||
dnl show in in configure.
|
dnl show in in configure.
|
||||||
# The following RCS revision string applies to configure.in
|
# The following RCS revision string applies to configure.in
|
||||||
# $Revision: 1.25 $
|
# $Revision: 1.26 $
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# Programs needed
|
# Programs needed
|
||||||
@@ -407,13 +407,26 @@ else
|
|||||||
TARGET_EXEEXT=$config_TARGET_EXEEXT
|
TARGET_EXEEXT=$config_TARGET_EXEEXT
|
||||||
fi
|
fi
|
||||||
if test "$TARGET_EXEEXT" = ".exe"; then
|
if test "$TARGET_EXEEXT" = ".exe"; then
|
||||||
|
if test $OS2_SHELL ; then
|
||||||
|
OS_UNIX=0
|
||||||
|
OS_WIN=0
|
||||||
|
OS_OS2=1
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_OS2=1"
|
||||||
|
if test "$ac_compiler_gnu" == "yes" ; then
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -Zomf -Zexe -Zmap"
|
||||||
|
BUILD_CFLAGS="$BUILD_CFLAGS -Zomf -Zexe"
|
||||||
|
fi
|
||||||
|
else
|
||||||
OS_UNIX=0
|
OS_UNIX=0
|
||||||
OS_WIN=1
|
OS_WIN=1
|
||||||
|
OS_OS2=0
|
||||||
tclsubdir=win
|
tclsubdir=win
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1"
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_WIN=1"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
OS_UNIX=1
|
OS_UNIX=1
|
||||||
OS_WIN=0
|
OS_WIN=0
|
||||||
|
OS_OS2=0
|
||||||
tclsubdir=unix
|
tclsubdir=unix
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1"
|
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_UNIX=1"
|
||||||
fi
|
fi
|
||||||
@@ -421,6 +434,7 @@ fi
|
|||||||
AC_SUBST(BUILD_EXEEXT)
|
AC_SUBST(BUILD_EXEEXT)
|
||||||
AC_SUBST(OS_UNIX)
|
AC_SUBST(OS_UNIX)
|
||||||
AC_SUBST(OS_WIN)
|
AC_SUBST(OS_WIN)
|
||||||
|
AC_SUBST(OS_OS2)
|
||||||
AC_SUBST(TARGET_EXEEXT)
|
AC_SUBST(TARGET_EXEEXT)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
|
|||||||
7
main.mk
7
main.mk
@@ -58,7 +58,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
|
|||||||
LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \
|
LIBOBJ+= alter.o analyze.o attach.o auth.o btree.o build.o \
|
||||||
callback.o complete.o date.o delete.o \
|
callback.o complete.o date.o delete.o \
|
||||||
expr.o func.o hash.o insert.o \
|
expr.o func.o hash.o insert.o \
|
||||||
main.o opcodes.o os.o os_unix.o os_win.o \
|
main.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
||||||
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
pager.o parse.o pragma.o prepare.o printf.o random.o \
|
||||||
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
select.o table.o tclsqlite.o tokenize.o trigger.o \
|
||||||
update.o util.o vacuum.o \
|
update.o util.o vacuum.o \
|
||||||
@@ -87,6 +87,7 @@ SRC = \
|
|||||||
$(TOP)/src/legacy.c \
|
$(TOP)/src/legacy.c \
|
||||||
$(TOP)/src/main.c \
|
$(TOP)/src/main.c \
|
||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
$(TOP)/src/os_win.c \
|
$(TOP)/src/os_win.c \
|
||||||
$(TOP)/src/pager.c \
|
$(TOP)/src/pager.c \
|
||||||
@@ -124,6 +125,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
$(TOP)/src/func.c \
|
$(TOP)/src/func.c \
|
||||||
$(TOP)/src/os.c \
|
$(TOP)/src/os.c \
|
||||||
|
$(TOP)/src/os_os2.c \
|
||||||
$(TOP)/src/os_unix.c \
|
$(TOP)/src/os_unix.c \
|
||||||
$(TOP)/src/os_win.c \
|
$(TOP)/src/os_win.c \
|
||||||
$(TOP)/src/pager.c \
|
$(TOP)/src/pager.c \
|
||||||
@@ -270,6 +272,9 @@ opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
|
|||||||
os.o: $(TOP)/src/os.c $(HDR)
|
os.o: $(TOP)/src/os.c $(HDR)
|
||||||
$(TCCX) -c $(TOP)/src/os.c
|
$(TCCX) -c $(TOP)/src/os.c
|
||||||
|
|
||||||
|
os_os2.o: $(TOP)/src/os_os2.c $(HDR)
|
||||||
|
$(TCCX) -c $(TOP)/src/os_os2.c
|
||||||
|
|
||||||
os_unix.o: $(TOP)/src/os_unix.c $(HDR)
|
os_unix.o: $(TOP)/src/os_unix.c $(HDR)
|
||||||
$(TCCX) -c $(TOP)/src/os_unix.c
|
$(TCCX) -c $(TOP)/src/os_unix.c
|
||||||
|
|
||||||
|
|||||||
24
manifest
24
manifest
@@ -1,10 +1,10 @@
|
|||||||
C Do\snot\srecord\sblank\slines\sin\sthe\scommand-line\sediting\shistory\sof\sthe\sshell.\s(CVS\s3197)
|
C Added\ssupport\sfor\sOS/2.\s\sTicket\s#1817\s(CVS\s3198)
|
||||||
D 2006-06-03T17:37:26
|
D 2006-06-03T18:02:16
|
||||||
F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b
|
F Makefile.in 87b6d483513ab8a4e763775bc5b434d6b5c34963
|
||||||
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
F VERSION 2bc3eace6a71bc4f2575679b944378b275e9412c
|
F VERSION 2bc3eace6a71bc4f2575679b944378b275e9412c
|
||||||
F aclocal.m4 7daea4c35e88de30d5a3f6f7a2ab99720e803bbd
|
F aclocal.m4 a8df0ae21d1ac797fa7d7eaa1703412bc61b973f
|
||||||
F addopcodes.awk 701697fae48376375ec8532c3d04e910cfeef352
|
F addopcodes.awk 701697fae48376375ec8532c3d04e910cfeef352
|
||||||
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248
|
||||||
F art/SQLite.eps 9b43cc99cfd2be687d386faea6862ea68d6a72b2
|
F art/SQLite.eps 9b43cc99cfd2be687d386faea6862ea68d6a72b2
|
||||||
@@ -12,14 +12,14 @@ F art/SQLite.gif 1bbb94484963f1382e27e1c5e86dd0c1061eba2b
|
|||||||
F art/SQLiteLogo3.tiff b9e6bf022ae939bc986cddb8ab99583ca1b02cb3
|
F art/SQLiteLogo3.tiff b9e6bf022ae939bc986cddb8ab99583ca1b02cb3
|
||||||
F config.guess 2103e94b15dc57112d7b9ee152c6fac5288895b4
|
F config.guess 2103e94b15dc57112d7b9ee152c6fac5288895b4
|
||||||
F config.sub 9bf686ec001ae7bc53f5b3563c90c62d4c6d48be
|
F config.sub 9bf686ec001ae7bc53f5b3563c90c62d4c6d48be
|
||||||
F configure d454f3ef3a1cf42e91e97d06c27179d56a77c005 x
|
F configure 6be7b37dd811c43f59c119aa5a713f688a2184c4 x
|
||||||
F configure.ac f6c5246585d14bc1ee1773ae5b71ae6cafa7494a
|
F configure.ac 83eaf11869cd893db6126c0ce77381a9cd264bad
|
||||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||||
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||||
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
||||||
F main.mk 33144e8ccfa885a4b0c1c03e85131bd6c541f30c
|
F main.mk e3dd76266d1b62f1835b238bb0565900ab99fe14
|
||||||
F mkdll.sh 919df5efde876194e3102c6ebc60657d38949909
|
F mkdll.sh 919df5efde876194e3102c6ebc60657d38949909
|
||||||
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
|
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
|
||||||
F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5
|
F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5
|
||||||
@@ -51,8 +51,10 @@ F src/legacy.c fa15d505dd4e45044177ee4d1c6aeaf8c836d390
|
|||||||
F src/main.c 928d93cfd5d72be3a619ee908182c9432151a99e
|
F src/main.c 928d93cfd5d72be3a619ee908182c9432151a99e
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235
|
F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235
|
||||||
F src/os.h 93035a0e3b9dd05cdd0aaef32ea28ca28e02fe78
|
F src/os.h 46fad85c707ad8643622bab9d894a642940850aa
|
||||||
F src/os_common.h 108cd719c96a2b714b64e02aeabbd40684274e6a
|
F src/os_common.h 108cd719c96a2b714b64e02aeabbd40684274e6a
|
||||||
|
F src/os_os2.c 123cb394c069bc8c6a305830ffa2bc5f72e5b83a
|
||||||
|
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
|
||||||
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
||||||
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
||||||
F src/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7
|
F src/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7
|
||||||
@@ -356,7 +358,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 4bf03c3bbc1303ed9b4059917e8d6a613b1510f3
|
P 0eabda82cd0d476a7e05ba4b027b819318aef9c3
|
||||||
R b3aa39403a9b5a900b82638a005965c6
|
R 6acf85d509c19fb60080d44405f8852c
|
||||||
U drh
|
U drh
|
||||||
Z eb8ea770aee12d212e5ceb58cc64d4fe
|
Z b6f82a7c0122f6042d20b908e87d0aa6
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0eabda82cd0d476a7e05ba4b027b819318aef9c3
|
373246c2d1edaec1ce248ff875db48ce51d896f9
|
||||||
40
src/os.h
40
src/os.h
@@ -27,12 +27,19 @@
|
|||||||
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
|
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
|
||||||
# define OS_WIN 1
|
# define OS_WIN 1
|
||||||
# define OS_UNIX 0
|
# define OS_UNIX 0
|
||||||
|
# define OS_OS2 0
|
||||||
|
# elif defined(_EMX_) || defined(_OS2) || defined(OS2) || defined(OS_OS2)
|
||||||
|
# define OS_WIN 0
|
||||||
|
# define OS_UNIX 0
|
||||||
|
# define OS_OS2 1
|
||||||
# else
|
# else
|
||||||
# define OS_WIN 0
|
# define OS_WIN 0
|
||||||
# define OS_UNIX 1
|
# define OS_UNIX 1
|
||||||
|
# define OS_OS2 0
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# define OS_UNIX 0
|
# define OS_UNIX 0
|
||||||
|
# define OS_OS2 0
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# ifndef OS_WIN
|
# ifndef OS_WIN
|
||||||
@@ -47,6 +54,14 @@
|
|||||||
#if OS_WIN
|
#if OS_WIN
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
|
||||||
|
#elif OS_OS2
|
||||||
|
# define INCL_DOSDATETIME
|
||||||
|
# define INCL_DOSFILEMGR
|
||||||
|
# define INCL_DOSERRORS
|
||||||
|
# define INCL_DOSMISC
|
||||||
|
# define INCL_DOSPROCESS
|
||||||
|
# include <os2.h>
|
||||||
|
# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
|
||||||
#else
|
#else
|
||||||
# define SQLITE_TEMPNAME_SIZE 200
|
# define SQLITE_TEMPNAME_SIZE 200
|
||||||
#endif
|
#endif
|
||||||
@@ -72,7 +87,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Define the interfaces for Unix and for Windows.
|
** Define the interfaces for Unix, Windows, and OS/2.
|
||||||
*/
|
*/
|
||||||
#if OS_UNIX
|
#if OS_UNIX
|
||||||
#define sqlite3OsOpenReadWrite sqlite3UnixOpenReadWrite
|
#define sqlite3OsOpenReadWrite sqlite3UnixOpenReadWrite
|
||||||
@@ -118,6 +133,29 @@
|
|||||||
#define sqlite3OsFree sqlite3GenericFree
|
#define sqlite3OsFree sqlite3GenericFree
|
||||||
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
|
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
|
||||||
#endif
|
#endif
|
||||||
|
#if OS_OS2
|
||||||
|
#define sqlite3OsOpenReadWrite sqlite3Os2OpenReadWrite
|
||||||
|
#define sqlite3OsOpenExclusive sqlite3Os2OpenExclusive
|
||||||
|
#define sqlite3OsOpenReadOnly sqlite3Os2OpenReadOnly
|
||||||
|
#define sqlite3OsDelete sqlite3Os2Delete
|
||||||
|
#define sqlite3OsFileExists sqlite3Os2FileExists
|
||||||
|
#define sqlite3OsFullPathname sqlite3Os2FullPathname
|
||||||
|
#define sqlite3OsIsDirWritable sqlite3Os2IsDirWritable
|
||||||
|
#define sqlite3OsSyncDirectory sqlite3Os2SyncDirectory
|
||||||
|
#define sqlite3OsTempFileName sqlite3Os2TempFileName
|
||||||
|
#define sqlite3OsRandomSeed sqlite3Os2RandomSeed
|
||||||
|
#define sqlite3OsSleep sqlite3Os2Sleep
|
||||||
|
#define sqlite3OsCurrentTime sqlite3Os2CurrentTime
|
||||||
|
#define sqlite3OsEnterMutex sqlite3Os2EnterMutex
|
||||||
|
#define sqlite3OsLeaveMutex sqlite3Os2LeaveMutex
|
||||||
|
#define sqlite3OsInMutex sqlite3Os2InMutex
|
||||||
|
#define sqlite3OsThreadSpecificData sqlite3Os2ThreadSpecificData
|
||||||
|
#define sqlite3OsMalloc sqlite3GenericMalloc
|
||||||
|
#define sqlite3OsRealloc sqlite3GenericRealloc
|
||||||
|
#define sqlite3OsFree sqlite3GenericFree
|
||||||
|
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If using an alternative OS interface, then we must have an "os_other.h"
|
** If using an alternative OS interface, then we must have an "os_other.h"
|
||||||
|
|||||||
965
src/os_os2.c
Normal file
965
src/os_os2.c
Normal file
@@ -0,0 +1,965 @@
|
|||||||
|
/*
|
||||||
|
** 2006 Feb 14
|
||||||
|
**
|
||||||
|
** 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 OS/2.
|
||||||
|
*/
|
||||||
|
#include "sqliteInt.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#if OS_OS2
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Macros used to determine whether or not to use threads.
|
||||||
|
*/
|
||||||
|
#if defined(THREADSAFE) && THREADSAFE
|
||||||
|
# define SQLITE_OS2_THREADS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Include code that is common to all os_*.c files
|
||||||
|
*/
|
||||||
|
#include "os_common.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The os2File structure is subclass of OsFile specific for the OS/2
|
||||||
|
** protability layer.
|
||||||
|
*/
|
||||||
|
typedef struct os2File os2File;
|
||||||
|
struct os2File {
|
||||||
|
IoMethod const *pMethod; /* Always the first entry */
|
||||||
|
HFILE h; /* Handle for accessing the file */
|
||||||
|
int delOnClose; /* True if file is to be deleted on close */
|
||||||
|
char* pathToDel; /* Name of file to delete on close */
|
||||||
|
unsigned char locktype; /* Type of lock currently held on this file */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Do not include any of the File I/O interface procedures if the
|
||||||
|
** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
|
||||||
|
** will be in-memory only)
|
||||||
|
*/
|
||||||
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete the named file
|
||||||
|
*/
|
||||||
|
int sqlite3Os2Delete( const char *zFilename ){
|
||||||
|
DosDelete( (PSZ)zFilename );
|
||||||
|
TRACE2( "DELETE \"%s\"\n", zFilename );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return TRUE if the named file exists.
|
||||||
|
*/
|
||||||
|
int sqlite3Os2FileExists( const char *zFilename ){
|
||||||
|
FILESTATUS3 fsts3ConfigInfo;
|
||||||
|
memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo));
|
||||||
|
return DosQueryPathInfo( (PSZ)zFilename, FIL_STANDARD,
|
||||||
|
&fsts3ConfigInfo, sizeof(FILESTATUS3) ) == NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forward declaration */
|
||||||
|
int allocateOs2File( os2File *pInit, OsFile **pld );
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 sqlite3Os2OpenReadWrite(
|
||||||
|
const char *zFilename,
|
||||||
|
OsFile **pld,
|
||||||
|
int *pReadonly
|
||||||
|
){
|
||||||
|
os2File f;
|
||||||
|
HFILE hf;
|
||||||
|
ULONG ulAction;
|
||||||
|
APIRET rc;
|
||||||
|
|
||||||
|
assert( *pld == 0 );
|
||||||
|
rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
|
||||||
|
FILE_ARCHIVED | FILE_NORMAL,
|
||||||
|
OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
|
||||||
|
OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
|
||||||
|
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL );
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
|
||||||
|
FILE_ARCHIVED | FILE_NORMAL,
|
||||||
|
OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
|
||||||
|
OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
|
||||||
|
OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL );
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
*pReadonly = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
*pReadonly = 0;
|
||||||
|
}
|
||||||
|
f.h = hf;
|
||||||
|
f.locktype = NO_LOCK;
|
||||||
|
f.delOnClose = 0;
|
||||||
|
f.pathToDel = NULL;
|
||||||
|
OpenCounter(+1);
|
||||||
|
TRACE3( "OPEN R/W %d \"%s\"\n", hf, zFilename );
|
||||||
|
return allocateOs2File( &f, pld );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 sqlite3Os2OpenExclusive( const char *zFilename, OsFile **pld, int delFlag ){
|
||||||
|
os2File f;
|
||||||
|
HFILE hf;
|
||||||
|
ULONG ulAction;
|
||||||
|
APIRET rc;
|
||||||
|
|
||||||
|
assert( *pld == 0 );
|
||||||
|
rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L, FILE_NORMAL,
|
||||||
|
OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS,
|
||||||
|
OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
|
||||||
|
OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, (PEAOP2)NULL );
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.h = hf;
|
||||||
|
f.locktype = NO_LOCK;
|
||||||
|
f.delOnClose = delFlag ? 1 : 0;
|
||||||
|
f.pathToDel = delFlag ? sqlite3OsFullPathname( zFilename ) : NULL;
|
||||||
|
OpenCounter( +1 );
|
||||||
|
if( delFlag ) DosForceDelete( sqlite3OsFullPathname( zFilename ) );
|
||||||
|
TRACE3( "OPEN EX %d \"%s\"\n", hf, sqlite3OsFullPathname ( zFilename ) );
|
||||||
|
return allocateOs2File( &f, pld );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 sqlite3Os2OpenReadOnly( const char *zFilename, OsFile **pld ){
|
||||||
|
os2File f;
|
||||||
|
HFILE hf;
|
||||||
|
ULONG ulAction;
|
||||||
|
APIRET rc;
|
||||||
|
|
||||||
|
assert( *pld == 0 );
|
||||||
|
rc = DosOpen( (PSZ)zFilename, &hf, &ulAction, 0L,
|
||||||
|
FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
|
||||||
|
OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_RANDOM |
|
||||||
|
OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, (PEAOP2)NULL );
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
f.h = hf;
|
||||||
|
f.locktype = NO_LOCK;
|
||||||
|
f.delOnClose = 0;
|
||||||
|
f.pathToDel = NULL;
|
||||||
|
OpenCounter( +1 );
|
||||||
|
TRACE3( "OPEN RO %d \"%s\"\n", hf, zFilename );
|
||||||
|
return allocateOs2File( &f, pld );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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
|
||||||
|
** OS/2 since OS/2 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 os2OpenDirectory(
|
||||||
|
OsFile *id,
|
||||||
|
const char *zDirname
|
||||||
|
){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If the following global variable points to a string which is the
|
||||||
|
** name of a directory, then that directory will be used to store
|
||||||
|
** temporary files.
|
||||||
|
*/
|
||||||
|
char *sqlite3_temp_directory = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||||
|
** hold at least SQLITE_TEMPNAME_SIZE characters.
|
||||||
|
*/
|
||||||
|
int sqlite3Os2TempFileName( char *zBuf ){
|
||||||
|
static const unsigned char zChars[] =
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"0123456789";
|
||||||
|
int i, j;
|
||||||
|
PSZ zTempPath = 0;
|
||||||
|
if( DosScanEnv( "TEMP", &zTempPath ) ){
|
||||||
|
if( DosScanEnv( "TMP", &zTempPath ) ){
|
||||||
|
if( DosScanEnv( "TMPDIR", &zTempPath ) ){
|
||||||
|
ULONG ulDriveNum = 0, ulDriveMap = 0;
|
||||||
|
DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
|
||||||
|
sprintf( zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
TRACE2( "TEMP FILENAME: %s\n", zBuf );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Close a file.
|
||||||
|
*/
|
||||||
|
int os2Close( OsFile **pld ){
|
||||||
|
os2File *pFile;
|
||||||
|
if( pld && (pFile = (os2File*)*pld)!=0 ){
|
||||||
|
TRACE2( "CLOSE %d\n", pFile->h );
|
||||||
|
DosClose( pFile->h );
|
||||||
|
pFile->locktype = NO_LOCK;
|
||||||
|
if( pFile->delOnClose != 0 ){
|
||||||
|
DosForceDelete( pFile->pathToDel );
|
||||||
|
}
|
||||||
|
*pld = 0;
|
||||||
|
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 os2Read( OsFile *id, void *pBuf, int amt ){
|
||||||
|
ULONG got;
|
||||||
|
assert( id!=0 );
|
||||||
|
SimulateIOError( SQLITE_IOERR );
|
||||||
|
TRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
|
||||||
|
DosRead( ((os2File*)id)->h, pBuf, amt, &got );
|
||||||
|
return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write data from a buffer into a file. Return SQLITE_OK on success
|
||||||
|
** or some other error code on failure.
|
||||||
|
*/
|
||||||
|
int os2Write( OsFile *id, const void *pBuf, int amt ){
|
||||||
|
APIRET rc=NO_ERROR;
|
||||||
|
ULONG wrote;
|
||||||
|
assert( id!=0 );
|
||||||
|
SimulateIOError( SQLITE_IOERR );
|
||||||
|
SimulateDiskfullError;
|
||||||
|
TRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
|
||||||
|
while( amt > 0 &&
|
||||||
|
(rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){
|
||||||
|
amt -= wrote;
|
||||||
|
pBuf = &((char*)pBuf)[wrote];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Move the read/write pointer in a file.
|
||||||
|
*/
|
||||||
|
int os2Seek( OsFile *id, i64 offset ){
|
||||||
|
APIRET rc;
|
||||||
|
ULONG filePointer = 0L;
|
||||||
|
assert( id!=0 );
|
||||||
|
rc = DosSetFilePtr( ((os2File*)id)->h, offset, FILE_BEGIN, &filePointer );
|
||||||
|
TRACE3( "SEEK %d %lld\n", ((os2File*)id)->h, offset );
|
||||||
|
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Make sure all writes to a particular file are committed to disk.
|
||||||
|
*/
|
||||||
|
int os2Sync( OsFile *id, int dataOnly ){
|
||||||
|
assert( id!=0 );
|
||||||
|
TRACE3( "SYNC %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
|
||||||
|
return DosResetBuffer( ((os2File*)id)->h ) ? SQLITE_IOERR : SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Sync the directory zDirname. This is a no-op on operating systems other
|
||||||
|
** than UNIX.
|
||||||
|
*/
|
||||||
|
int sqlite3Os2SyncDirectory( const char *zDirname ){
|
||||||
|
SimulateIOError( SQLITE_IOERR );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Truncate an open file to a specified size
|
||||||
|
*/
|
||||||
|
int os2Truncate( OsFile *id, i64 nByte ){
|
||||||
|
APIRET rc;
|
||||||
|
ULONG upperBits = nByte>>32;
|
||||||
|
assert( id!=0 );
|
||||||
|
TRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte );
|
||||||
|
SimulateIOError( SQLITE_IOERR );
|
||||||
|
rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits );
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
return SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
rc = DosSetFilePtr( ((os2File*)id)->h, 0L, FILE_END, &upperBits );
|
||||||
|
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Determine the current size of a file in bytes
|
||||||
|
*/
|
||||||
|
int os2FileSize( OsFile *id, i64 *pSize ){
|
||||||
|
APIRET rc;
|
||||||
|
FILESTATUS3 fsts3FileInfo;
|
||||||
|
memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
|
||||||
|
assert( id!=0 );
|
||||||
|
SimulateIOError( SQLITE_IOERR );
|
||||||
|
rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
|
||||||
|
if( rc == NO_ERROR ){
|
||||||
|
*pSize = fsts3FileInfo.cbFile;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Acquire a reader lock.
|
||||||
|
*/
|
||||||
|
static int getReadLock( os2File *id ){
|
||||||
|
FILELOCK LockArea,
|
||||||
|
UnlockArea;
|
||||||
|
memset(&LockArea, 0, sizeof(LockArea));
|
||||||
|
memset(&UnlockArea, 0, sizeof(UnlockArea));
|
||||||
|
LockArea.lOffset = SHARED_FIRST;
|
||||||
|
LockArea.lRange = SHARED_SIZE;
|
||||||
|
UnlockArea.lOffset = 0L;
|
||||||
|
UnlockArea.lRange = 0L;
|
||||||
|
return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Undo a readlock
|
||||||
|
*/
|
||||||
|
static int unlockReadLock( os2File *id ){
|
||||||
|
FILELOCK LockArea,
|
||||||
|
UnlockArea;
|
||||||
|
memset(&LockArea, 0, sizeof(LockArea));
|
||||||
|
memset(&UnlockArea, 0, sizeof(UnlockArea));
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = SHARED_FIRST;
|
||||||
|
UnlockArea.lRange = SHARED_SIZE;
|
||||||
|
return DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||||
|
/*
|
||||||
|
** Check that a given pathname is a directory and is writable
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
int sqlite3Os2IsDirWritable( char *zDirname ){
|
||||||
|
FILESTATUS3 fsts3ConfigInfo;
|
||||||
|
APIRET rc = NO_ERROR;
|
||||||
|
memset(&fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo));
|
||||||
|
if( zDirname==0 ) return 0;
|
||||||
|
if( strlen(zDirname)>CCHMAXPATH ) return 0;
|
||||||
|
rc = DosQueryPathInfo( (PSZ)zDirname, FIL_STANDARD, &fsts3ConfigInfo, sizeof(FILESTATUS3) );
|
||||||
|
if( rc != NO_ERROR ) return 0;
|
||||||
|
if( (fsts3ConfigInfo.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY ) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Lock the file with the lock specified by parameter locktype - one
|
||||||
|
** of the following:
|
||||||
|
**
|
||||||
|
** (1) SHARED_LOCK
|
||||||
|
** (2) RESERVED_LOCK
|
||||||
|
** (3) PENDING_LOCK
|
||||||
|
** (4) EXCLUSIVE_LOCK
|
||||||
|
**
|
||||||
|
** Sometimes when requesting one lock state, additional lock states
|
||||||
|
** are inserted in between. The locking might fail on one of the later
|
||||||
|
** transitions leaving the lock state different from what it started but
|
||||||
|
** still short of its goal. The following chart shows the allowed
|
||||||
|
** transitions and the inserted intermediate states:
|
||||||
|
**
|
||||||
|
** UNLOCKED -> SHARED
|
||||||
|
** SHARED -> RESERVED
|
||||||
|
** SHARED -> (PENDING) -> EXCLUSIVE
|
||||||
|
** RESERVED -> (PENDING) -> EXCLUSIVE
|
||||||
|
** PENDING -> EXCLUSIVE
|
||||||
|
**
|
||||||
|
** This routine will only increase a lock. The os2Unlock() routine
|
||||||
|
** erases all locks at once and returns us immediately to locking level 0.
|
||||||
|
** It is not possible to lower the locking level one step at a time. You
|
||||||
|
** must go straight to locking level 0.
|
||||||
|
*/
|
||||||
|
int os2Lock( OsFile *id, int locktype ){
|
||||||
|
APIRET rc = SQLITE_OK; /* Return code from subroutines */
|
||||||
|
APIRET res = 1; /* Result of a windows lock call */
|
||||||
|
int newLocktype; /* Set id->locktype to this value before exiting */
|
||||||
|
int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
|
||||||
|
FILELOCK LockArea,
|
||||||
|
UnlockArea;
|
||||||
|
os2File *pFile = (os2File*)id;
|
||||||
|
memset(&LockArea, 0, sizeof(LockArea));
|
||||||
|
memset(&UnlockArea, 0, sizeof(UnlockArea));
|
||||||
|
assert( pFile!=0 );
|
||||||
|
TRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype );
|
||||||
|
|
||||||
|
/* If there is already a lock of this type or more restrictive on the
|
||||||
|
** OsFile, do nothing. Don't use the end_lock: exit path, as
|
||||||
|
** sqlite3OsEnterMutex() hasn't been called yet.
|
||||||
|
*/
|
||||||
|
if( pFile->locktype>=locktype ){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the locking sequence is correct
|
||||||
|
*/
|
||||||
|
assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
|
||||||
|
assert( locktype!=PENDING_LOCK );
|
||||||
|
assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
|
||||||
|
|
||||||
|
/* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
|
||||||
|
** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
|
||||||
|
** the PENDING_LOCK byte is temporary.
|
||||||
|
*/
|
||||||
|
newLocktype = pFile->locktype;
|
||||||
|
if( pFile->locktype==NO_LOCK
|
||||||
|
|| (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
|
||||||
|
){
|
||||||
|
int cnt = 3;
|
||||||
|
|
||||||
|
LockArea.lOffset = PENDING_BYTE;
|
||||||
|
LockArea.lRange = 1L;
|
||||||
|
UnlockArea.lOffset = 0L;
|
||||||
|
UnlockArea.lRange = 0L;
|
||||||
|
|
||||||
|
while( cnt-->0 && (res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L) )!=NO_ERROR ){
|
||||||
|
/* Try 3 times to get the pending lock. The pending lock might be
|
||||||
|
** held by another reader process who will release it momentarily.
|
||||||
|
*/
|
||||||
|
TRACE2( "could not get a PENDING lock. cnt=%d\n", cnt );
|
||||||
|
DosSleep(1);
|
||||||
|
}
|
||||||
|
gotPendingLock = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire a shared lock
|
||||||
|
*/
|
||||||
|
if( locktype==SHARED_LOCK && res ){
|
||||||
|
assert( pFile->locktype==NO_LOCK );
|
||||||
|
res = getReadLock(pFile);
|
||||||
|
if( res == NO_ERROR ){
|
||||||
|
newLocktype = SHARED_LOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire a RESERVED lock
|
||||||
|
*/
|
||||||
|
if( locktype==RESERVED_LOCK && res ){
|
||||||
|
assert( pFile->locktype==SHARED_LOCK );
|
||||||
|
LockArea.lOffset = RESERVED_BYTE;
|
||||||
|
LockArea.lRange = 1L;
|
||||||
|
UnlockArea.lOffset = 0L;
|
||||||
|
UnlockArea.lRange = 0L;
|
||||||
|
res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
if( res == NO_ERROR ){
|
||||||
|
newLocktype = RESERVED_LOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire a PENDING lock
|
||||||
|
*/
|
||||||
|
if( locktype==EXCLUSIVE_LOCK && res ){
|
||||||
|
newLocktype = PENDING_LOCK;
|
||||||
|
gotPendingLock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire an EXCLUSIVE lock
|
||||||
|
*/
|
||||||
|
if( locktype==EXCLUSIVE_LOCK && res ){
|
||||||
|
assert( pFile->locktype>=SHARED_LOCK );
|
||||||
|
res = unlockReadLock(pFile);
|
||||||
|
TRACE2( "unreadlock = %d\n", res );
|
||||||
|
LockArea.lOffset = SHARED_FIRST;
|
||||||
|
LockArea.lRange = SHARED_SIZE;
|
||||||
|
UnlockArea.lOffset = 0L;
|
||||||
|
UnlockArea.lRange = 0L;
|
||||||
|
res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
if( res == NO_ERROR ){
|
||||||
|
newLocktype = EXCLUSIVE_LOCK;
|
||||||
|
}else{
|
||||||
|
TRACE2( "error-code = %d\n", res );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are holding a PENDING lock that ought to be released, then
|
||||||
|
** release it now.
|
||||||
|
*/
|
||||||
|
if( gotPendingLock && locktype==SHARED_LOCK ){
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = PENDING_BYTE;
|
||||||
|
UnlockArea.lRange = 1L;
|
||||||
|
DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the state of the lock has held in the file descriptor then
|
||||||
|
** return the appropriate result code.
|
||||||
|
*/
|
||||||
|
if( res == NO_ERROR ){
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
|
TRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
|
||||||
|
locktype, newLocktype );
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
pFile->locktype = newLocktype;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine checks if there is a RESERVED lock held on the specified
|
||||||
|
** file by this or any other process. If such a lock is held, return
|
||||||
|
** non-zero, otherwise zero.
|
||||||
|
*/
|
||||||
|
int os2CheckReservedLock( OsFile *id ){
|
||||||
|
APIRET rc;
|
||||||
|
os2File *pFile = (os2File*)id;
|
||||||
|
assert( pFile!=0 );
|
||||||
|
if( pFile->locktype>=RESERVED_LOCK ){
|
||||||
|
rc = 1;
|
||||||
|
TRACE3( "TEST WR-LOCK %d %d (local)\n", pFile->h, rc );
|
||||||
|
}else{
|
||||||
|
FILELOCK LockArea,
|
||||||
|
UnlockArea;
|
||||||
|
memset(&LockArea, 0, sizeof(LockArea));
|
||||||
|
memset(&UnlockArea, 0, sizeof(UnlockArea));
|
||||||
|
LockArea.lOffset = RESERVED_BYTE;
|
||||||
|
LockArea.lRange = 1L;
|
||||||
|
UnlockArea.lOffset = 0L;
|
||||||
|
UnlockArea.lRange = 0L;
|
||||||
|
rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
if( rc == NO_ERROR ){
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = RESERVED_BYTE;
|
||||||
|
UnlockArea.lRange = 1L;
|
||||||
|
rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
TRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, rc );
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Lower the locking level on file descriptor id to locktype. locktype
|
||||||
|
** must be either NO_LOCK or SHARED_LOCK.
|
||||||
|
**
|
||||||
|
** If the locking level of the file descriptor is already at or below
|
||||||
|
** the requested locking level, this routine is a no-op.
|
||||||
|
**
|
||||||
|
** It is not possible for this routine to fail if the second argument
|
||||||
|
** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
|
||||||
|
** might return SQLITE_IOERR;
|
||||||
|
*/
|
||||||
|
int os2Unlock( OsFile *id, int locktype ){
|
||||||
|
int type;
|
||||||
|
APIRET rc = SQLITE_OK;
|
||||||
|
os2File *pFile = (os2File*)id;
|
||||||
|
FILELOCK LockArea,
|
||||||
|
UnlockArea;
|
||||||
|
memset(&LockArea, 0, sizeof(LockArea));
|
||||||
|
memset(&UnlockArea, 0, sizeof(UnlockArea));
|
||||||
|
assert( pFile!=0 );
|
||||||
|
assert( locktype<=SHARED_LOCK );
|
||||||
|
TRACE4( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype );
|
||||||
|
type = pFile->locktype;
|
||||||
|
if( type>=EXCLUSIVE_LOCK ){
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = SHARED_FIRST;
|
||||||
|
UnlockArea.lRange = SHARED_SIZE;
|
||||||
|
DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
|
||||||
|
/* This should never happen. We should always be able to
|
||||||
|
** reacquire the read lock */
|
||||||
|
rc = SQLITE_IOERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( type>=RESERVED_LOCK ){
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = RESERVED_BYTE;
|
||||||
|
UnlockArea.lRange = 1L;
|
||||||
|
DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
|
||||||
|
unlockReadLock(pFile);
|
||||||
|
}
|
||||||
|
if( type>=PENDING_LOCK ){
|
||||||
|
LockArea.lOffset = 0L;
|
||||||
|
LockArea.lRange = 0L;
|
||||||
|
UnlockArea.lOffset = PENDING_BYTE;
|
||||||
|
UnlockArea.lRange = 1L;
|
||||||
|
DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
|
||||||
|
}
|
||||||
|
pFile->locktype = locktype;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 *sqlite3Os2FullPathname( const char *zRelative ){
|
||||||
|
char *zFull = 0;
|
||||||
|
if( strchr(zRelative, ':') ){
|
||||||
|
sqlite3SetString( &zFull, zRelative, (char*)0 );
|
||||||
|
}else{
|
||||||
|
char zBuff[SQLITE_TEMPNAME_SIZE - 2] = {0};
|
||||||
|
char zDrive[1] = {0};
|
||||||
|
ULONG cbzFullLen = SQLITE_TEMPNAME_SIZE;
|
||||||
|
ULONG ulDriveNum = 0;
|
||||||
|
ULONG ulDriveMap = 0;
|
||||||
|
DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
|
||||||
|
DosQueryCurrentDir( 0L, zBuff, &cbzFullLen );
|
||||||
|
zFull = sqliteMalloc( cbzFullLen );
|
||||||
|
sprintf( zDrive, "%c", (char)('A' + ulDriveNum - 1) );
|
||||||
|
sqlite3SetString( &zFull, zDrive, ":\\", zBuff, "\\", zRelative, (char*)0 );
|
||||||
|
}
|
||||||
|
return zFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The fullSync option is meaningless on os2, or correct me if I'm wrong. This is a no-op.
|
||||||
|
** From os_unix.c: Change the value of the fullsync flag in the given file descriptor.
|
||||||
|
** From os_unix.c: ((unixFile*)id)->fullSync = v;
|
||||||
|
*/
|
||||||
|
static void os2SetFullSync( OsFile *id, int v ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the underlying file handle for an OsFile
|
||||||
|
*/
|
||||||
|
static int os2FileHandle( OsFile *id ){
|
||||||
|
return (int)((os2File*)id)->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return an integer that indices the type of lock currently held
|
||||||
|
** by this handle. (Used for testing and analysis only.)
|
||||||
|
*/
|
||||||
|
static int os2LockState( OsFile *id ){
|
||||||
|
return ((os2File*)id)->locktype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This vector defines all the methods that can operate on an OsFile
|
||||||
|
** for os2.
|
||||||
|
*/
|
||||||
|
static const IoMethod sqlite3Os2IoMethod = {
|
||||||
|
os2Close,
|
||||||
|
os2OpenDirectory,
|
||||||
|
os2Read,
|
||||||
|
os2Write,
|
||||||
|
os2Seek,
|
||||||
|
os2Truncate,
|
||||||
|
os2Sync,
|
||||||
|
os2SetFullSync,
|
||||||
|
os2FileHandle,
|
||||||
|
os2FileSize,
|
||||||
|
os2Lock,
|
||||||
|
os2Unlock,
|
||||||
|
os2LockState,
|
||||||
|
os2CheckReservedLock,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate memory for an OsFile. Initialize the new OsFile
|
||||||
|
** to the value given in pInit and return a pointer to the new
|
||||||
|
** OsFile. If we run out of memory, close the file and return NULL.
|
||||||
|
*/
|
||||||
|
int allocateOs2File( os2File *pInit, OsFile **pld ){
|
||||||
|
os2File *pNew;
|
||||||
|
pNew = sqliteMalloc( sizeof(*pNew) );
|
||||||
|
if( pNew==0 ){
|
||||||
|
DosClose( pInit->h );
|
||||||
|
*pld = 0;
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
*pNew = *pInit;
|
||||||
|
pNew->pMethod = &sqlite3Os2IoMethod;
|
||||||
|
pNew->locktype = NO_LOCK;
|
||||||
|
*pld = (OsFile*)pNew;
|
||||||
|
OpenCounter(+1);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SQLITE_OMIT_DISKIO */
|
||||||
|
/***************************************************************************
|
||||||
|
** Everything above deals with file I/O. Everything that follows deals
|
||||||
|
** with other miscellanous aspects of the operating system interface
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 sqlite3Os2RandomSeed( 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 );
|
||||||
|
DosGetDateTime( (PDATETIME)zBuf );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Sleep for a little while. Return the amount of time slept.
|
||||||
|
*/
|
||||||
|
int sqlite3Os2Sleep( int ms ){
|
||||||
|
DosSleep( ms );
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Static variables used for thread synchronization
|
||||||
|
*/
|
||||||
|
static int inMutex = 0;
|
||||||
|
#ifdef SQLITE_OS2_THREADS
|
||||||
|
static ULONG mutexOwner;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following pair of routines 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 sqlite3Os2EnterMutex(){
|
||||||
|
PTIB ptib;
|
||||||
|
#ifdef SQLITE_OS2_THREADS
|
||||||
|
DosEnterCritSec();
|
||||||
|
DosGetInfoBlocks( &ptib, NULL );
|
||||||
|
mutexOwner = ptib->tib_ptib2->tib2_ultid;
|
||||||
|
#endif
|
||||||
|
assert( !inMutex );
|
||||||
|
inMutex = 1;
|
||||||
|
}
|
||||||
|
void sqlite3Os2LeaveMutex(){
|
||||||
|
PTIB ptib;
|
||||||
|
assert( inMutex );
|
||||||
|
inMutex = 0;
|
||||||
|
#ifdef SQLITE_OS2_THREADS
|
||||||
|
DosGetInfoBlocks( &ptib, NULL );
|
||||||
|
assert( mutexOwner == ptib->tib_ptib2->tib2_ultid );
|
||||||
|
DosExitCritSec();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return TRUE if the mutex is currently held.
|
||||||
|
**
|
||||||
|
** If the thisThreadOnly parameter is true, return true if and only if the
|
||||||
|
** calling thread holds the mutex. If the parameter is false, return
|
||||||
|
** true if any thread holds the mutex.
|
||||||
|
*/
|
||||||
|
int sqlite3Os2InMutex( int thisThreadOnly ){
|
||||||
|
#ifdef SQLITE_OS2_THREADS
|
||||||
|
PTIB ptib;
|
||||||
|
DosGetInfoBlocks( &ptib, NULL );
|
||||||
|
return inMutex>0 && (thisThreadOnly==0 || mutexOwner==ptib->tib_ptib2->tib2_ultid);
|
||||||
|
#else
|
||||||
|
return inMutex>0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 sqlite3Os2CurrentTime( double *prNow ){
|
||||||
|
double now;
|
||||||
|
USHORT second, minute, hour,
|
||||||
|
day, month, year;
|
||||||
|
DATETIME dt;
|
||||||
|
DosGetDateTime( &dt );
|
||||||
|
second = (USHORT)dt.seconds;
|
||||||
|
minute = (USHORT)dt.minutes + dt.timezone;
|
||||||
|
hour = (USHORT)dt.hours;
|
||||||
|
day = (USHORT)dt.day;
|
||||||
|
month = (USHORT)dt.month;
|
||||||
|
year = (USHORT)dt.year;
|
||||||
|
|
||||||
|
/* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
|
||||||
|
http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */
|
||||||
|
/* Calculate the Julian days */
|
||||||
|
now = day - 32076 +
|
||||||
|
1461*(year + 4800 + (month - 14)/12)/4 +
|
||||||
|
367*(month - 2 - (month - 14)/12*12)/12 -
|
||||||
|
3*((year + 4900 + (month - 14)/12)/100)/4;
|
||||||
|
|
||||||
|
/* Add the fractional hours, mins and seconds */
|
||||||
|
now += (hour + 12.0)/24.0;
|
||||||
|
now += minute/1440.0;
|
||||||
|
now += second/86400.0;
|
||||||
|
*prNow = now;
|
||||||
|
#ifdef SQLITE_TEST
|
||||||
|
if( sqlite3_current_time ){
|
||||||
|
*prNow = sqlite3_current_time/86400.0 + 2440587.5;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Remember the number of thread-specific-data blocks allocated.
|
||||||
|
** Use this to verify that we are not leaking thread-specific-data.
|
||||||
|
** Ticket #1601
|
||||||
|
*/
|
||||||
|
#ifdef SQLITE_TEST
|
||||||
|
int sqlite3_tsd_count = 0;
|
||||||
|
# define TSD_COUNTER_INCR InterlockedIncrement( &sqlite3_tsd_count )
|
||||||
|
# define TSD_COUNTER_DECR InterlockedDecrement( &sqlite3_tsd_count )
|
||||||
|
#else
|
||||||
|
# define TSD_COUNTER_INCR /* no-op */
|
||||||
|
# define TSD_COUNTER_DECR /* no-op */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If called with allocateFlag>1, then return a pointer to thread
|
||||||
|
** specific data for the current thread. Allocate and zero the
|
||||||
|
** thread-specific data if it does not already exist necessary.
|
||||||
|
**
|
||||||
|
** If called with allocateFlag==0, then check the current thread
|
||||||
|
** specific data. Return it if it exists. If it does not exist,
|
||||||
|
** then return NULL.
|
||||||
|
**
|
||||||
|
** If called with allocateFlag<0, check to see if the thread specific
|
||||||
|
** data is allocated and is all zero. If it is then deallocate it.
|
||||||
|
** Return a pointer to the thread specific data or NULL if it is
|
||||||
|
** unallocated or gets deallocated.
|
||||||
|
*/
|
||||||
|
ThreadData *sqlite3Os2ThreadSpecificData( int allocateFlag ){
|
||||||
|
static ThreadData **s_ppTsd = NULL;
|
||||||
|
static const ThreadData zeroData = {0, 0, 0};
|
||||||
|
ThreadData *pTsd;
|
||||||
|
|
||||||
|
if( !s_ppTsd ){
|
||||||
|
sqlite3OsEnterMutex();
|
||||||
|
if( !s_ppTsd ){
|
||||||
|
PULONG pul;
|
||||||
|
APIRET rc = DosAllocThreadLocalMemory(1, &pul);
|
||||||
|
if( rc != NO_ERROR ){
|
||||||
|
sqlite3OsLeaveMutex();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s_ppTsd = (ThreadData **)pul;
|
||||||
|
}
|
||||||
|
sqlite3OsLeaveMutex();
|
||||||
|
}
|
||||||
|
pTsd = *s_ppTsd;
|
||||||
|
if( allocateFlag>0 ){
|
||||||
|
if( !pTsd ){
|
||||||
|
pTsd = sqlite3OsMalloc( sizeof(zeroData) );
|
||||||
|
if( pTsd ){
|
||||||
|
*pTsd = zeroData;
|
||||||
|
*s_ppTsd = pTsd;
|
||||||
|
TSD_COUNTER_INCR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if( pTsd!=0 && allocateFlag<0
|
||||||
|
&& memcmp( pTsd, &zeroData, sizeof(ThreadData) )==0 ){
|
||||||
|
sqlite3OsFree(pTsd);
|
||||||
|
*s_ppTsd = NULL;
|
||||||
|
TSD_COUNTER_DECR;
|
||||||
|
pTsd = 0;
|
||||||
|
}
|
||||||
|
return pTsd;
|
||||||
|
}
|
||||||
|
#endif /* OS_OS2 */
|
||||||
73
src/os_os2.h
Normal file
73
src/os_os2.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
** 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 OS/2.
|
||||||
|
*/
|
||||||
|
#ifndef _SQLITE_OS_OS2_H_
|
||||||
|
#define _SQLITE_OS_OS2_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** standard include files.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Macros used to determine whether or not to use threads. The
|
||||||
|
** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
|
||||||
|
** Posix threads and SQLITE_W32_THREADS is defined if we are
|
||||||
|
** synchronizing using Win32 threads.
|
||||||
|
*/
|
||||||
|
/* this mutex implementation only available with EMX */
|
||||||
|
#if defined(THREADSAFE) && THREADSAFE
|
||||||
|
# include <sys/builtin.h>
|
||||||
|
# include <sys/smutex.h>
|
||||||
|
# define SQLITE_OS2_THREADS 1
|
||||||
|
#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 Unix.
|
||||||
|
**
|
||||||
|
** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
|
||||||
|
** PENDING_LOCK or EXCLUSIVE_LOCK.
|
||||||
|
*/
|
||||||
|
typedef struct OsFile OsFile;
|
||||||
|
struct OsFile {
|
||||||
|
int h; /* The file descriptor (LHANDLE) */
|
||||||
|
int locked; /* True if this user holds the lock */
|
||||||
|
int delOnClose; /* True if file is to be deleted on close */
|
||||||
|
char *pathToDel; /* Name of file to delete on close */
|
||||||
|
unsigned char locktype; /* The type of lock held on this fd */
|
||||||
|
unsigned char isOpen; /* True if needs to be closed */
|
||||||
|
unsigned char fullSync;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Maximum number of characters in a temporary file name
|
||||||
|
*/
|
||||||
|
#define SQLITE_TEMPNAME_SIZE 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Minimum interval supported by sqlite3OsSleep().
|
||||||
|
*/
|
||||||
|
#define SQLITE_MIN_SLEEP_MS 1
|
||||||
|
|
||||||
|
#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
|
||||||
|
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SQLITE_OS_OS2_H_ */
|
||||||
Reference in New Issue
Block a user